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