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 */ 25package org.slf4j.impl; 26 27import java.io.Serializable; 28 29import org.apache.log4j.Level; 30import org.slf4j.Logger; 31import org.slf4j.Marker; 32import org.slf4j.helpers.FormattingTuple; 33import org.slf4j.helpers.MarkerIgnoringBase; 34import org.slf4j.helpers.MessageFormatter; 35import 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 */ 55public final class Log4jLoggerAdapter extends MarkerIgnoringBase implements LocationAwareLogger, Serializable { 56 57 private static final long serialVersionUID = 6182834493563598289L; 58 59 final transient org.apache.log4j.Logger logger; 60 61 /** 62 * Following the pattern discussed in pages 162 through 168 of "The complete 63 * log4j manual". 64 */ 65 final static String FQCN = Log4jLoggerAdapter.class.getName(); 66 67 // Does the log4j version in use recognize the TRACE level? 68 // The trace level was introduced in log4j 1.2.12. 69 final boolean traceCapable; 70 71 // WARN: Log4jLoggerAdapter constructor should have only package access so 72 // that 73 // only Log4jLoggerFactory be able to create one. 74 Log4jLoggerAdapter(org.apache.log4j.Logger logger) { 75 this.logger = logger; 76 this.name = logger.getName(); 77 traceCapable = isTraceCapable(); 78 } 79 80 private boolean isTraceCapable() { 81 try { 82 logger.isTraceEnabled(); 83 return true; 84 } catch (NoSuchMethodError e) { 85 return false; 86 } 87 } 88 89 /** 90 * Is this logger instance enabled for the TRACE level? 91 * 92 * @return True if this Logger is enabled for level TRACE, false otherwise. 93 */ 94 public boolean isTraceEnabled() { 95 if (traceCapable) { 96 return logger.isTraceEnabled(); 97 } else { 98 return logger.isDebugEnabled(); 99 } 100 } 101 102 /** 103 * Log a message object at level TRACE. 104 * 105 * @param msg 106 * - the message object to be logged 107 */ 108 public void trace(String msg) { 109 logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, msg, null); 110 } 111 112 /** 113 * Log a message at level TRACE according to the specified format and 114 * argument. 115 * 116 * <p> 117 * This form avoids superfluous object creation when the logger is disabled 118 * for level TRACE. 119 * </p> 120 * 121 * @param format 122 * the format string 123 * @param arg 124 * the argument 125 */ 126 public void trace(String format, Object arg) { 127 if (isTraceEnabled()) { 128 FormattingTuple ft = MessageFormatter.format(format, arg); 129 logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, ft.getMessage(), ft.getThrowable()); 130 } 131 } 132 133 /** 134 * Log a message at level TRACE according to the specified format and 135 * arguments. 136 * 137 * <p> 138 * This form avoids superfluous object creation when the logger is disabled 139 * for the TRACE level. 140 * </p> 141 * 142 * @param format 143 * the format string 144 * @param arg1 145 * the first argument 146 * @param arg2 147 * the second argument 148 */ 149 public void trace(String format, Object arg1, Object arg2) { 150 if (isTraceEnabled()) { 151 FormattingTuple ft = MessageFormatter.format(format, arg1, arg2); 152 logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, ft.getMessage(), ft.getThrowable()); 153 } 154 } 155 156 /** 157 * Log a message at level TRACE according to the specified format and 158 * arguments. 159 * 160 * <p> 161 * This form avoids superfluous object creation when the logger is disabled 162 * for the TRACE level. 163 * </p> 164 * 165 * @param format 166 * the format string 167 * @param arguments 168 * an array of arguments 169 */ 170 public void trace(String format, Object... arguments) { 171 if (isTraceEnabled()) { 172 FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments); 173 logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, ft.getMessage(), ft.getThrowable()); 174 } 175 } 176 177 /** 178 * Log an exception (throwable) at level TRACE with an accompanying message. 179 * 180 * @param msg 181 * the message accompanying the exception 182 * @param t 183 * the exception (throwable) to log 184 */ 185 public void trace(String msg, Throwable t) { 186 logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, msg, t); 187 } 188 189 /** 190 * Is this logger instance enabled for the DEBUG level? 191 * 192 * @return True if this Logger is enabled for level DEBUG, false otherwise. 193 */ 194 public boolean isDebugEnabled() { 195 return logger.isDebugEnabled(); 196 } 197 198 /** 199 * Log a message object at level DEBUG. 200 * 201 * @param msg 202 * - the message object to be logged 203 */ 204 public void debug(String msg) { 205 logger.log(FQCN, Level.DEBUG, msg, null); 206 } 207 208 /** 209 * Log a message at level DEBUG according to the specified format and 210 * argument. 211 * 212 * <p> 213 * This form avoids superfluous object creation when the logger is disabled 214 * for level DEBUG. 215 * </p> 216 * 217 * @param format 218 * the format string 219 * @param arg 220 * the argument 221 */ 222 public void debug(String format, Object arg) { 223 if (logger.isDebugEnabled()) { 224 FormattingTuple ft = MessageFormatter.format(format, arg); 225 logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable()); 226 } 227 } 228 229 /** 230 * Log a message at level DEBUG according to the specified format and 231 * arguments. 232 * 233 * <p> 234 * This form avoids superfluous object creation when the logger is disabled 235 * for the DEBUG level. 236 * </p> 237 * 238 * @param format 239 * the format string 240 * @param arg1 241 * the first argument 242 * @param arg2 243 * the second argument 244 */ 245 public void debug(String format, Object arg1, Object arg2) { 246 if (logger.isDebugEnabled()) { 247 FormattingTuple ft = MessageFormatter.format(format, arg1, arg2); 248 logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable()); 249 } 250 } 251 252 /** 253 * Log a message at level DEBUG according to the specified format and 254 * arguments. 255 * 256 * <p> 257 * This form avoids superfluous object creation when the logger is disabled 258 * for the DEBUG level. 259 * </p> 260 * 261 * @param format 262 * the format string 263 * @param arguments an array of arguments 264 */ 265 public void debug(String format, Object... arguments) { 266 if (logger.isDebugEnabled()) { 267 FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments); 268 logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable()); 269 } 270 } 271 272 /** 273 * Log an exception (throwable) at level DEBUG with an accompanying message. 274 * 275 * @param msg 276 * the message accompanying the exception 277 * @param t 278 * the exception (throwable) to log 279 */ 280 public void debug(String msg, Throwable t) { 281 logger.log(FQCN, Level.DEBUG, msg, t); 282 } 283 284 /** 285 * Is this logger instance enabled for the INFO level? 286 * 287 * @return True if this Logger is enabled for the INFO level, false otherwise. 288 */ 289 public boolean isInfoEnabled() { 290 return logger.isInfoEnabled(); 291 } 292 293 /** 294 * Log a message object at the INFO level. 295 * 296 * @param msg 297 * - the message object to be logged 298 */ 299 public void info(String msg) { 300 logger.log(FQCN, Level.INFO, msg, null); 301 } 302 303 /** 304 * Log a message at level INFO according to the specified format and argument. 305 * 306 * <p> 307 * This form avoids superfluous object creation when the logger is disabled 308 * for the INFO level. 309 * </p> 310 * 311 * @param format 312 * the format string 313 * @param arg 314 * the argument 315 */ 316 public void info(String format, Object arg) { 317 if (logger.isInfoEnabled()) { 318 FormattingTuple ft = MessageFormatter.format(format, arg); 319 logger.log(FQCN, Level.INFO, ft.getMessage(), ft.getThrowable()); 320 } 321 } 322 323 /** 324 * Log a message at the INFO level according to the specified format and 325 * arguments. 326 * 327 * <p> 328 * This form avoids superfluous object creation when the logger is disabled 329 * for the INFO level. 330 * </p> 331 * 332 * @param format 333 * the format string 334 * @param arg1 335 * the first argument 336 * @param arg2 337 * the second argument 338 */ 339 public void info(String format, Object arg1, Object arg2) { 340 if (logger.isInfoEnabled()) { 341 FormattingTuple ft = MessageFormatter.format(format, arg1, arg2); 342 logger.log(FQCN, Level.INFO, ft.getMessage(), ft.getThrowable()); 343 } 344 } 345 346 /** 347 * Log a message at level INFO according to the specified format and 348 * arguments. 349 * 350 * <p> 351 * This form avoids superfluous object creation when the logger is disabled 352 * for the INFO level. 353 * </p> 354 * 355 * @param format 356 * the format string 357 * @param argArray 358 * an array of arguments 359 */ 360 public void info(String format, Object... argArray) { 361 if (logger.isInfoEnabled()) { 362 FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); 363 logger.log(FQCN, Level.INFO, ft.getMessage(), ft.getThrowable()); 364 } 365 } 366 367 /** 368 * Log an exception (throwable) at the INFO level with an accompanying 369 * message. 370 * 371 * @param msg 372 * the message accompanying the exception 373 * @param t 374 * the exception (throwable) to log 375 */ 376 public void info(String msg, Throwable t) { 377 logger.log(FQCN, Level.INFO, msg, t); 378 } 379 380 /** 381 * Is this logger instance enabled for the WARN level? 382 * 383 * @return True if this Logger is enabled for the WARN level, false otherwise. 384 */ 385 public boolean isWarnEnabled() { 386 return logger.isEnabledFor(Level.WARN); 387 } 388 389 /** 390 * Log a message object at the WARN level. 391 * 392 * @param msg 393 * - the message object to be logged 394 */ 395 public void warn(String msg) { 396 logger.log(FQCN, Level.WARN, msg, null); 397 } 398 399 /** 400 * Log a message at the WARN level according to the specified format and 401 * argument. 402 * 403 * <p> 404 * This form avoids superfluous object creation when the logger is disabled 405 * for the WARN level. 406 * </p> 407 * 408 * @param format 409 * the format string 410 * @param arg 411 * the argument 412 */ 413 public void warn(String format, Object arg) { 414 if (logger.isEnabledFor(Level.WARN)) { 415 FormattingTuple ft = MessageFormatter.format(format, arg); 416 logger.log(FQCN, Level.WARN, ft.getMessage(), ft.getThrowable()); 417 } 418 } 419 420 /** 421 * Log a message at the WARN level according to the specified format and 422 * arguments. 423 * 424 * <p> 425 * This form avoids superfluous object creation when the logger is disabled 426 * for the WARN level. 427 * </p> 428 * 429 * @param format 430 * the format string 431 * @param arg1 432 * the first argument 433 * @param arg2 434 * the second argument 435 */ 436 public void warn(String format, Object arg1, Object arg2) { 437 if (logger.isEnabledFor(Level.WARN)) { 438 FormattingTuple ft = MessageFormatter.format(format, arg1, arg2); 439 logger.log(FQCN, Level.WARN, ft.getMessage(), ft.getThrowable()); 440 } 441 } 442 443 /** 444 * Log a message at level WARN according to the specified format and 445 * arguments. 446 * 447 * <p> 448 * This form avoids superfluous object creation when the logger is disabled 449 * for the WARN level. 450 * </p> 451 * 452 * @param format 453 * the format string 454 * @param argArray 455 * an array of arguments 456 */ 457 public void warn(String format, Object... argArray) { 458 if (logger.isEnabledFor(Level.WARN)) { 459 FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); 460 logger.log(FQCN, Level.WARN, ft.getMessage(), ft.getThrowable()); 461 } 462 } 463 464 /** 465 * Log an exception (throwable) at the WARN level with an accompanying 466 * message. 467 * 468 * @param msg 469 * the message accompanying the exception 470 * @param t 471 * the exception (throwable) to log 472 */ 473 public void warn(String msg, Throwable t) { 474 logger.log(FQCN, Level.WARN, msg, t); 475 } 476 477 /** 478 * Is this logger instance enabled for level ERROR? 479 * 480 * @return True if this Logger is enabled for level ERROR, false otherwise. 481 */ 482 public boolean isErrorEnabled() { 483 return logger.isEnabledFor(Level.ERROR); 484 } 485 486 /** 487 * Log a message object at the ERROR level. 488 * 489 * @param msg 490 * - the message object to be logged 491 */ 492 public void error(String msg) { 493 logger.log(FQCN, Level.ERROR, msg, null); 494 } 495 496 /** 497 * Log a message at the ERROR level according to the specified format and 498 * argument. 499 * 500 * <p> 501 * This form avoids superfluous object creation when the logger is disabled 502 * for the ERROR level. 503 * </p> 504 * 505 * @param format 506 * the format string 507 * @param arg 508 * the argument 509 */ 510 public void error(String format, Object arg) { 511 if (logger.isEnabledFor(Level.ERROR)) { 512 FormattingTuple ft = MessageFormatter.format(format, arg); 513 logger.log(FQCN, Level.ERROR, ft.getMessage(), ft.getThrowable()); 514 } 515 } 516 517 /** 518 * Log a message at the ERROR level according to the specified format and 519 * arguments. 520 * 521 * <p> 522 * This form avoids superfluous object creation when the logger is disabled 523 * for the ERROR level. 524 * </p> 525 * 526 * @param format 527 * the format string 528 * @param arg1 529 * the first argument 530 * @param arg2 531 * the second argument 532 */ 533 public void error(String format, Object arg1, Object arg2) { 534 if (logger.isEnabledFor(Level.ERROR)) { 535 FormattingTuple ft = MessageFormatter.format(format, arg1, arg2); 536 logger.log(FQCN, Level.ERROR, ft.getMessage(), ft.getThrowable()); 537 } 538 } 539 540 /** 541 * Log a message at level ERROR according to the specified format and 542 * arguments. 543 * 544 * <p> 545 * This form avoids superfluous object creation when the logger is disabled 546 * for the ERROR level. 547 * </p> 548 * 549 * @param format 550 * the format string 551 * @param argArray 552 * an array of arguments 553 */ 554 public void error(String format, Object... argArray) { 555 if (logger.isEnabledFor(Level.ERROR)) { 556 FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); 557 logger.log(FQCN, Level.ERROR, ft.getMessage(), ft.getThrowable()); 558 } 559 } 560 561 /** 562 * Log an exception (throwable) at the ERROR level with an accompanying 563 * message. 564 * 565 * @param msg 566 * the message accompanying the exception 567 * @param t 568 * the exception (throwable) to log 569 */ 570 public void error(String msg, Throwable t) { 571 logger.log(FQCN, Level.ERROR, msg, t); 572 } 573 574 public void log(Marker marker, String callerFQCN, int level, String msg, Object[] argArray, Throwable t) { 575 Level log4jLevel; 576 switch (level) { 577 case LocationAwareLogger.TRACE_INT: 578 log4jLevel = traceCapable ? Level.TRACE : Level.DEBUG; 579 break; 580 case LocationAwareLogger.DEBUG_INT: 581 log4jLevel = Level.DEBUG; 582 break; 583 case LocationAwareLogger.INFO_INT: 584 log4jLevel = Level.INFO; 585 break; 586 case LocationAwareLogger.WARN_INT: 587 log4jLevel = Level.WARN; 588 break; 589 case LocationAwareLogger.ERROR_INT: 590 log4jLevel = Level.ERROR; 591 break; 592 default: 593 throw new IllegalStateException("Level number " + level + " is not recognized."); 594 } 595 logger.log(callerFQCN, log4jLevel, msg, t); 596 } 597 598} 599