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 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 }