1 /** 2 * Copyright (c) 2004-2011 QOS.ch 3 * All rights reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be 14 * included in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 */ 25 package org.slf4j.impl; 26 27 import java.io.Serializable; 28 29 import org.apache.log4j.Level; 30 import org.slf4j.Logger; 31 import org.slf4j.Marker; 32 import org.slf4j.helpers.FormattingTuple; 33 import org.slf4j.helpers.MarkerIgnoringBase; 34 import org.slf4j.helpers.MessageFormatter; 35 import org.slf4j.spi.LocationAwareLogger; 36 37 /** 38 * A wrapper over {@link org.apache.log4j.Logger org.apache.log4j.Logger} in 39 * conforming to the {@link Logger} interface. 40 * 41 * <p> 42 * Note that the logging levels mentioned in this class refer to those defined 43 * in the <a 44 * href="http://logging.apache.org/log4j/docs/api/org/apache/log4j/Level.html"> 45 * <code>org.apache.log4j.Level</code></a> class. 46 * 47 * <p> 48 * The TRACE level was introduced in log4j version 1.2.12. In order to avoid 49 * crashing the host application, in the case the log4j version in use predates 50 * 1.2.12, the TRACE level will be mapped as DEBUG. See also <a 51 * href="http://bugzilla.slf4j.org/show_bug.cgi?id=68">bug 68</a>. 52 * 53 * @author Ceki Gülcü 54 */ 55 public final class Log4jLoggerAdapter extends MarkerIgnoringBase implements 56 LocationAwareLogger, Serializable { 57 58 private static final long serialVersionUID = 6182834493563598289L; 59 60 final transient org.apache.log4j.Logger logger; 61 62 /** 63 * Following the pattern discussed in pages 162 through 168 of "The complete 64 * log4j manual". 65 */ 66 final static String FQCN = Log4jLoggerAdapter.class.getName(); 67 68 // Does the log4j version in use recognize the TRACE level? 69 // The trace level was introduced in log4j 1.2.12. 70 final boolean traceCapable; 71 72 // WARN: Log4jLoggerAdapter constructor should have only package access so 73 // that 74 // only Log4jLoggerFactory be able to create one. 75 Log4jLoggerAdapter(org.apache.log4j.Logger logger) { 76 this.logger = logger; 77 this.name = logger.getName(); 78 traceCapable = isTraceCapable(); 79 } 80 81 private boolean isTraceCapable() { 82 try { 83 logger.isTraceEnabled(); 84 return true; 85 } catch (NoSuchMethodError e) { 86 return false; 87 } 88 } 89 90 /** 91 * Is this logger instance enabled for the TRACE level? 92 * 93 * @return True if this Logger is enabled for level TRACE, false otherwise. 94 */ 95 public boolean isTraceEnabled() { 96 if (traceCapable) { 97 return logger.isTraceEnabled(); 98 } else { 99 return logger.isDebugEnabled(); 100 } 101 } 102 103 /** 104 * Log a message object at level TRACE. 105 * 106 * @param msg 107 * - the message object to be logged 108 */ 109 public void trace(String msg) { 110 logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, msg, null); 111 } 112 113 /** 114 * Log a message at level TRACE according to the specified format and 115 * argument. 116 * 117 * <p> 118 * This form avoids superfluous object creation when the logger is disabled 119 * for level TRACE. 120 * </p> 121 * 122 * @param format 123 * the format string 124 * @param arg 125 * the argument 126 */ 127 public void trace(String format, Object arg) { 128 if (isTraceEnabled()) { 129 FormattingTuple ft = MessageFormatter.format(format, arg); 130 logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, ft 131 .getMessage(), ft.getThrowable()); 132 } 133 } 134 135 /** 136 * Log a message at level TRACE according to the specified format and 137 * arguments. 138 * 139 * <p> 140 * This form avoids superfluous object creation when the logger is disabled 141 * for the TRACE level. 142 * </p> 143 * 144 * @param format 145 * the format string 146 * @param arg1 147 * the first argument 148 * @param arg2 149 * the second argument 150 */ 151 public void trace(String format, Object arg1, Object arg2) { 152 if (isTraceEnabled()) { 153 FormattingTuple ft = MessageFormatter.format(format, arg1, arg2); 154 logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, ft 155 .getMessage(), ft.getThrowable()); 156 } 157 } 158 159 /** 160 * Log a message at level TRACE according to the specified format and 161 * arguments. 162 * 163 * <p> 164 * This form avoids superfluous object creation when the logger is disabled 165 * for the TRACE level. 166 * </p> 167 * 168 * @param format 169 * the format string 170 * @param argArray 171 * an array of arguments 172 */ 173 public void trace(String format, Object[] argArray) { 174 if (isTraceEnabled()) { 175 FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); 176 logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, ft 177 .getMessage(), ft.getThrowable()); 178 } 179 } 180 181 /** 182 * Log an exception (throwable) at level TRACE with an accompanying message. 183 * 184 * @param msg 185 * the message accompanying the exception 186 * @param t 187 * the exception (throwable) to log 188 */ 189 public void trace(String msg, Throwable t) { 190 logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, msg, t); 191 } 192 193 /** 194 * Is this logger instance enabled for the DEBUG level? 195 * 196 * @return True if this Logger is enabled for level DEBUG, false otherwise. 197 */ 198 public boolean isDebugEnabled() { 199 return logger.isDebugEnabled(); 200 } 201 202 /** 203 * Log a message object at level DEBUG. 204 * 205 * @param msg 206 * - the message object to be logged 207 */ 208 public void debug(String msg) { 209 logger.log(FQCN, Level.DEBUG, msg, null); 210 } 211 212 /** 213 * Log a message at level DEBUG according to the specified format and 214 * argument. 215 * 216 * <p> 217 * This form avoids superfluous object creation when the logger is disabled 218 * for level DEBUG. 219 * </p> 220 * 221 * @param format 222 * the format string 223 * @param arg 224 * the argument 225 */ 226 public void debug(String format, Object arg) { 227 if (logger.isDebugEnabled()) { 228 FormattingTuple ft = MessageFormatter.format(format, arg); 229 logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable()); 230 } 231 } 232 233 /** 234 * Log a message at level DEBUG according to the specified format and 235 * arguments. 236 * 237 * <p> 238 * This form avoids superfluous object creation when the logger is disabled 239 * for the DEBUG level. 240 * </p> 241 * 242 * @param format 243 * the format string 244 * @param arg1 245 * the first argument 246 * @param arg2 247 * the second argument 248 */ 249 public void debug(String format, Object arg1, Object arg2) { 250 if (logger.isDebugEnabled()) { 251 FormattingTuple ft = MessageFormatter.format(format, arg1, arg2); 252 logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable()); 253 } 254 } 255 256 /** 257 * Log a message at level DEBUG according to the specified format and 258 * arguments. 259 * 260 * <p> 261 * This form avoids superfluous object creation when the logger is disabled 262 * for the DEBUG level. 263 * </p> 264 * 265 * @param format 266 * the format string 267 * @param argArray 268 * an array of arguments 269 */ 270 public void debug(String format, Object[] argArray) { 271 if (logger.isDebugEnabled()) { 272 FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); 273 logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable()); 274 } 275 } 276 277 /** 278 * Log an exception (throwable) at level DEBUG with an accompanying message. 279 * 280 * @param msg 281 * the message accompanying the exception 282 * @param t 283 * the exception (throwable) to log 284 */ 285 public void debug(String msg, Throwable t) { 286 logger.log(FQCN, Level.DEBUG, msg, t); 287 } 288 289 /** 290 * Is this logger instance enabled for the INFO level? 291 * 292 * @return True if this Logger is enabled for the INFO level, false otherwise. 293 */ 294 public boolean isInfoEnabled() { 295 return logger.isInfoEnabled(); 296 } 297 298 /** 299 * Log a message object at the INFO level. 300 * 301 * @param msg 302 * - the message object to be logged 303 */ 304 public void info(String msg) { 305 logger.log(FQCN, Level.INFO, msg, null); 306 } 307 308 /** 309 * Log a message at level INFO according to the specified format and argument. 310 * 311 * <p> 312 * This form avoids superfluous object creation when the logger is disabled 313 * for the INFO level. 314 * </p> 315 * 316 * @param format 317 * the format string 318 * @param arg 319 * the argument 320 */ 321 public void info(String format, Object arg) { 322 if (logger.isInfoEnabled()) { 323 FormattingTuple ft = MessageFormatter.format(format, arg); 324 logger.log(FQCN, Level.INFO, ft.getMessage(), ft.getThrowable()); 325 } 326 } 327 328 /** 329 * Log a message at the INFO level according to the specified format and 330 * arguments. 331 * 332 * <p> 333 * This form avoids superfluous object creation when the logger is disabled 334 * for the INFO level. 335 * </p> 336 * 337 * @param format 338 * the format string 339 * @param arg1 340 * the first argument 341 * @param arg2 342 * the second argument 343 */ 344 public void info(String format, Object arg1, Object arg2) { 345 if (logger.isInfoEnabled()) { 346 FormattingTuple ft = MessageFormatter.format(format, arg1, arg2); 347 logger.log(FQCN, Level.INFO, ft.getMessage(), ft.getThrowable()); 348 } 349 } 350 351 /** 352 * Log a message at level INFO according to the specified format and 353 * arguments. 354 * 355 * <p> 356 * This form avoids superfluous object creation when the logger is disabled 357 * for the INFO level. 358 * </p> 359 * 360 * @param format 361 * the format string 362 * @param argArray 363 * an array of arguments 364 */ 365 public void info(String format, Object[] argArray) { 366 if (logger.isInfoEnabled()) { 367 FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); 368 logger.log(FQCN, Level.INFO, ft.getMessage(), ft.getThrowable()); 369 } 370 } 371 372 /** 373 * Log an exception (throwable) at the INFO level with an accompanying 374 * message. 375 * 376 * @param msg 377 * the message accompanying the exception 378 * @param t 379 * the exception (throwable) to log 380 */ 381 public void info(String msg, Throwable t) { 382 logger.log(FQCN, Level.INFO, msg, t); 383 } 384 385 /** 386 * Is this logger instance enabled for the WARN level? 387 * 388 * @return True if this Logger is enabled for the WARN level, false otherwise. 389 */ 390 public boolean isWarnEnabled() { 391 return logger.isEnabledFor(Level.WARN); 392 } 393 394 /** 395 * Log a message object at the WARN level. 396 * 397 * @param msg 398 * - the message object to be logged 399 */ 400 public void warn(String msg) { 401 logger.log(FQCN, Level.WARN, msg, null); 402 } 403 404 /** 405 * Log a message at the WARN level according to the specified format and 406 * argument. 407 * 408 * <p> 409 * This form avoids superfluous object creation when the logger is disabled 410 * for the WARN level. 411 * </p> 412 * 413 * @param format 414 * the format string 415 * @param arg 416 * the argument 417 */ 418 public void warn(String format, Object arg) { 419 if (logger.isEnabledFor(Level.WARN)) { 420 FormattingTuple ft = MessageFormatter.format(format, arg); 421 logger.log(FQCN, Level.WARN, ft.getMessage(), ft.getThrowable()); 422 } 423 } 424 425 /** 426 * Log a message at the WARN level according to the specified format and 427 * arguments. 428 * 429 * <p> 430 * This form avoids superfluous object creation when the logger is disabled 431 * for the WARN level. 432 * </p> 433 * 434 * @param format 435 * the format string 436 * @param arg1 437 * the first argument 438 * @param arg2 439 * the second argument 440 */ 441 public void warn(String format, Object arg1, Object arg2) { 442 if (logger.isEnabledFor(Level.WARN)) { 443 FormattingTuple ft = MessageFormatter.format(format, arg1, arg2); 444 logger.log(FQCN, Level.WARN, ft.getMessage(), ft.getThrowable()); 445 } 446 } 447 448 /** 449 * Log a message at level WARN according to the specified format and 450 * arguments. 451 * 452 * <p> 453 * This form avoids superfluous object creation when the logger is disabled 454 * for the WARN level. 455 * </p> 456 * 457 * @param format 458 * the format string 459 * @param argArray 460 * an array of arguments 461 */ 462 public void warn(String format, Object[] argArray) { 463 if (logger.isEnabledFor(Level.WARN)) { 464 FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); 465 logger.log(FQCN, Level.WARN, ft.getMessage(), ft.getThrowable()); 466 } 467 } 468 469 /** 470 * Log an exception (throwable) at the WARN level with an accompanying 471 * message. 472 * 473 * @param msg 474 * the message accompanying the exception 475 * @param t 476 * the exception (throwable) to log 477 */ 478 public void warn(String msg, Throwable t) { 479 logger.log(FQCN, Level.WARN, msg, t); 480 } 481 482 /** 483 * Is this logger instance enabled for level ERROR? 484 * 485 * @return True if this Logger is enabled for level ERROR, false otherwise. 486 */ 487 public boolean isErrorEnabled() { 488 return logger.isEnabledFor(Level.ERROR); 489 } 490 491 /** 492 * Log a message object at the ERROR level. 493 * 494 * @param msg 495 * - the message object to be logged 496 */ 497 public void error(String msg) { 498 logger.log(FQCN, Level.ERROR, msg, null); 499 } 500 501 /** 502 * Log a message at the ERROR level according to the specified format and 503 * argument. 504 * 505 * <p> 506 * This form avoids superfluous object creation when the logger is disabled 507 * for the ERROR level. 508 * </p> 509 * 510 * @param format 511 * the format string 512 * @param arg 513 * the argument 514 */ 515 public void error(String format, Object arg) { 516 if (logger.isEnabledFor(Level.ERROR)) { 517 FormattingTuple ft = MessageFormatter.format(format, arg); 518 logger.log(FQCN, Level.ERROR, ft.getMessage(), ft.getThrowable()); 519 } 520 } 521 522 /** 523 * Log a message at the ERROR level according to the specified format and 524 * arguments. 525 * 526 * <p> 527 * This form avoids superfluous object creation when the logger is disabled 528 * for the ERROR level. 529 * </p> 530 * 531 * @param format 532 * the format string 533 * @param arg1 534 * the first argument 535 * @param arg2 536 * the second argument 537 */ 538 public void error(String format, Object arg1, Object arg2) { 539 if (logger.isEnabledFor(Level.ERROR)) { 540 FormattingTuple ft = MessageFormatter.format(format, arg1, arg2); 541 logger.log(FQCN, Level.ERROR, ft.getMessage(), ft.getThrowable()); 542 } 543 } 544 545 /** 546 * Log a message at level ERROR according to the specified format and 547 * arguments. 548 * 549 * <p> 550 * This form avoids superfluous object creation when the logger is disabled 551 * for the ERROR level. 552 * </p> 553 * 554 * @param format 555 * the format string 556 * @param argArray 557 * an array of arguments 558 */ 559 public void error(String format, Object[] argArray) { 560 if (logger.isEnabledFor(Level.ERROR)) { 561 FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); 562 logger.log(FQCN, Level.ERROR, ft.getMessage(), ft.getThrowable()); 563 } 564 } 565 566 /** 567 * Log an exception (throwable) at the ERROR level with an accompanying 568 * message. 569 * 570 * @param msg 571 * the message accompanying the exception 572 * @param t 573 * the exception (throwable) to log 574 */ 575 public void error(String msg, Throwable t) { 576 logger.log(FQCN, Level.ERROR, msg, t); 577 } 578 579 public void log(Marker marker, String callerFQCN, int level, String msg, 580 Object[] argArray, Throwable t) { 581 Level log4jLevel; 582 switch (level) { 583 case LocationAwareLogger.TRACE_INT: 584 log4jLevel = traceCapable ? Level.TRACE : Level.DEBUG; 585 break; 586 case LocationAwareLogger.DEBUG_INT: 587 log4jLevel = Level.DEBUG; 588 break; 589 case LocationAwareLogger.INFO_INT: 590 log4jLevel = Level.INFO; 591 break; 592 case LocationAwareLogger.WARN_INT: 593 log4jLevel = Level.WARN; 594 break; 595 case LocationAwareLogger.ERROR_INT: 596 log4jLevel = Level.ERROR; 597 break; 598 default: 599 throw new IllegalStateException("Level number " + level 600 + " is not recognized."); 601 } 602 logger.log(callerFQCN, log4jLevel, msg, t); 603 } 604 605 }