001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.classic.pattern; 015 016import static org.junit.Assert.assertEquals; 017import static org.junit.Assert.assertTrue; 018import static org.junit.Assert.fail; 019 020import java.util.ArrayList; 021import java.util.List; 022import java.util.regex.Pattern; 023 024import org.junit.Before; 025import org.junit.Test; 026import org.slf4j.MDC; 027import org.slf4j.MarkerFactory; 028 029import ch.qos.logback.classic.ClassicConstants; 030import ch.qos.logback.classic.ClassicTestConstants; 031import ch.qos.logback.classic.Level; 032import ch.qos.logback.classic.Logger; 033import ch.qos.logback.classic.LoggerContext; 034import ch.qos.logback.classic.spi.ILoggingEvent; 035import ch.qos.logback.classic.spi.LoggingEvent; 036import ch.qos.logback.core.CoreConstants; 037import ch.qos.logback.core.net.SyslogConstants; 038import ch.qos.logback.core.pattern.DynamicConverter; 039import ch.qos.logback.core.pattern.FormatInfo; 040 041 042public class ConverterTest { 043 044 LoggerContext lc = new LoggerContext(); 045 Logger logger = lc.getLogger(ConverterTest.class); 046 LoggingEvent le; 047 List<String> optionList = new ArrayList<String>(); 048 049 // The LoggingEvent is massaged with an FCQN of FormattingConverter. This 050 // forces the returned caller information to match the caller stack for this 051 // this particular test. 052 LoggingEvent makeLoggingEvent(Exception ex) { 053 return new LoggingEvent(ch.qos.logback.core.pattern.FormattingConverter.class.getName(), logger, Level.INFO, "Some message", ex, null); 054 } 055 056 Exception getException(String msg, Exception cause) { 057 return new Exception(msg, cause); 058 } 059 060 @Before 061 public void setUp() throws Exception { 062 Exception rootEx = getException("Innermost", null); 063 Exception nestedEx = getException("Nested", rootEx); 064 065 Exception ex = new Exception("Bogus exception", nestedEx); 066 067 le = makeLoggingEvent(ex); 068 } 069 070 @Test 071 public void testLineOfCaller() { 072 { 073 DynamicConverter<ILoggingEvent> converter = new LineOfCallerConverter(); 074 StringBuilder buf = new StringBuilder(); 075 converter.write(buf, le); 076 // the number below should be the line number of the previous line 077 assertEquals("75", buf.toString()); 078 } 079 } 080 081 @Test 082 public void testLevel() { 083 { 084 DynamicConverter<ILoggingEvent> converter = new LevelConverter(); 085 StringBuilder buf = new StringBuilder(); 086 converter.write(buf, le); 087 assertEquals("INFO", buf.toString()); 088 } 089 { 090 DynamicConverter<ILoggingEvent> converter = new LevelConverter(); 091 converter.setFormattingInfo(new FormatInfo(1, 1, true, false)); 092 StringBuilder buf = new StringBuilder(); 093 converter.write(buf, le); 094 assertEquals("I", buf.toString()); 095 } 096 } 097 098 @Test 099 public void testThread() { 100 DynamicConverter<ILoggingEvent> converter = new ThreadConverter(); 101 StringBuilder buf = new StringBuilder(); 102 converter.write(buf, le); 103 System.out.println(buf.toString()); 104 String regex = ClassicTestConstants.NAKED_MAIN_REGEX; 105 assertTrue(buf.toString().matches(regex)); 106 } 107 108 @Test 109 public void testMessage() { 110 DynamicConverter<ILoggingEvent> converter = new MessageConverter(); 111 StringBuilder buf = new StringBuilder(); 112 converter.write(buf, le); 113 assertEquals("Some message", buf.toString()); 114 } 115 116 @Test 117 public void testLineSeparator() { 118 DynamicConverter<ILoggingEvent> converter = new LineSeparatorConverter(); 119 StringBuilder buf = new StringBuilder(); 120 converter.write(buf, le); 121 assertEquals(CoreConstants.LINE_SEPARATOR, buf.toString()); 122 } 123 124 @Test 125 public void testException() { 126 { 127 DynamicConverter<ILoggingEvent> converter = new ThrowableProxyConverter(); 128 StringBuilder buf = new StringBuilder(); 129 converter.write(buf, le); 130 } 131 132 { 133 DynamicConverter<ILoggingEvent> converter = new ThrowableProxyConverter(); 134 this.optionList.add("3"); 135 converter.setOptionList(this.optionList); 136 StringBuilder buf = new StringBuilder(); 137 converter.write(buf, le); 138 } 139 } 140 141 @Test 142 public void testLogger() { 143 { 144 ClassicConverter converter = new LoggerConverter(); 145 StringBuilder buf = new StringBuilder(); 146 converter.write(buf, le); 147 assertEquals(this.getClass().getName(), buf.toString()); 148 } 149 150 { 151 ClassicConverter converter = new LoggerConverter(); 152 this.optionList.add("20"); 153 converter.setOptionList(this.optionList); 154 converter.start(); 155 StringBuilder buf = new StringBuilder(); 156 converter.write(buf, le); 157 assertEquals("c.q.l.c.p.ConverterTest", buf.toString()); 158 } 159 160 { 161 DynamicConverter<ILoggingEvent> converter = new LoggerConverter(); 162 this.optionList.clear(); 163 this.optionList.add("0"); 164 converter.setOptionList(this.optionList); 165 converter.start(); 166 StringBuilder buf = new StringBuilder(); 167 converter.write(buf, le); 168 assertEquals("ConverterTest", buf.toString()); 169 } 170 } 171 172 @Test 173 public void testVeryLongLoggerName() { 174 ClassicConverter converter = new LoggerConverter(); 175 this.optionList.add("5"); 176 converter.setOptionList(this.optionList); 177 converter.start(); 178 StringBuilder buf = new StringBuilder(); 179 180 char c = 'a'; 181 int extraParts = 3; 182 int totalParts = ClassicConstants.MAX_DOTS + extraParts; 183 StringBuilder loggerNameBuf = new StringBuilder(); 184 StringBuilder witness = new StringBuilder(); 185 186 for (int i = 0; i < totalParts; i++) { 187 loggerNameBuf.append(c).append(c).append(c); 188 if (i < ClassicConstants.MAX_DOTS) { 189 witness.append(c); 190 } else { 191 witness.append(c).append(c).append(c); 192 } 193 loggerNameBuf.append('.'); 194 witness.append('.'); 195 } 196 loggerNameBuf.append("zzzzzz"); 197 witness.append("zzzzzz"); 198 199 le.setLoggerName(loggerNameBuf.toString()); 200 converter.write(buf, le); 201 assertEquals(witness.toString(), buf.toString()); 202 } 203 204 @Test 205 public void testClass() { 206 DynamicConverter<ILoggingEvent> converter = new ClassOfCallerConverter(); 207 StringBuilder buf = new StringBuilder(); 208 converter.write(buf, le); 209 assertEquals(this.getClass().getName(), buf.toString()); 210 } 211 212 @Test 213 public void testMethodOfCaller() { 214 DynamicConverter<ILoggingEvent> converter = new MethodOfCallerConverter(); 215 StringBuilder buf = new StringBuilder(); 216 converter.write(buf, le); 217 assertEquals("testMethodOfCaller", buf.toString()); 218 } 219 220 @Test 221 public void testFileOfCaller() { 222 DynamicConverter<ILoggingEvent> converter = new FileOfCallerConverter(); 223 StringBuilder buf = new StringBuilder(); 224 converter.write(buf, le); 225 assertEquals("ConverterTest.java", buf.toString()); 226 } 227 228 @Test 229 public void testCallerData() { 230 { 231 DynamicConverter<ILoggingEvent> converter = new CallerDataConverter(); 232 converter.start(); 233 234 StringBuilder buf = new StringBuilder(); 235 converter.write(buf, le); 236 if (buf.length() < 10) { 237 fail("buf is too short"); 238 } 239 } 240 241 { 242 DynamicConverter<ILoggingEvent> converter = new CallerDataConverter(); 243 this.optionList.add("2"); 244 this.optionList.add("XXX"); 245 converter.setOptionList(this.optionList); 246 converter.start(); 247 248 StringBuilder buf = new StringBuilder(); 249 LoggingEvent event = makeLoggingEvent(null); 250 event.setMarker(MarkerFactory.getMarker("XXX")); 251 converter.write(buf, event); 252 if (buf.length() < 10) { 253 fail("buf is too short"); 254 } 255 } 256 257 { 258 DynamicConverter<ILoggingEvent> converter = new CallerDataConverter(); 259 this.optionList.clear(); 260 this.optionList.add("2"); 261 this.optionList.add("XXX"); 262 this.optionList.add("*"); 263 converter.setOptionList(this.optionList); 264 converter.start(); 265 266 StringBuilder buf = new StringBuilder(); 267 LoggingEvent event = makeLoggingEvent(null); 268 event.setMarker(MarkerFactory.getMarker("YYY")); 269 converter.write(buf, event); 270 if (buf.length() < 10) { 271 fail("buf is too short"); 272 } 273 } 274 { 275 DynamicConverter<ILoggingEvent> converter = new CallerDataConverter(); 276 this.optionList.clear(); 277 this.optionList.add("2"); 278 this.optionList.add("XXX"); 279 this.optionList.add("+"); 280 converter.setOptionList(this.optionList); 281 converter.start(); 282 283 StringBuilder buf = new StringBuilder(); 284 LoggingEvent event = makeLoggingEvent(null); 285 event.setMarker(MarkerFactory.getMarker("YYY")); 286 converter.write(buf, event); 287 if (buf.length() < 10) { 288 fail("buf is too short"); 289 } 290 } 291 292 { 293 DynamicConverter<ILoggingEvent> converter = new CallerDataConverter(); 294 this.optionList.clear(); 295 this.optionList.add("2"); 296 this.optionList.add("XXX"); 297 this.optionList.add("*"); 298 converter.setOptionList(this.optionList); 299 converter.start(); 300 301 StringBuilder buf = new StringBuilder(); 302 converter.write(buf, le); 303 if (buf.length() < 10) { 304 fail("buf is too short"); 305 } 306 // System.out.println(buf); 307 } 308 309 { 310 DynamicConverter<ILoggingEvent> converter = new CallerDataConverter(); 311 this.optionList.clear(); 312 this.optionList.add("4..5"); 313 converter.setOptionList(this.optionList); 314 converter.start(); 315 316 StringBuilder buf = new StringBuilder(); 317 converter.write(buf, le); 318 assertTrue("buf is too short", buf.length() >= 10); 319 320 String expectedRegex = "Caller\\+4\t at (java.base\\/)?java.lang.reflect.Method.invoke.*$"; 321 String actual = buf.toString(); 322 assertTrue("actual: "+actual, Pattern.compile(expectedRegex).matcher(actual).find()); 323 324 } 325 } 326 327 @Test 328 public void testRelativeTime() throws Exception { 329 DynamicConverter<ILoggingEvent> converter = new RelativeTimeConverter(); 330 StringBuilder buf0 = new StringBuilder(); 331 StringBuilder buf1 = new StringBuilder(); 332 long timestamp = System.currentTimeMillis(); 333 LoggingEvent e0 = makeLoggingEvent(null); 334 e0.setTimeStamp(timestamp); 335 LoggingEvent e1 = makeLoggingEvent(null); 336 e1.setTimeStamp(timestamp); 337 converter.write(buf0, e0); 338 converter.write(buf1, e1); 339 assertEquals(buf0.toString(), buf1.toString()); 340 } 341 342 @Test 343 public void testSyslogStart() throws Exception { 344 DynamicConverter<ILoggingEvent> converter = new SyslogStartConverter(); 345 this.optionList.clear(); 346 this.optionList.add("MAIL"); 347 converter.setOptionList(this.optionList); 348 converter.start(); 349 350 ILoggingEvent event = makeLoggingEvent(null); 351 352 StringBuilder buf = new StringBuilder(); 353 converter.write(buf, event); 354 355 String expected = "<" + (SyslogConstants.LOG_MAIL + SyslogConstants.INFO_SEVERITY) + ">"; 356 assertTrue(buf.toString().startsWith(expected)); 357 } 358 359 @Test 360 public void testMDCConverter() throws Exception { 361 MDC.clear(); 362 MDC.put("someKey", "someValue"); 363 MDCConverter converter = new MDCConverter(); 364 this.optionList.clear(); 365 this.optionList.add("someKey"); 366 converter.setOptionList(optionList); 367 converter.start(); 368 369 ILoggingEvent event = makeLoggingEvent(null); 370 371 String result = converter.convert(event); 372 assertEquals("someValue", result); 373 } 374 375 @Test 376 public void contextNameConverter() { 377 ClassicConverter converter = new ContextNameConverter(); 378 // see http://jira.qos.ch/browse/LBCLASSIC-149 379 LoggerContext lcOther = new LoggerContext(); 380 lcOther.setName("another"); 381 converter.setContext(lcOther); 382 383 lc.setName("aValue"); 384 ILoggingEvent event = makeLoggingEvent(null); 385 386 String result = converter.convert(event); 387 assertEquals("aValue", result); 388 } 389 390 @Test 391 public void contextProperty() { 392 PropertyConverter converter = new PropertyConverter(); 393 converter.setContext(lc); 394 List<String> ol = new ArrayList<String>(); 395 ol.add("k"); 396 converter.setOptionList(ol); 397 converter.start(); 398 lc.setName("aValue"); 399 lc.putProperty("k", "v"); 400 ILoggingEvent event = makeLoggingEvent(null); 401 402 String result = converter.convert(event); 403 assertEquals("v", result); 404 } 405}