1 /*
2 * Copyright (c) 2004-2008 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
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 }