View Javadoc

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&uuml;lc&uuml;
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 }