1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.classic.net;
15
16 import ch.qos.logback.classic.util.LogbackMDCAdapter;
17 import org.junit.jupiter.api.AfterEach;
18 import org.junit.jupiter.api.BeforeEach;
19 import org.junit.jupiter.api.Disabled;
20 import org.junit.jupiter.api.Test;
21 import org.slf4j.LoggerFactory;
22
23 import ch.qos.logback.classic.ClassicTestConstants;
24 import ch.qos.logback.classic.Logger;
25 import ch.qos.logback.classic.LoggerContext;
26 import ch.qos.logback.classic.joran.JoranConfigurator;
27 import ch.qos.logback.classic.net.mock.MockSyslogServer;
28 import ch.qos.logback.core.CoreConstants;
29 import ch.qos.logback.core.joran.spi.JoranException;
30 import ch.qos.logback.core.net.SyslogConstants;
31 import ch.qos.logback.core.recovery.RecoveryCoordinator;
32 import ch.qos.logback.core.testUtil.RandomUtil;
33 import ch.qos.logback.core.util.StatusPrinter;
34
35 import java.nio.charset.Charset;
36
37 import static org.junit.jupiter.api.Assertions.assertEquals;
38 import static org.junit.jupiter.api.Assertions.assertTrue;
39
40 public class SyslogAppenderTest {
41
42 private static final String SYSLOG_PREFIX_REGEX = "<\\d{2}>\\w{3} [\\d ]\\d \\d{2}(:\\d{2}){2} [\\w.-]* ";
43
44 LoggerContext lc = new LoggerContext();
45 LogbackMDCAdapter logbackMDCAdapter = new LogbackMDCAdapter();
46
47 SyslogAppender sa = new SyslogAppender();
48 MockSyslogServer mockServer;
49 String loggerName = this.getClass().getName();
50 Logger logger = lc.getLogger(loggerName);
51
52 @BeforeEach
53 public void setUp() throws Exception {
54 lc.setName("test");
55 lc.setMDCAdapter(logbackMDCAdapter);
56 sa.setContext(lc);
57 }
58
59 @AfterEach
60 public void tearDown() throws Exception {
61 }
62
63 public void setMockServerAndConfigure(int expectedCount, String suffixPattern) throws InterruptedException {
64 int port = RandomUtil.getRandomServerPort();
65
66 mockServer = new MockSyslogServer(expectedCount, port);
67 mockServer.start();
68
69
70 Thread.sleep(100);
71
72 sa.setSyslogHost("localhost");
73 sa.setFacility("MAIL");
74 sa.setPort(port);
75 sa.setSuffixPattern(suffixPattern);
76 sa.setStackTracePattern("[%thread] foo " + CoreConstants.TAB);
77 sa.start();
78 assertTrue(sa.isStarted());
79
80 String loggerName = this.getClass().getName();
81 Logger logger = lc.getLogger(loggerName);
82 logger.addAppender(sa);
83
84 }
85
86 public void setMockServerAndConfigure(int expectedCount) throws InterruptedException {
87 this.setMockServerAndConfigure(expectedCount, "[%thread] %logger %msg");
88 }
89
90 @Test
91 public void basic() throws InterruptedException {
92
93 setMockServerAndConfigure(1);
94 String logMsg = "hello";
95 logger.debug(logMsg);
96
97
98
99 mockServer.join(8000);
100
101 assertTrue(mockServer.isFinished());
102 assertEquals(1, mockServer.getMessageList().size());
103 String msg = new String(mockServer.getMessageList().get(0));
104
105 String threadName = Thread.currentThread().getName();
106
107 String expected = "<" + (SyslogConstants.LOG_MAIL + SyslogConstants.DEBUG_SEVERITY) + ">";
108 assertTrue(msg.startsWith(expected));
109
110 checkRegexMatch(msg, SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + loggerName + " " + logMsg);
111
112 }
113
114 @Test
115 public void suffixPatternWithTag() throws InterruptedException {
116 setMockServerAndConfigure(1, "test/something [%thread] %logger %msg");
117 String logMsg = "hello";
118 logger.debug(logMsg);
119
120
121
122 mockServer.join(8000);
123
124 assertTrue(mockServer.isFinished());
125 assertEquals(1, mockServer.getMessageList().size());
126 String msg = new String(mockServer.getMessageList().get(0));
127
128 String threadName = Thread.currentThread().getName();
129
130 String expected = "<" + (SyslogConstants.LOG_MAIL + SyslogConstants.DEBUG_SEVERITY) + ">";
131 assertTrue(msg.startsWith(expected));
132
133 checkRegexMatch(msg,
134 SYSLOG_PREFIX_REGEX + "test/something \\[" + threadName + "\\] " + loggerName + " " + logMsg);
135
136 }
137
138 @Test
139 public void tException() throws InterruptedException {
140 setMockServerAndConfigure(21);
141
142 String logMsg = "hello";
143 String exMsg = "just testing";
144 Exception ex = new Exception(exMsg);
145 logger.debug(logMsg, ex);
146 StatusPrinter.print(lc);
147
148
149
150 mockServer.join(8000);
151 assertTrue(mockServer.isFinished());
152
153
154 assertEquals(21, mockServer.getMessageList().size());
155
156
157
158
159
160 String msg = new String(mockServer.getMessageList().get(0));
161 String expected = "<" + (SyslogConstants.LOG_MAIL + SyslogConstants.DEBUG_SEVERITY) + ">";
162 assertTrue(msg.startsWith(expected));
163
164 String threadName = Thread.currentThread().getName();
165 String regex = SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + loggerName + " " + logMsg;
166 checkRegexMatch(msg, regex);
167
168 msg = new String(mockServer.getMessageList().get(1));
169 assertTrue(msg.contains(ex.getClass().getName()));
170 assertTrue(msg.contains(ex.getMessage()));
171
172 msg = new String(mockServer.getMessageList().get(2));
173 assertTrue(msg.startsWith(expected));
174 regex = SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + "foo " + CoreConstants.TAB + "at ch\\.qos.*";
175 checkRegexMatch(msg, regex);
176 }
177
178 private void checkRegexMatch(String s, String regex) {
179 assertTrue(s.matches(regex), "The string [" + s + "] did not match regex [" + regex + "]");
180 }
181
182 @Test
183 public void large() throws Exception {
184 setMockServerAndConfigure(2);
185 StringBuilder largeBuf = new StringBuilder();
186 for (int i = 0; i < 2 * 1024 * 1024; i++) {
187 largeBuf.append('a');
188 }
189 logger.debug(largeBuf.toString());
190
191 String logMsg = "hello";
192 logger.debug(logMsg);
193 Thread.sleep(RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN + 10);
194 logger.debug(logMsg);
195
196 mockServer.join(8000);
197 assertTrue(mockServer.isFinished());
198
199
200 assertEquals(2, mockServer.getMessageList().size());
201
202 String expected = "<" + (SyslogConstants.LOG_MAIL + SyslogConstants.DEBUG_SEVERITY) + ">";
203 String threadName = Thread.currentThread().getName();
204
205
206 final int maxMessageSize = sa.getMaxMessageSize();
207 String largeMsg = new String(mockServer.getMessageList().get(0));
208 assertTrue(largeMsg.startsWith(expected));
209 String largeRegex = SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + loggerName + " " + "a{"
210 + (maxMessageSize - 2000) + "," + maxMessageSize + "}";
211 checkRegexMatch(largeMsg, largeRegex);
212
213 String msg = new String(mockServer.getMessageList().get(1));
214 assertTrue(msg.startsWith(expected));
215 String regex = SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + loggerName + " " + logMsg;
216 checkRegexMatch(msg, regex);
217 }
218
219 @Test
220 public void LBCLASSIC_50() throws JoranException {
221
222 LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
223
224 JoranConfigurator configurator = new JoranConfigurator();
225 configurator.setContext(lc);
226 lc.reset();
227 configurator.doConfigure(ClassicTestConstants.JORAN_INPUT_PREFIX + "syslog_LBCLASSIC_50.xml");
228
229 org.slf4j.Logger logger = LoggerFactory.getLogger(this.getClass());
230 logger.info("hello");
231 }
232
233 @Test
234 public void unknownHostShouldNotCauseStopToFail() {
235
236 sa.setSyslogHost("unknown.host");
237 sa.setFacility("MAIL");
238 sa.start();
239 sa.stop();
240 }
241
242 @Test
243 public void nonAsciiMessageEncoding() throws Exception {
244
245 setMockServerAndConfigure(1);
246
247
248
249
250 String logMsg = "R\u0129ga";
251
252 Charset ISO_8859_4 = Charset.forName("ISO-8859-4");
253 sa.setCharset(ISO_8859_4);
254 logger.debug(logMsg);
255
256
257
258 mockServer.join(8000);
259
260 assertTrue(mockServer.isFinished());
261 assertEquals(1, mockServer.getMessageList().size());
262 String msg = new String(mockServer.getMessageList().get(0), ISO_8859_4);
263 String threadName = Thread.currentThread().getName();
264
265 String expected = "<" + (SyslogConstants.LOG_MAIL + SyslogConstants.DEBUG_SEVERITY) + ">";
266 assertTrue(msg.startsWith(expected));
267
268 System.out.println(logMsg);
269 checkRegexMatch(msg, SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + loggerName + " " + logMsg);
270
271 }
272 }