1   /*
2    * Copyright (c) 2004-2005 SLF4J.ORG
3    * Copyright (c) 2004-2005 QOS.ch
4    *
5    * All rights reserved.
6    *
7    * Permission is hereby granted, free of charge, to any person obtaining
8    * a copy of this software and associated documentation files (the
9    * "Software"), to  deal in  the Software without  restriction, including
10   * without limitation  the rights to  use, copy, modify,  merge, publish,
11   * distribute, and/or sell copies of  the Software, and to permit persons
12   * to whom  the Software is furnished  to do so, provided  that the above
13   * copyright notice(s) and this permission notice appear in all copies of
14   * the  Software and  that both  the above  copyright notice(s)  and this
15   * permission notice appear in supporting documentation.
16   *
17   * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
18   * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
19   * MERCHANTABILITY, FITNESS FOR  A PARTICULAR PURPOSE AND NONINFRINGEMENT
20   * OF  THIRD PARTY  RIGHTS. IN  NO EVENT  SHALL THE  COPYRIGHT  HOLDER OR
21   * HOLDERS  INCLUDED IN  THIS  NOTICE BE  LIABLE  FOR ANY  CLAIM, OR  ANY
22   * SPECIAL INDIRECT  OR CONSEQUENTIAL DAMAGES, OR  ANY DAMAGES WHATSOEVER
23   * RESULTING FROM LOSS  OF USE, DATA OR PROFITS, WHETHER  IN AN ACTION OF
24   * CONTRACT, NEGLIGENCE  OR OTHER TORTIOUS  ACTION, ARISING OUT OF  OR IN
25   * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26   *
27   * Except as  contained in  this notice, the  name of a  copyright holder
28   * shall not be used in advertising or otherwise to promote the sale, use
29   * or other dealings in this Software without prior written authorization
30   * of the copyright holder.
31   *
32   */
33  
34  package org.slf4j.impl;
35  
36  import org.apache.log4j.Level;
37  import org.slf4j.Logger;
38  import org.slf4j.Marker;
39  import org.slf4j.helpers.MarkerIgnoringBase;
40  import org.slf4j.helpers.MessageFormatter;
41  import org.slf4j.spi.LocationAwareLogger;
42  
43  /**
44   * A wrapper over {@link org.apache.log4j.Logger org.apache.log4j.Logger} in
45   * conforming to the {@link Logger} interface. 
46   * 
47   * <p>Note that the logging levels mentioned in this class refer to those defined in the <a
48   * href="http://logging.apache.org/log4j/docs/api/org/apache/log4j/Level.html"><code>org.apache.log4j.Level</code></a>
49   * class.
50   * 
51   * <p>
52   * The TRACE level was introduced in log4j version 1.2.12. In order to avoid
53   * crashing the host application, in the case the log4j version in use predates
54   * 1.2.12, the TRACE level will be mapped as DEBUG. See also <a
55   * href="http://bugzilla.slf4j.org/show_bug.cgi?id=68">bug 68</a>.
56   * 
57   * @author Ceki G&uuml;lc&uuml;
58   */
59  public final class Log4jLoggerAdapter extends MarkerIgnoringBase implements
60      LocationAwareLogger {
61    final org.apache.log4j.Logger logger;
62  
63    /**
64     * Following the pattern discussed in pages 162 through 168 of "The complete
65     * log4j manual".
66     */
67    final static String FQCN = Log4jLoggerAdapter.class.getName();
68  
69    // Does the log4j version in use recognize the TRACE level?
70    // The trace level was introduced in log4j 1.2.12.
71    final boolean traceCapable;
72  
73    // WARN: Log4jLoggerAdapter constructor should have only package access so
74    // that
75    // only Log4jLoggerFactory be able to create one.
76    Log4jLoggerAdapter(org.apache.log4j.Logger logger) {
77      this.logger = logger;
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    public String getName() {
91      return logger.getName();
92    }
93  
94    /**
95     * Is this logger instance enabled for the TRACE level?
96     * 
97     * @return True if this Logger is enabled for level TRACE, false otherwise.
98     */
99    public boolean isTraceEnabled() {
100     if (traceCapable) {
101       return logger.isTraceEnabled();
102     } else {
103       return logger.isDebugEnabled();
104     }
105   }
106 
107   /**
108    * Log a message object at level TRACE.
109    * 
110    * @param msg -
111    *                the message object to be logged
112    */
113   public void trace(String msg) {
114     logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, msg, null);
115   }
116 
117   /**
118    * Log a message at level TRACE according to the specified format and
119    * argument.
120    * 
121    * <p>
122    * This form avoids superfluous object creation when the logger is disabled
123    * for level TRACE.
124    * </p>
125    * 
126    * @param format
127    *                the format string
128    * @param arg
129    *                the argument
130    */
131   public void trace(String format, Object arg) {
132     if (logger.isTraceEnabled()) {
133       String msgStr = MessageFormatter.format(format, arg);
134       logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, msgStr, null);
135     }
136   }
137 
138   /**
139    * Log a message at level TRACE according to the specified format and
140    * arguments.
141    * 
142    * <p>
143    * This form avoids superfluous object creation when the logger is disabled
144    * for the TRACE level.
145    * </p>
146    * 
147    * @param format
148    *                the format string
149    * @param arg1
150    *                the first argument
151    * @param arg2
152    *                the second argument
153    */
154   public void trace(String format, Object arg1, Object arg2) {
155     if (logger.isTraceEnabled()) {
156       String msgStr = MessageFormatter.format(format, arg1, arg2);
157       logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, msgStr, null);
158     }
159   }
160 
161   /**
162    * Log a message at level TRACE according to the specified format and
163    * arguments.
164    * 
165    * <p>
166    * This form avoids superfluous object creation when the logger is disabled
167    * for the TRACE level.
168    * </p>
169    * 
170    * @param format
171    *                the format string
172    * @param argArray
173    *                an array of arguments
174    */
175   public void trace(String format, Object[] argArray) {
176     if (logger.isTraceEnabled()) {
177       String msgStr = MessageFormatter.arrayFormat(format, argArray);
178       logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, msgStr, null);
179     }
180   }
181 
182   /**
183    * Log an exception (throwable) at level TRACE with an accompanying message.
184    * 
185    * @param msg
186    *                the message accompanying the exception
187    * @param t
188    *                the exception (throwable) to log
189    */
190   public void trace(String msg, Throwable t) {
191     logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, msg, t);
192   }
193 
194   /**
195    * Is this logger instance enabled for the DEBUG level?
196    * 
197    * @return True if this Logger is enabled for level DEBUG, false otherwise.
198    */
199   public boolean isDebugEnabled() {
200     return logger.isDebugEnabled();
201   }
202 
203   /**
204    * Log a message object at level DEBUG.
205    * 
206    * @param msg -
207    *                the message object to be logged
208    */
209   public void debug(String msg) {
210     logger.log(FQCN, Level.DEBUG, msg, null);
211   }
212 
213   /**
214    * Log a message at level DEBUG according to the specified format and
215    * argument.
216    * 
217    * <p>
218    * This form avoids superfluous object creation when the logger is disabled
219    * for level DEBUG.
220    * </p>
221    * 
222    * @param format
223    *                the format string
224    * @param arg
225    *                the argument
226    */
227   public void debug(String format, Object arg) {
228     if (logger.isDebugEnabled()) {
229       String msgStr = MessageFormatter.format(format, arg);
230       logger.log(FQCN, Level.DEBUG, msgStr, null);
231     }
232   }
233 
234   /**
235    * Log a message at level DEBUG according to the specified format and
236    * arguments.
237    * 
238    * <p>
239    * This form avoids superfluous object creation when the logger is disabled
240    * for the DEBUG level.
241    * </p>
242    * 
243    * @param format
244    *                the format string
245    * @param arg1
246    *                the first argument
247    * @param arg2
248    *                the second argument
249    */
250   public void debug(String format, Object arg1, Object arg2) {
251     if (logger.isDebugEnabled()) {
252       String msgStr = MessageFormatter.format(format, arg1, arg2);
253       logger.log(FQCN, Level.DEBUG, msgStr, null);
254     }
255   }
256 
257   /**
258    * Log a message at level DEBUG according to the specified format and
259    * arguments.
260    * 
261    * <p>
262    * This form avoids superfluous object creation when the logger is disabled
263    * for the DEBUG level.
264    * </p>
265    * 
266    * @param format
267    *                the format string
268    * @param argArray
269    *                an array of arguments
270    */
271   public void debug(String format, Object[] argArray) {
272     if (logger.isDebugEnabled()) {
273       String msgStr = MessageFormatter.arrayFormat(format, argArray);
274       logger.log(FQCN, Level.DEBUG, msgStr, null);
275     }
276   }
277 
278   /**
279    * Log an exception (throwable) at level DEBUG with an accompanying message.
280    * 
281    * @param msg
282    *                the message accompanying the exception
283    * @param t
284    *                the exception (throwable) to log
285    */
286   public void debug(String msg, Throwable t) {
287     logger.log(FQCN, Level.DEBUG, msg, t);
288   }
289 
290   /**
291    * Is this logger instance enabled for the INFO level?
292    * 
293    * @return True if this Logger is enabled for the INFO level, false otherwise.
294    */
295   public boolean isInfoEnabled() {
296     return logger.isInfoEnabled();
297   }
298 
299   /**
300    * Log a message object at the INFO level.
301    * 
302    * @param msg -
303    *                the message object to be logged
304    */
305   public void info(String msg) {
306     logger.log(FQCN, Level.INFO, msg, null);
307   }
308 
309   /**
310    * Log a message at level INFO according to the specified format and argument.
311    * 
312    * <p>
313    * This form avoids superfluous object creation when the logger is disabled
314    * for the INFO level.
315    * </p>
316    * 
317    * @param format
318    *                the format string
319    * @param arg
320    *                the argument
321    */
322   public void info(String format, Object arg) {
323     if (logger.isInfoEnabled()) {
324       String msgStr = MessageFormatter.format(format, arg);
325       logger.log(FQCN, Level.INFO, msgStr, null);
326     }
327   }
328 
329   /**
330    * Log a message at the INFO level according to the specified format and
331    * arguments.
332    * 
333    * <p>
334    * This form avoids superfluous object creation when the logger is disabled
335    * for the INFO level.
336    * </p>
337    * 
338    * @param format
339    *                the format string
340    * @param arg1
341    *                the first argument
342    * @param arg2
343    *                the second argument
344    */
345   public void info(String format, Object arg1, Object arg2) {
346     if (logger.isInfoEnabled()) {
347       String msgStr = MessageFormatter.format(format, arg1, arg2);
348       logger.log(FQCN, Level.INFO, msgStr, null);
349     }
350   }
351 
352   /**
353    * Log a message at level INFO according to the specified format and
354    * arguments.
355    * 
356    * <p>
357    * This form avoids superfluous object creation when the logger is disabled
358    * for the INFO level.
359    * </p>
360    * 
361    * @param format
362    *                the format string
363    * @param argArray
364    *                an array of arguments
365    */
366   public void info(String format, Object[] argArray) {
367     if (logger.isInfoEnabled()) {
368       String msgStr = MessageFormatter.arrayFormat(format, argArray);
369       logger.log(FQCN, Level.INFO, msgStr, null);
370     }
371   }
372 
373   /**
374    * Log an exception (throwable) at the INFO level with an accompanying
375    * message.
376    * 
377    * @param msg
378    *                the message accompanying the exception
379    * @param t
380    *                the exception (throwable) to log
381    */
382   public void info(String msg, Throwable t) {
383     logger.log(FQCN, Level.INFO, msg, t);
384   }
385 
386   /**
387    * Is this logger instance enabled for the WARN level?
388    * 
389    * @return True if this Logger is enabled for the WARN level, false otherwise.
390    */
391   public boolean isWarnEnabled() {
392     return logger.isEnabledFor(Level.WARN);
393   }
394 
395   /**
396    * Log a message object at the WARN level.
397    * 
398    * @param msg -
399    *                the message object to be logged
400    */
401   public void warn(String msg) {
402     logger.log(FQCN, Level.WARN, msg, null);
403   }
404 
405   /**
406    * Log a message at the WARN level according to the specified format and
407    * argument.
408    * 
409    * <p>
410    * This form avoids superfluous object creation when the logger is disabled
411    * for the WARN level.
412    * </p>
413    * 
414    * @param format
415    *                the format string
416    * @param arg
417    *                the argument
418    */
419   public void warn(String format, Object arg) {
420     if (logger.isEnabledFor(Level.WARN)) {
421       String msgStr = MessageFormatter.format(format, arg);
422       logger.log(FQCN, Level.WARN, msgStr, null);
423     }
424   }
425 
426   /**
427    * Log a message at the WARN level according to the specified format and
428    * arguments.
429    * 
430    * <p>
431    * This form avoids superfluous object creation when the logger is disabled
432    * for the WARN level.
433    * </p>
434    * 
435    * @param format
436    *                the format string
437    * @param arg1
438    *                the first argument
439    * @param arg2
440    *                the second argument
441    */
442   public void warn(String format, Object arg1, Object arg2) {
443     if (logger.isEnabledFor(Level.WARN)) {
444       String msgStr = MessageFormatter.format(format, arg1, arg2);
445       logger.log(FQCN, Level.WARN, msgStr, null);
446     }
447   }
448 
449   /**
450    * Log a message at level WARN according to the specified format and
451    * arguments.
452    * 
453    * <p>
454    * This form avoids superfluous object creation when the logger is disabled
455    * for the WARN level.
456    * </p>
457    * 
458    * @param format
459    *                the format string
460    * @param argArray
461    *                an array of arguments
462    */
463   public void warn(String format, Object[] argArray) {
464     if (logger.isEnabledFor(Level.WARN)) {
465       String msgStr = MessageFormatter.arrayFormat(format, argArray);
466       logger.log(FQCN, Level.WARN, msgStr, null);
467     }
468   }
469 
470   /**
471    * Log an exception (throwable) at the WARN level with an accompanying
472    * message.
473    * 
474    * @param msg
475    *                the message accompanying the exception
476    * @param t
477    *                the exception (throwable) to log
478    */
479   public void warn(String msg, Throwable t) {
480     logger.log(FQCN, Level.WARN, msg, t);
481   }
482 
483   /**
484    * Is this logger instance enabled for level ERROR?
485    * 
486    * @return True if this Logger is enabled for level ERROR, false otherwise.
487    */
488   public boolean isErrorEnabled() {
489     return logger.isEnabledFor(Level.ERROR);
490   }
491 
492   /**
493    * Log a message object at the ERROR level.
494    * 
495    * @param msg -
496    *                the message object to be logged
497    */
498   public void error(String msg) {
499     logger.log(FQCN, Level.ERROR, msg, null);
500   }
501 
502   /**
503    * Log a message at the ERROR level according to the specified format and
504    * argument.
505    * 
506    * <p>
507    * This form avoids superfluous object creation when the logger is disabled
508    * for the ERROR level.
509    * </p>
510    * 
511    * @param format
512    *                the format string
513    * @param arg
514    *                the argument
515    */
516   public void error(String format, Object arg) {
517     if (logger.isEnabledFor(Level.ERROR)) {
518       String msgStr = MessageFormatter.format(format, arg);
519       logger.log(FQCN, Level.ERROR, msgStr, null);
520     }
521   }
522 
523   /**
524    * Log a message at the ERROR level according to the specified format and
525    * arguments.
526    * 
527    * <p>
528    * This form avoids superfluous object creation when the logger is disabled
529    * for the ERROR level.
530    * </p>
531    * 
532    * @param format
533    *                the format string
534    * @param arg1
535    *                the first argument
536    * @param arg2
537    *                the second argument
538    */
539   public void error(String format, Object arg1, Object arg2) {
540     if (logger.isEnabledFor(Level.ERROR)) {
541       String msgStr = MessageFormatter.format(format, arg1, arg2);
542       logger.log(FQCN, Level.ERROR, msgStr, null);
543     }
544   }
545 
546   /**
547    * Log a message at level ERROR according to the specified format and
548    * arguments.
549    * 
550    * <p>
551    * This form avoids superfluous object creation when the logger is disabled
552    * for the ERROR level.
553    * </p>
554    * 
555    * @param format
556    *                the format string
557    * @param argArray
558    *                an array of arguments
559    */
560   public void error(String format, Object[] argArray) {
561     if (logger.isEnabledFor(Level.ERROR)) {
562       String msgStr = MessageFormatter.arrayFormat(format, argArray);
563       logger.log(FQCN, Level.ERROR, msgStr, null);
564     }
565   }
566 
567   /**
568    * Log an exception (throwable) at the ERROR level with an accompanying
569    * message.
570    * 
571    * @param msg
572    *                the message accompanying the exception
573    * @param t
574    *                the exception (throwable) to log
575    */
576   public void error(String msg, Throwable t) {
577     logger.log(FQCN, Level.ERROR, msg, t);
578   }
579 
580   public void log(Marker marker, String callerFQCN, int level, String msg,
581       Throwable t) {
582     Level log4jLevel;
583     switch (level) {
584     case LocationAwareLogger.TRACE_INT:
585       log4jLevel = traceCapable ? Level.TRACE : Level.DEBUG;
586       break;
587     case LocationAwareLogger.DEBUG_INT:
588       log4jLevel = Level.DEBUG;
589       break;
590     case LocationAwareLogger.INFO_INT:
591       log4jLevel = Level.INFO;
592       break;
593     case LocationAwareLogger.WARN_INT:
594       log4jLevel = Level.WARN;
595       break;
596     case LocationAwareLogger.ERROR_INT:
597       log4jLevel = Level.ERROR;
598       break;
599     default:
600       throw new IllegalStateException("Level number " + level
601           + " is not recognized.");
602     }
603     logger.log(callerFQCN, log4jLevel, msg, t);
604   }
605 }