JDK14LoggerAdapter xref

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.util.logging.Level;
    28  import java.util.logging.LogRecord;
    29
    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 java.util.logging.Logger java.util.logging.Logger} in
    39   * conformity with the {@link Logger} interface. Note that the logging levels
    40   * mentioned in this class refer to those defined in the java.util.logging
    41   * package.
    42   *
    43   * @author Ceki G&uuml;lc&uuml;
    44   * @author Peter Royal
    45   */
    46  public final class JDK14LoggerAdapter extends MarkerIgnoringBase implements
    47      LocationAwareLogger {
    48
    49    private static final long serialVersionUID = -8053026990503422791L;
    50
    51    transient final java.util.logging.Logger logger;
    52
    53    // WARN: JDK14LoggerAdapter constructor should have only package access so
    54    // that only JDK14LoggerFactory be able to create one.
    55    JDK14LoggerAdapter(java.util.logging.Logger logger) {
    56      this.logger = logger;
    57      this.name = logger.getName();
    58    }
    59
    60    /**
    61     * Is this logger instance enabled for the FINEST level?
    62     *
    63     * @return True if this Logger is enabled for level FINEST, false otherwise.
    64     */
    65    public boolean isTraceEnabled() {
    66      return logger.isLoggable(Level.FINEST);
    67    }
    68
    69    /**
    70     * Log a message object at level FINEST.
    71     *
    72     * @param msg
    73     *          - the message object to be logged
    74     */
    75    public void trace(String msg) {
    76      if (logger.isLoggable(Level.FINEST)) {
    77        log(SELF, Level.FINEST, msg, null);
    78      }
    79    }
    80
    81    /**
    82     * Log a message at level FINEST according to the specified format and
    83     * argument.
    84     *
    85     * <p>
    86     * This form avoids superfluous object creation when the logger is disabled
    87     * for level FINEST.
    88     * </p>
    89     *
    90     * @param format
    91     *          the format string
    92     * @param arg
    93     *          the argument
    94     */
    95    public void trace(String format, Object arg) {
    96      if (logger.isLoggable(Level.FINEST)) {
    97        FormattingTuple ft = MessageFormatter.format(format, arg);
    98        log(SELF, Level.FINEST, ft.getMessage(), ft.getThrowable());
    99      }
    100   }
    101
    102   /**
    103    * Log a message at level FINEST according to the specified format and
    104    * arguments.
    105    *
    106    * <p>
    107    * This form avoids superfluous object creation when the logger is disabled
    108    * for the FINEST level.
    109    * </p>
    110    *
    111    * @param format
    112    *          the format string
    113    * @param arg1
    114    *          the first argument
    115    * @param arg2
    116    *          the second argument
    117    */
    118   public void trace(String format, Object arg1, Object arg2) {
    119     if (logger.isLoggable(Level.FINEST)) {
    120       FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
    121       log(SELF, Level.FINEST, ft.getMessage(), ft.getThrowable());
    122     }
    123   }
    124
    125   /**
    126    * Log a message at level FINEST according to the specified format and
    127    * arguments.
    128    *
    129    * <p>
    130    * This form avoids superfluous object creation when the logger is disabled
    131    * for the FINEST level.
    132    * </p>
    133    *
    134    * @param format
    135    *          the format string
    136    * @param argArray
    137    *          an array of arguments
    138    */
    139   public void trace(String format, Object... argArray) {
    140     if (logger.isLoggable(Level.FINEST)) {
    141       FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
    142       log(SELF, Level.FINEST, ft.getMessage(), ft.getThrowable());
    143     }
    144   }
    145
    146   /**
    147    * Log an exception (throwable) at level FINEST with an accompanying message.
    148    *
    149    * @param msg
    150    *          the message accompanying the exception
    151    * @param t
    152    *          the exception (throwable) to log
    153    */
    154   public void trace(String msg, Throwable t) {
    155     if (logger.isLoggable(Level.FINEST)) {
    156       log(SELF, Level.FINEST, msg, t);
    157     }
    158   }
    159
    160   /**
    161    * Is this logger instance enabled for the FINE level?
    162    *
    163    * @return True if this Logger is enabled for level FINE, false otherwise.
    164    */
    165   public boolean isDebugEnabled() {
    166     return logger.isLoggable(Level.FINE);
    167   }
    168
    169   /**
    170    * Log a message object at level FINE.
    171    *
    172    * @param msg
    173    *          - the message object to be logged
    174    */
    175   public void debug(String msg) {
    176     if (logger.isLoggable(Level.FINE)) {
    177       log(SELF, Level.FINE, msg, null);
    178     }
    179   }
    180
    181   /**
    182    * Log a message at level FINE according to the specified format and argument.
    183    *
    184    * <p>
    185    * This form avoids superfluous object creation when the logger is disabled
    186    * for level FINE.
    187    * </p>
    188    *
    189    * @param format
    190    *          the format string
    191    * @param arg
    192    *          the argument
    193    */
    194   public void debug(String format, Object arg) {
    195     if (logger.isLoggable(Level.FINE)) {
    196       FormattingTuple ft = MessageFormatter.format(format, arg);
    197       log(SELF, Level.FINE, ft.getMessage(), ft.getThrowable());
    198     }
    199   }
    200
    201   /**
    202    * Log a message at level FINE according to the specified format and
    203    * arguments.
    204    *
    205    * <p>
    206    * This form avoids superfluous object creation when the logger is disabled
    207    * for the FINE level.
    208    * </p>
    209    *
    210    * @param format
    211    *          the format string
    212    * @param arg1
    213    *          the first argument
    214    * @param arg2
    215    *          the second argument
    216    */
    217   public void debug(String format, Object arg1, Object arg2) {
    218     if (logger.isLoggable(Level.FINE)) {
    219       FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
    220       log(SELF, Level.FINE, ft.getMessage(), ft.getThrowable());
    221     }
    222   }
    223
    224   /**
    225    * Log a message at level FINE according to the specified format and
    226    * arguments.
    227    *
    228    * <p>
    229    * This form avoids superfluous object creation when the logger is disabled
    230    * for the FINE level.
    231    * </p>
    232    *
    233    * @param format
    234    *          the format string
    235    * @param argArray
    236    *          an array of arguments
    237    */
    238   public void debug(String format, Object... argArray) {
    239     if (logger.isLoggable(Level.FINE)) {
    240       FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
    241       log(SELF, Level.FINE, ft.getMessage(), ft.getThrowable());
    242     }
    243   }
    244
    245   /**
    246    * Log an exception (throwable) at level FINE with an accompanying message.
    247    *
    248    * @param msg
    249    *          the message accompanying the exception
    250    * @param t
    251    *          the exception (throwable) to log
    252    */
    253   public void debug(String msg, Throwable t) {
    254     if (logger.isLoggable(Level.FINE)) {
    255       log(SELF, Level.FINE, msg, t);
    256     }
    257   }
    258
    259   /**
    260    * Is this logger instance enabled for the INFO level?
    261    *
    262    * @return True if this Logger is enabled for the INFO level, false otherwise.
    263    */
    264   public boolean isInfoEnabled() {
    265     return logger.isLoggable(Level.INFO);
    266   }
    267
    268   /**
    269    * Log a message object at the INFO level.
    270    *
    271    * @param msg
    272    *          - the message object to be logged
    273    */
    274   public void info(String msg) {
    275     if (logger.isLoggable(Level.INFO)) {
    276       log(SELF, Level.INFO, msg, null);
    277     }
    278   }
    279
    280   /**
    281    * Log a message at level INFO according to the specified format and argument.
    282    *
    283    * <p>
    284    * This form avoids superfluous object creation when the logger is disabled
    285    * for the INFO level.
    286    * </p>
    287    *
    288    * @param format
    289    *          the format string
    290    * @param arg
    291    *          the argument
    292    */
    293   public void info(String format, Object arg) {
    294     if (logger.isLoggable(Level.INFO)) {
    295       FormattingTuple ft = MessageFormatter.format(format, arg);
    296       log(SELF, Level.INFO, ft.getMessage(), ft.getThrowable());
    297     }
    298   }
    299
    300   /**
    301    * Log a message at the INFO level according to the specified format and
    302    * arguments.
    303    *
    304    * <p>
    305    * This form avoids superfluous object creation when the logger is disabled
    306    * for the INFO level.
    307    * </p>
    308    *
    309    * @param format
    310    *          the format string
    311    * @param arg1
    312    *          the first argument
    313    * @param arg2
    314    *          the second argument
    315    */
    316   public void info(String format, Object arg1, Object arg2) {
    317     if (logger.isLoggable(Level.INFO)) {
    318       FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
    319       log(SELF, Level.INFO, ft.getMessage(), ft.getThrowable());
    320     }
    321   }
    322
    323   /**
    324    * Log a message at level INFO 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 argArray
    335    *          an array of arguments
    336    */
    337   public void info(String format, Object... argArray) {
    338     if (logger.isLoggable(Level.INFO)) {
    339       FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
    340       log(SELF, Level.INFO, ft.getMessage(), ft.getThrowable());
    341     }
    342   }
    343
    344   /**
    345    * Log an exception (throwable) at the INFO level with an accompanying
    346    * message.
    347    *
    348    * @param msg
    349    *          the message accompanying the exception
    350    * @param t
    351    *          the exception (throwable) to log
    352    */
    353   public void info(String msg, Throwable t) {
    354     if (logger.isLoggable(Level.INFO)) {
    355       log(SELF, Level.INFO, msg, t);
    356     }
    357   }
    358
    359   /**
    360    * Is this logger instance enabled for the WARNING level?
    361    *
    362    * @return True if this Logger is enabled for the WARNING level, false
    363    *         otherwise.
    364    */
    365   public boolean isWarnEnabled() {
    366     return logger.isLoggable(Level.WARNING);
    367   }
    368
    369   /**
    370    * Log a message object at the WARNING level.
    371    *
    372    * @param msg
    373    *          - the message object to be logged
    374    */
    375   public void warn(String msg) {
    376     if (logger.isLoggable(Level.WARNING)) {
    377       log(SELF, Level.WARNING, msg, null);
    378     }
    379   }
    380
    381   /**
    382    * Log a message at the WARNING level according to the specified format and
    383    * argument.
    384    *
    385    * <p>
    386    * This form avoids superfluous object creation when the logger is disabled
    387    * for the WARNING level.
    388    * </p>
    389    *
    390    * @param format
    391    *          the format string
    392    * @param arg
    393    *          the argument
    394    */
    395   public void warn(String format, Object arg) {
    396     if (logger.isLoggable(Level.WARNING)) {
    397       FormattingTuple ft = MessageFormatter.format(format, arg);
    398       log(SELF, Level.WARNING, ft.getMessage(), ft.getThrowable());
    399     }
    400   }
    401
    402   /**
    403    * Log a message at the WARNING level according to the specified format and
    404    * arguments.
    405    *
    406    * <p>
    407    * This form avoids superfluous object creation when the logger is disabled
    408    * for the WARNING level.
    409    * </p>
    410    *
    411    * @param format
    412    *          the format string
    413    * @param arg1
    414    *          the first argument
    415    * @param arg2
    416    *          the second argument
    417    */
    418   public void warn(String format, Object arg1, Object arg2) {
    419     if (logger.isLoggable(Level.WARNING)) {
    420       FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
    421       log(SELF, Level.WARNING, ft.getMessage(), ft.getThrowable());
    422     }
    423   }
    424
    425   /**
    426    * Log a message at level WARNING 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 WARNING level.
    432    * </p>
    433    *
    434    * @param format
    435    *          the format string
    436    * @param argArray
    437    *          an array of arguments
    438    */
    439   public void warn(String format, Object... argArray) {
    440     if (logger.isLoggable(Level.WARNING)) {
    441       FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
    442       log(SELF, Level.WARNING, ft.getMessage(), ft.getThrowable());
    443     }
    444   }
    445
    446   /**
    447    * Log an exception (throwable) at the WARNING level with an accompanying
    448    * message.
    449    *
    450    * @param msg
    451    *          the message accompanying the exception
    452    * @param t
    453    *          the exception (throwable) to log
    454    */
    455   public void warn(String msg, Throwable t) {
    456     if (logger.isLoggable(Level.WARNING)) {
    457       log(SELF, Level.WARNING, msg, t);
    458     }
    459   }
    460
    461   /**
    462    * Is this logger instance enabled for level SEVERE?
    463    *
    464    * @return True if this Logger is enabled for level SEVERE, false otherwise.
    465    */
    466   public boolean isErrorEnabled() {
    467     return logger.isLoggable(Level.SEVERE);
    468   }
    469
    470   /**
    471    * Log a message object at the SEVERE level.
    472    *
    473    * @param msg
    474    *          - the message object to be logged
    475    */
    476   public void error(String msg) {
    477     if (logger.isLoggable(Level.SEVERE)) {
    478       log(SELF, Level.SEVERE, msg, null);
    479     }
    480   }
    481
    482   /**
    483    * Log a message at the SEVERE level according to the specified format and
    484    * argument.
    485    *
    486    * <p>
    487    * This form avoids superfluous object creation when the logger is disabled
    488    * for the SEVERE level.
    489    * </p>
    490    *
    491    * @param format
    492    *          the format string
    493    * @param arg
    494    *          the argument
    495    */
    496   public void error(String format, Object arg) {
    497     if (logger.isLoggable(Level.SEVERE)) {
    498       FormattingTuple ft = MessageFormatter.format(format, arg);
    499       log(SELF, Level.SEVERE, ft.getMessage(), ft.getThrowable());
    500     }
    501   }
    502
    503   /**
    504    * Log a message at the SEVERE level according to the specified format and
    505    * arguments.
    506    *
    507    * <p>
    508    * This form avoids superfluous object creation when the logger is disabled
    509    * for the SEVERE level.
    510    * </p>
    511    *
    512    * @param format
    513    *          the format string
    514    * @param arg1
    515    *          the first argument
    516    * @param arg2
    517    *          the second argument
    518    */
    519   public void error(String format, Object arg1, Object arg2) {
    520     if (logger.isLoggable(Level.SEVERE)) {
    521       FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
    522       log(SELF, Level.SEVERE, ft.getMessage(), ft.getThrowable());
    523     }
    524   }
    525
    526   /**
    527    * Log a message at level SEVERE according to the specified format and
    528    * arguments.
    529    *
    530    * <p>
    531    * This form avoids superfluous object creation when the logger is disabled
    532    * for the SEVERE level.
    533    * </p>
    534    *
    535    * @param format
    536    *          the format string
    537    * @param arguments
    538    *          an array of arguments
    539    */
    540   public void error(String format, Object... arguments) {
    541     if (logger.isLoggable(Level.SEVERE)) {
    542       FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
    543       log(SELF, Level.SEVERE, ft.getMessage(), ft.getThrowable());
    544     }
    545   }
    546
    547   /**
    548    * Log an exception (throwable) at the SEVERE level with an accompanying
    549    * message.
    550    *
    551    * @param msg
    552    *          the message accompanying the exception
    553    * @param t
    554    *          the exception (throwable) to log
    555    */
    556   public void error(String msg, Throwable t) {
    557     if (logger.isLoggable(Level.SEVERE)) {
    558       log(SELF, Level.SEVERE, msg, t);
    559     }
    560   }
    561
    562   /**
    563    * Log the message at the specified level with the specified throwable if any.
    564    * This method creates a LogRecord and fills in caller date before calling
    565    * this instance's JDK14 logger.
    566    *
    567    * See bug report #13 for more details.
    568    *
    569    * @param level
    570    * @param msg
    571    * @param t
    572    */
    573   private void log(String callerFQCN, Level level, String msg, Throwable t) {
    574     // millis and thread are filled by the constructor
    575     LogRecord record = new LogRecord(level, msg);
    576     record.setLoggerName(getName());
    577     record.setThrown(t);
    578     fillCallerData(callerFQCN, record);
    579     logger.log(record);
    580
    581   }
    582
    583   static String SELF = JDK14LoggerAdapter.class.getName();
    584   static String SUPER = MarkerIgnoringBase.class.getName();
    585
    586   /**
    587    * Fill in caller data if possible.
    588    *
    589    * @param record
    590    *          The record to update
    591    */
    592   final private void fillCallerData(String callerFQCN, LogRecord record) {
    593     StackTraceElement[] steArray = new Throwable().getStackTrace();
    594
    595     int selfIndex = -1;
    596     for (int i = 0; i < steArray.length; i++) {
    597       final String className = steArray[i].getClassName();
    598       if (className.equals(callerFQCN) || className.equals(SUPER)) {
    599         selfIndex = i;
    600         break;
    601       }
    602     }
    603
    604     int found = -1;
    605     for (int i = selfIndex + 1; i < steArray.length; i++) {
    606       final String className = steArray[i].getClassName();
    607       if (!(className.equals(callerFQCN) || className.equals(SUPER))) {
    608         found = i;
    609         break;
    610       }
    611     }
    612
    613     if (found != -1) {
    614       StackTraceElement ste = steArray[found];
    615       // setting the class name has the side effect of setting
    616       // the needToInferCaller variable to false.
    617       record.setSourceClassName(ste.getClassName());
    618       record.setSourceMethodName(ste.getMethodName());
    619     }
    620   }
    621
    622   public void log(Marker marker, String callerFQCN, int level, String message,
    623       Object[] argArray, Throwable t) {
    624     Level julLevel;
    625     switch (level) {
    626     case LocationAwareLogger.TRACE_INT:
    627       julLevel = Level.FINEST;
    628       break;
    629     case LocationAwareLogger.DEBUG_INT:
    630       julLevel = Level.FINE;
    631       break;
    632     case LocationAwareLogger.INFO_INT:
    633       julLevel = Level.INFO;
    634       break;
    635     case LocationAwareLogger.WARN_INT:
    636       julLevel = Level.WARNING;
    637       break;
    638     case LocationAwareLogger.ERROR_INT:
    639       julLevel = Level.SEVERE;
    640       break;
    641     default:
    642       throw new IllegalStateException("Level number " + level
    643           + " is not recognized.");
    644     }
    645     // the logger.isLoggable check avoids the unconditional
    646     // construction of location data for disabled log
    647     // statements. As of 2008-07-31, callers of this method
    648     // do not perform this check. See also
    649     // http://bugzilla.slf4j.org/show_bug.cgi?id=90
    650     if (logger.isLoggable(julLevel)) {
    651       log(callerFQCN, julLevel, message, t);
    652     }
    653   }
    654 }