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