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 }