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 arguments 171 * an array of arguments 172 */ 173 public void trace(String format, Object... arguments) { 174 if (isTraceEnabled()) { 175 FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments); 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 arguments an array of arguments 268 */ 269 public void debug(String format, Object... arguments) { 270 if (logger.isDebugEnabled()) { 271 FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments); 272 logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable()); 273 } 274 } 275 276 /** 277 * Log an exception (throwable) at level DEBUG with an accompanying message. 278 * 279 * @param msg 280 * the message accompanying the exception 281 * @param t 282 * the exception (throwable) to log 283 */ 284 public void debug(String msg, Throwable t) { 285 logger.log(FQCN, Level.DEBUG, msg, t); 286 } 287 288 /** 289 * Is this logger instance enabled for the INFO level? 290 * 291 * @return True if this Logger is enabled for the INFO level, false otherwise. 292 */ 293 public boolean isInfoEnabled() { 294 return logger.isInfoEnabled(); 295 } 296 297 /** 298 * Log a message object at the INFO level. 299 * 300 * @param msg 301 * - the message object to be logged 302 */ 303 public void info(String msg) { 304 logger.log(FQCN, Level.INFO, msg, null); 305 } 306 307 /** 308 * Log a message at level INFO according to the specified format and argument. 309 * 310 * <p> 311 * This form avoids superfluous object creation when the logger is disabled 312 * for the INFO level. 313 * </p> 314 * 315 * @param format 316 * the format string 317 * @param arg 318 * the argument 319 */ 320 public void info(String format, Object arg) { 321 if (logger.isInfoEnabled()) { 322 FormattingTuple ft = MessageFormatter.format(format, arg); 323 logger.log(FQCN, Level.INFO, ft.getMessage(), ft.getThrowable()); 324 } 325 } 326 327 /** 328 * Log a message at the INFO level according to the specified format and 329 * arguments. 330 * 331 * <p> 332 * This form avoids superfluous object creation when the logger is disabled 333 * for the INFO level. 334 * </p> 335 * 336 * @param format 337 * the format string 338 * @param arg1 339 * the first argument 340 * @param arg2 341 * the second argument 342 */ 343 public void info(String format, Object arg1, Object arg2) { 344 if (logger.isInfoEnabled()) { 345 FormattingTuple ft = MessageFormatter.format(format, arg1, arg2); 346 logger.log(FQCN, Level.INFO, ft.getMessage(), ft.getThrowable()); 347 } 348 } 349 350 /** 351 * Log a message at level INFO according to the specified format and 352 * arguments. 353 * 354 * <p> 355 * This form avoids superfluous object creation when the logger is disabled 356 * for the INFO level. 357 * </p> 358 * 359 * @param format 360 * the format string 361 * @param argArray 362 * an array of arguments 363 */ 364 public void info(String format, Object... argArray) { 365 if (logger.isInfoEnabled()) { 366 FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); 367 logger.log(FQCN, Level.INFO, ft.getMessage(), ft.getThrowable()); 368 } 369 } 370 371 /** 372 * Log an exception (throwable) at the INFO level with an accompanying 373 * message. 374 * 375 * @param msg 376 * the message accompanying the exception 377 * @param t 378 * the exception (throwable) to log 379 */ 380 public void info(String msg, Throwable t) { 381 logger.log(FQCN, Level.INFO, msg, t); 382 } 383 384 /** 385 * Is this logger instance enabled for the WARN level? 386 * 387 * @return True if this Logger is enabled for the WARN level, false otherwise. 388 */ 389 public boolean isWarnEnabled() { 390 return logger.isEnabledFor(Level.WARN); 391 } 392 393 /** 394 * Log a message object at the WARN level. 395 * 396 * @param msg 397 * - the message object to be logged 398 */ 399 public void warn(String msg) { 400 logger.log(FQCN, Level.WARN, msg, null); 401 } 402 403 /** 404 * Log a message at the WARN level according to the specified format and 405 * argument. 406 * 407 * <p> 408 * This form avoids superfluous object creation when the logger is disabled 409 * for the WARN level. 410 * </p> 411 * 412 * @param format 413 * the format string 414 * @param arg 415 * the argument 416 */ 417 public void warn(String format, Object arg) { 418 if (logger.isEnabledFor(Level.WARN)) { 419 FormattingTuple ft = MessageFormatter.format(format, arg); 420 logger.log(FQCN, Level.WARN, ft.getMessage(), ft.getThrowable()); 421 } 422 } 423 424 /** 425 * Log a message at the WARN level according to the specified format and 426 * arguments. 427 * 428 * <p> 429 * This form avoids superfluous object creation when the logger is disabled 430 * for the WARN level. 431 * </p> 432 * 433 * @param format 434 * the format string 435 * @param arg1 436 * the first argument 437 * @param arg2 438 * the second argument 439 */ 440 public void warn(String format, Object arg1, Object arg2) { 441 if (logger.isEnabledFor(Level.WARN)) { 442 FormattingTuple ft = MessageFormatter.format(format, arg1, arg2); 443 logger.log(FQCN, Level.WARN, ft.getMessage(), ft.getThrowable()); 444 } 445 } 446 447 /** 448 * Log a message at level WARN according to the specified format and 449 * arguments. 450 * 451 * <p> 452 * This form avoids superfluous object creation when the logger is disabled 453 * for the WARN level. 454 * </p> 455 * 456 * @param format 457 * the format string 458 * @param argArray 459 * an array of arguments 460 */ 461 public void warn(String format, Object... argArray) { 462 if (logger.isEnabledFor(Level.WARN)) { 463 FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); 464 logger.log(FQCN, Level.WARN, ft.getMessage(), ft.getThrowable()); 465 } 466 } 467 468 /** 469 * Log an exception (throwable) at the WARN level with an accompanying 470 * message. 471 * 472 * @param msg 473 * the message accompanying the exception 474 * @param t 475 * the exception (throwable) to log 476 */ 477 public void warn(String msg, Throwable t) { 478 logger.log(FQCN, Level.WARN, msg, t); 479 } 480 481 /** 482 * Is this logger instance enabled for level ERROR? 483 * 484 * @return True if this Logger is enabled for level ERROR, false otherwise. 485 */ 486 public boolean isErrorEnabled() { 487 return logger.isEnabledFor(Level.ERROR); 488 } 489 490 /** 491 * Log a message object at the ERROR level. 492 * 493 * @param msg 494 * - the message object to be logged 495 */ 496 public void error(String msg) { 497 logger.log(FQCN, Level.ERROR, msg, null); 498 } 499 500 /** 501 * Log a message at the ERROR level according to the specified format and 502 * argument. 503 * 504 * <p> 505 * This form avoids superfluous object creation when the logger is disabled 506 * for the ERROR level. 507 * </p> 508 * 509 * @param format 510 * the format string 511 * @param arg 512 * the argument 513 */ 514 public void error(String format, Object arg) { 515 if (logger.isEnabledFor(Level.ERROR)) { 516 FormattingTuple ft = MessageFormatter.format(format, arg); 517 logger.log(FQCN, Level.ERROR, ft.getMessage(), ft.getThrowable()); 518 } 519 } 520 521 /** 522 * Log a message at the ERROR level according to the specified format and 523 * arguments. 524 * 525 * <p> 526 * This form avoids superfluous object creation when the logger is disabled 527 * for the ERROR level. 528 * </p> 529 * 530 * @param format 531 * the format string 532 * @param arg1 533 * the first argument 534 * @param arg2 535 * the second argument 536 */ 537 public void error(String format, Object arg1, Object arg2) { 538 if (logger.isEnabledFor(Level.ERROR)) { 539 FormattingTuple ft = MessageFormatter.format(format, arg1, arg2); 540 logger.log(FQCN, Level.ERROR, ft.getMessage(), ft.getThrowable()); 541 } 542 } 543 544 /** 545 * Log a message at level ERROR according to the specified format and 546 * arguments. 547 * 548 * <p> 549 * This form avoids superfluous object creation when the logger is disabled 550 * for the ERROR level. 551 * </p> 552 * 553 * @param format 554 * the format string 555 * @param argArray 556 * an array of arguments 557 */ 558 public void error(String format, Object... argArray) { 559 if (logger.isEnabledFor(Level.ERROR)) { 560 FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); 561 logger.log(FQCN, Level.ERROR, ft.getMessage(), ft.getThrowable()); 562 } 563 } 564 565 /** 566 * Log an exception (throwable) at the ERROR level with an accompanying 567 * message. 568 * 569 * @param msg 570 * the message accompanying the exception 571 * @param t 572 * the exception (throwable) to log 573 */ 574 public void error(String msg, Throwable t) { 575 logger.log(FQCN, Level.ERROR, msg, t); 576 } 577 578 public void log(Marker marker, String callerFQCN, int level, String msg, 579 Object[] argArray, Throwable t) { 580 Level log4jLevel; 581 switch (level) { 582 case LocationAwareLogger.TRACE_INT: 583 log4jLevel = traceCapable ? Level.TRACE : Level.DEBUG; 584 break; 585 case LocationAwareLogger.DEBUG_INT: 586 log4jLevel = Level.DEBUG; 587 break; 588 case LocationAwareLogger.INFO_INT: 589 log4jLevel = Level.INFO; 590 break; 591 case LocationAwareLogger.WARN_INT: 592 log4jLevel = Level.WARN; 593 break; 594 case LocationAwareLogger.ERROR_INT: 595 log4jLevel = Level.ERROR; 596 break; 597 default: 598 throw new IllegalStateException("Level number " + level 599 + " is not recognized."); 600 } 601 logger.log(callerFQCN, log4jLevel, msg, t); 602 } 603 604 }