1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.classic.pattern;
15
16 import ch.qos.logback.classic.ClassicConstants;
17 import ch.qos.logback.classic.ClassicTestConstants;
18 import ch.qos.logback.classic.Level;
19 import ch.qos.logback.classic.Logger;
20 import ch.qos.logback.classic.LoggerContext;
21 import ch.qos.logback.classic.spi.ILoggingEvent;
22 import ch.qos.logback.classic.spi.LoggingEvent;
23 import ch.qos.logback.classic.util.LogbackMDCAdapter;
24 import ch.qos.logback.core.CoreConstants;
25 import ch.qos.logback.core.net.SyslogConstants;
26 import ch.qos.logback.core.pattern.DynamicConverter;
27 import ch.qos.logback.core.pattern.FormatInfo;
28 import ch.qos.logback.core.util.EnvUtil;
29 import ch.qos.logback.core.util.StatusPrinter;
30 import org.junit.jupiter.api.BeforeEach;
31 import org.junit.jupiter.api.Test;
32 import org.slf4j.MarkerFactory;
33
34 import java.util.ArrayList;
35 import java.util.List;
36 import java.util.regex.Pattern;
37
38 import static org.junit.jupiter.api.Assertions.assertEquals;
39 import static org.junit.jupiter.api.Assertions.assertTrue;
40 import static org.junit.jupiter.api.Assertions.fail;
41
42 public class ConverterTest {
43
44 LoggerContext loggerContext = new LoggerContext();
45 LogbackMDCAdapter logbackMDCAdapter = new LogbackMDCAdapter();
46 Logger logger = loggerContext.getLogger(ConverterTest.class);
47 LoggingEvent le;
48 List<String> optionList = new ArrayList<String>();
49
50
51
52
53 LoggingEvent makeLoggingEvent(Exception ex) {
54 return new LoggingEvent(ch.qos.logback.core.pattern.FormattingConverter.class.getName(), logger, Level.INFO,
55 "Some message", ex, null);
56 }
57
58 Exception getException(String msg, Exception cause) {
59 return new Exception(msg, cause);
60 }
61
62 @BeforeEach
63 public void setUp() throws Exception {
64 loggerContext.setMDCAdapter(logbackMDCAdapter);
65 Exception rootEx = getException("Innermost", null);
66 Exception nestedEx = getException("Nested", rootEx);
67
68 Exception ex = new Exception("Bogus exception", nestedEx);
69
70 le = makeLoggingEvent(ex);
71 }
72
73 @Test
74 public void testLineOfCaller() {
75 {
76 DynamicConverter<ILoggingEvent> converter = new LineOfCallerConverter();
77 StringBuilder buf = new StringBuilder();
78 converter.write(buf, le);
79
80 assertEquals("78", buf.toString());
81 }
82 }
83
84 @Test
85 public void testLevel() {
86 {
87 DynamicConverter<ILoggingEvent> converter = new LevelConverter();
88 StringBuilder buf = new StringBuilder();
89 converter.write(buf, le);
90 assertEquals("INFO", buf.toString());
91 }
92 {
93 DynamicConverter<ILoggingEvent> converter = new LevelConverter();
94 converter.setFormattingInfo(new FormatInfo(1, 1, true, false));
95 StringBuilder buf = new StringBuilder();
96 converter.write(buf, le);
97 assertEquals("I", buf.toString());
98 }
99 }
100
101 @Test
102 public void testThread() {
103 DynamicConverter<ILoggingEvent> converter = new ThreadConverter();
104 StringBuilder buf = new StringBuilder();
105 converter.write(buf, le);
106 System.out.println(buf.toString());
107 String regex = ClassicTestConstants.NAKED_MAIN_REGEX;
108 assertTrue(buf.toString().matches(regex));
109 }
110
111 @Test
112 public void testMessage() {
113 DynamicConverter<ILoggingEvent> converter = new MessageConverter();
114 StringBuilder buf = new StringBuilder();
115 converter.write(buf, le);
116 assertEquals("Some message", buf.toString());
117 }
118
119 @Test
120 public void testLineSeparator() {
121 DynamicConverter<ILoggingEvent> converter = new LineSeparatorConverter();
122 StringBuilder buf = new StringBuilder();
123 converter.write(buf, le);
124 assertEquals(CoreConstants.LINE_SEPARATOR, buf.toString());
125 }
126
127 @Test
128 public void testException() {
129 {
130 DynamicConverter<ILoggingEvent> converter = new ThrowableProxyConverter();
131 StringBuilder buf = new StringBuilder();
132 converter.write(buf, le);
133 }
134
135 {
136 DynamicConverter<ILoggingEvent> converter = new ThrowableProxyConverter();
137 this.optionList.add("3");
138 converter.setOptionList(this.optionList);
139 StringBuilder buf = new StringBuilder();
140 converter.write(buf, le);
141 }
142 }
143
144 @Test
145 public void testLogger() {
146 {
147 ClassicConverter converter = new LoggerConverter();
148 StringBuilder buf = new StringBuilder();
149 converter.write(buf, le);
150 assertEquals(this.getClass().getName(), buf.toString());
151 }
152
153 {
154 ClassicConverter converter = new LoggerConverter();
155 this.optionList.add("20");
156 converter.setOptionList(this.optionList);
157 converter.start();
158 StringBuilder buf = new StringBuilder();
159 converter.write(buf, le);
160 assertEquals("c.q.l.c.p.ConverterTest", buf.toString());
161 }
162
163 {
164 DynamicConverter<ILoggingEvent> converter = new LoggerConverter();
165 this.optionList.clear();
166 this.optionList.add("0");
167 converter.setOptionList(this.optionList);
168 converter.start();
169 StringBuilder buf = new StringBuilder();
170 converter.write(buf, le);
171 assertEquals("ConverterTest", buf.toString());
172 }
173 }
174
175 @Test
176 public void testVeryLongLoggerName() {
177 ClassicConverter converter = new LoggerConverter();
178 this.optionList.add("5");
179 converter.setOptionList(this.optionList);
180 converter.start();
181 StringBuilder buf = new StringBuilder();
182
183 char c = 'a';
184 int extraParts = 3;
185 int totalParts = ClassicConstants.MAX_DOTS + extraParts;
186 StringBuilder loggerNameBuf = new StringBuilder();
187 StringBuilder witness = new StringBuilder();
188
189 for (int i = 0; i < totalParts; i++) {
190 loggerNameBuf.append(c).append(c).append(c);
191 witness.append(c);
192 loggerNameBuf.append('.');
193 witness.append('.');
194 }
195 loggerNameBuf.append("zzzzzz");
196 witness.append("zzzzzz");
197
198 le.setLoggerName(loggerNameBuf.toString());
199 converter.write(buf, le);
200 assertEquals(witness.toString(), buf.toString());
201 }
202
203 @Test
204 public void testClass() {
205 DynamicConverter<ILoggingEvent> converter = new ClassOfCallerConverter();
206 StringBuilder buf = new StringBuilder();
207 converter.write(buf, le);
208 assertEquals(this.getClass().getName(), buf.toString());
209 }
210
211 @Test
212 public void testMethodOfCaller() {
213 DynamicConverter<ILoggingEvent> converter = new MethodOfCallerConverter();
214 StringBuilder buf = new StringBuilder();
215 converter.write(buf, le);
216 assertEquals("testMethodOfCaller", buf.toString());
217 }
218
219 @Test
220 public void testFileOfCaller() {
221 DynamicConverter<ILoggingEvent> converter = new FileOfCallerConverter();
222 StringBuilder buf = new StringBuilder();
223 converter.write(buf, le);
224 assertEquals("ConverterTest.java", buf.toString());
225 }
226
227 @Test
228 public void testCallerData() {
229 {
230 DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
231 converter.start();
232
233 StringBuilder buf = new StringBuilder();
234 converter.write(buf, le);
235 if (buf.length() < 10) {
236 fail("buf is too short");
237 }
238 }
239
240 {
241 DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
242 this.optionList.add("2");
243 this.optionList.add("XXX");
244 converter.setOptionList(this.optionList);
245 converter.start();
246
247 StringBuilder buf = new StringBuilder();
248 LoggingEvent event = makeLoggingEvent(null);
249 event.addMarker(MarkerFactory.getMarker("XXX"));
250 converter.write(buf, event);
251 if (buf.length() < 10) {
252 fail("buf is too short");
253 }
254 }
255
256 {
257 DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
258 this.optionList.clear();
259 this.optionList.add("2");
260 this.optionList.add("XXX");
261 this.optionList.add("*");
262 converter.setOptionList(this.optionList);
263 converter.start();
264
265 StringBuilder buf = new StringBuilder();
266 LoggingEvent event = makeLoggingEvent(null);
267 event.addMarker(MarkerFactory.getMarker("YYY"));
268 converter.write(buf, event);
269 if (buf.length() < 10) {
270 fail("buf is too short");
271 }
272 }
273 {
274 DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
275 this.optionList.clear();
276 this.optionList.add("2");
277 this.optionList.add("XXX");
278 this.optionList.add("+");
279 converter.setOptionList(this.optionList);
280 converter.start();
281
282 StringBuilder buf = new StringBuilder();
283 LoggingEvent event = makeLoggingEvent(null);
284 event.addMarker(MarkerFactory.getMarker("YYY"));
285 converter.write(buf, event);
286 if (buf.length() < 10) {
287 fail("buf is too short");
288 }
289 }
290
291 {
292 DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
293 this.optionList.clear();
294 this.optionList.add("2");
295 this.optionList.add("XXX");
296 this.optionList.add("*");
297 converter.setOptionList(this.optionList);
298 converter.start();
299
300 StringBuilder buf = new StringBuilder();
301 converter.write(buf, le);
302 if (buf.length() < 10) {
303 fail("buf is too short");
304 }
305
306 }
307
308 {
309 DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
310 this.optionList.clear();
311
312 boolean jdk18 = EnvUtil.isJDK18OrHigher();
313
314 if(jdk18) {
315 this.optionList.add("2..3");
316 } else {
317 this.optionList.add("4..5");
318 }
319 converter.setOptionList(this.optionList);
320 converter.start();
321
322 StringBuilder buf = new StringBuilder();
323 converter.write(buf, le);
324 assertTrue( buf.length() >= 10, "buf is too short");
325
326 String expectedRegex = "Caller\\+4";
327 if(jdk18) {
328 expectedRegex = "Caller\\+2";
329 }
330 expectedRegex+="\t at (java.base\\/)?java.lang.reflect.Method.invoke.*$";
331 String actual = buf.toString();
332 assertTrue( Pattern.compile(expectedRegex).matcher(actual).find(), "actual: " + actual);
333
334 }
335 }
336
337 @Test
338 public void testRelativeTime() throws Exception {
339 DynamicConverter<ILoggingEvent> converter = new RelativeTimeConverter();
340 StringBuilder buf0 = new StringBuilder();
341 StringBuilder buf1 = new StringBuilder();
342 long timestamp = System.currentTimeMillis();
343 LoggingEvent e0 = makeLoggingEvent(null);
344 e0.setTimeStamp(timestamp);
345 LoggingEvent e1 = makeLoggingEvent(null);
346 e1.setTimeStamp(timestamp);
347 converter.write(buf0, e0);
348 converter.write(buf1, e1);
349 assertEquals(buf0.toString(), buf1.toString());
350 }
351
352 @Test
353 public void testSyslogStart() throws Exception {
354 DynamicConverter<ILoggingEvent> converter = new SyslogStartConverter();
355 this.optionList.clear();
356 this.optionList.add("MAIL");
357 converter.setOptionList(this.optionList);
358 converter.start();
359
360 ILoggingEvent event = makeLoggingEvent(null);
361
362 StringBuilder buf = new StringBuilder();
363 converter.write(buf, event);
364
365 String expected = "<" + (SyslogConstants.LOG_MAIL + SyslogConstants.INFO_SEVERITY) + ">";
366 assertTrue(buf.toString().startsWith(expected));
367 }
368
369 @Test
370 public void testMDCConverter() throws Exception {
371 logbackMDCAdapter.clear();
372 logbackMDCAdapter.put("someKey", "someValue");
373 MDCConverter converter = new MDCConverter();
374 this.optionList.clear();
375 this.optionList.add("someKey");
376 converter.setOptionList(optionList);
377 converter.start();
378
379 ILoggingEvent event = makeLoggingEvent(null);
380
381 String result = converter.convert(event);
382 assertEquals("someValue", result);
383 }
384
385 @Test
386 public void contextNameConverter() {
387 ClassicConverter converter = new ContextNameConverter();
388
389 LoggerContext lcOther = new LoggerContext();
390 lcOther.setName("another");
391 converter.setContext(lcOther);
392
393 loggerContext.setName("aValue");
394 ILoggingEvent event = makeLoggingEvent(null);
395
396 String result = converter.convert(event);
397 assertEquals("aValue", result);
398 }
399
400 @Test
401 public void contextProperty() {
402 PropertyConverter converter = new PropertyConverter();
403 converter.setContext(loggerContext);
404 List<String> ol = new ArrayList<String>();
405 ol.add("k");
406 converter.setOptionList(ol);
407 converter.start();
408 loggerContext.setName("aValue");
409 loggerContext.putProperty("k", "v");
410 ILoggingEvent event = makeLoggingEvent(null);
411
412 String result = converter.convert(event);
413 assertEquals("v", result);
414 }
415
416 @Test
417 public void testSequenceNumber() {
418
419 SequenceNumberConverter converter = new SequenceNumberConverter();
420 converter.setContext(loggerContext);
421 converter.start();
422
423 assertTrue(converter.isStarted());
424 LoggingEvent event = makeLoggingEvent(null);
425
426 event.setSequenceNumber(123);
427 assertEquals("123", converter.convert(event));
428 StatusPrinter.print(loggerContext);
429 }
430 }