View Javadoc

    1   /*
    2    * Copyright (c) 2004-2013 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 android.util.Log;
    28  import org.slf4j.helpers.FormattingTuple;
    29  import org.slf4j.helpers.MarkerIgnoringBase;
    30  import org.slf4j.helpers.MessageFormatter;
    31
    32  /**
    33   * <p>A simple implementation that delegates all log requests to the Google Android
    34   * logging facilities. Note that this logger does not support {@link org.slf4j.Marker}.
    35   * Methods taking marker data as parameter simply invoke the eponymous method
    36   * without the Marker argument, discarding any marker data in the process.</p>
    37   *
    38   * <p>The logging levels specified for SLF4J can be almost directly mapped to
    39   * the levels that exist in the Google Android platform. The following table
    40   * shows the mapping implemented by this logger.</p>
    41   *
    42   * <table border="1">
    43   * <tr><th><b>SLF4J<b></th><th><b>Android</b></th></tr>
    44   * <tr><td>TRACE</td><td>{@link android.util.Log#VERBOSE}</td></tr>
    45   * <tr><td>DEBUG</td><td>{@link android.util.Log#DEBUG}</td></tr>
    46   * <tr><td>INFO</td><td>{@link android.util.Log#INFO}</td></tr>
    47   * <tr><td>WARN</td><td>{@link android.util.Log#WARN}</td></tr>
    48   * <tr><td>ERROR</td><td>{@link android.util.Log#ERROR}</td></tr>
    49   * </table>
    50   *
    51   * <p>Use loggers as usual:
    52   * <ul>
    53   *     <li>
    54   *         Declare a logger<br/>
    55   *         <code>private static final Logger logger = LoggerFactory.getLogger(MyClass.class);</code>
    56   *     </li>
    57   *     <li>
    58   *         Invoke logging methods, e.g.,<br/>
    59   *         <code>logger.debug("Some log message. Details: {}", someObject);</code><br/>
    60   *         <code>logger.debug("Some log message with varargs. Details: {}, {}, {}", someObject1, someObject2, someObject3);</code>
    61   *     </li>
    62   * </ul>
    63   * </p>
    64   *
    65   * <p>Logger instances created using the LoggerFactory are named either according to the name
    66   * or the fully qualified class name of the class given as a parameter.
    67   * Each logger name will be used as the log message tag on the Android platform.
    68   * However, tag names cannot be longer than 23 characters so if logger name exceeds this limit then
    69   * it will be truncated by the LoggerFactory. The following examples illustrate this.
    70   * <table border="1">
    71   * <tr><th><b>Original Name<b></th><th><b>Truncated Name</b></th></tr>
    72   * <tr><td>org.example.myproject.mypackage.MyClass</td><td>o*.e*.m*.m*.MyClass</td></tr>
    73   * <tr><td>o.e.myproject.mypackage.MyClass</td><td>o.e.m*.m*.MyClass</td></tr>
    74   * <tr><td>org.example.ThisNameIsWayTooLongAndWillBeTruncated</td><td>*LongAndWillBeTruncated</td></tr>
    75   * <tr><td>ThisNameIsWayTooLongAndWillBeTruncated</td><td>*LongAndWillBeTruncated</td></tr>
    76   * </table>
    77   * </p>
    78   *
    79   * @author Andrey Korzhevskiy <a.korzhevskiy@gmail.com>
    80   */
    81  class AndroidLoggerAdapter extends MarkerIgnoringBase {
    82      private static final long serialVersionUID = -1227274521521287937L;
    83
    84      /**
    85       * Package access allows only {@link AndroidLoggerFactory} to instantiate
    86       * SimpleLogger instances.
    87       */
    88      AndroidLoggerAdapter(String tag) {
    89          this.name = tag;
    90      }
    91
    92      /**
    93       * Is this logger instance enabled for the VERBOSE level?
    94       *
    95       * @return True if this Logger is enabled for level VERBOSE, false otherwise.
    96       */
    97      public boolean isTraceEnabled() {
    98          return isLoggable(Log.VERBOSE);
    99      }
    100
    101     /**
    102      * Log a message object at level VERBOSE.
    103      *
    104      * @param msg
    105      *          - the message object to be logged
    106      */
    107     public void trace(String msg) {
    108         log(Log.VERBOSE, msg, null);
    109     }
    110
    111     /**
    112      * Log a message at level VERBOSE according to the specified format and
    113      * argument.
    114      *
    115      * <p>
    116      * This form avoids superfluous object creation when the logger is disabled
    117      * for level VERBOSE.
    118      * </p>
    119      *
    120      * @param format
    121      *          the format string
    122      * @param arg
    123      *          the argument
    124      */
    125     public void trace(String format, Object arg) {
    126         formatAndLog(Log.VERBOSE, format, arg);
    127     }
    128
    129     /**
    130      * Log a message at level VERBOSE according to the specified format and
    131      * arguments.
    132      *
    133      * <p>
    134      * This form avoids superfluous object creation when the logger is disabled
    135      * for the VERBOSE level.
    136      * </p>
    137      *
    138      * @param format
    139      *          the format string
    140      * @param arg1
    141      *          the first argument
    142      * @param arg2
    143      *          the second argument
    144      */
    145     public void trace(String format, Object arg1, Object arg2) {
    146         formatAndLog(Log.VERBOSE, format, arg1, arg2);
    147     }
    148
    149     /**
    150      * Log a message at level VERBOSE according to the specified format and
    151      * arguments.
    152      *
    153      * <p>
    154      * This form avoids superfluous object creation when the logger is disabled
    155      * for the VERBOSE level.
    156      * </p>
    157      *
    158      * @param format
    159      *          the format string
    160      * @param argArray
    161      *          an array of arguments
    162      */
    163     public void trace(String format, Object... argArray) {
    164         formatAndLog(Log.VERBOSE, format, argArray);
    165     }
    166
    167     /**
    168      * Log an exception (throwable) at level VERBOSE with an accompanying message.
    169      *
    170      * @param msg
    171      *          the message accompanying the exception
    172      * @param t
    173      *          the exception (throwable) to log
    174      */
    175     public void trace(String msg, Throwable t) {
    176         log(Log.VERBOSE, msg, t);
    177     }
    178
    179     /**
    180      * Is this logger instance enabled for the DEBUG level?
    181      *
    182      * @return True if this Logger is enabled for level DEBUG, false otherwise.
    183      */
    184     public boolean isDebugEnabled() {
    185         return isLoggable(Log.DEBUG);
    186     }
    187
    188     /**
    189      * Log a message object at level DEBUG.
    190      *
    191      * @param msg
    192      *          - the message object to be logged
    193      */
    194     public void debug(String msg) {
    195         log(Log.DEBUG, msg, null);
    196     }
    197
    198     /**
    199      * Log a message at level DEBUG according to the specified format and argument.
    200      *
    201      * <p>
    202      * This form avoids superfluous object creation when the logger is disabled
    203      * for level DEBUG.
    204      * </p>
    205      *
    206      * @param format
    207      *          the format string
    208      * @param arg
    209      *          the argument
    210      */
    211     public void debug(String format, Object arg) {
    212         formatAndLog(Log.DEBUG, format, arg);
    213     }
    214
    215     /**
    216      * Log a message at level DEBUG according to the specified format and
    217      * arguments.
    218      *
    219      * <p>
    220      * This form avoids superfluous object creation when the logger is disabled
    221      * for the DEBUG level.
    222      * </p>
    223      *
    224      * @param format
    225      *          the format string
    226      * @param arg1
    227      *          the first argument
    228      * @param arg2
    229      *          the second argument
    230      */
    231     public void debug(String format, Object arg1, Object arg2) {
    232         formatAndLog(Log.DEBUG, format, arg1, arg2);
    233     }
    234
    235     /**
    236      * Log a message at level DEBUG according to the specified format and
    237      * arguments.
    238      *
    239      * <p>
    240      * This form avoids superfluous object creation when the logger is disabled
    241      * for the DEBUG level.
    242      * </p>
    243      *
    244      * @param format
    245      *          the format string
    246      * @param argArray
    247      *          an array of arguments
    248      */
    249     public void debug(String format, Object... argArray) {
    250         formatAndLog(Log.DEBUG, format, argArray);
    251     }
    252
    253     /**
    254      * Log an exception (throwable) at level DEBUG with an accompanying message.
    255      *
    256      * @param msg
    257      *          the message accompanying the exception
    258      * @param t
    259      *          the exception (throwable) to log
    260      */
    261     public void debug(String msg, Throwable t) {
    262         log(Log.VERBOSE, msg, t);
    263     }
    264
    265     /**
    266      * Is this logger instance enabled for the INFO level?
    267      *
    268      * @return True if this Logger is enabled for the INFO level, false otherwise.
    269      */
    270     public boolean isInfoEnabled() {
    271         return isLoggable(Log.INFO);
    272     }
    273
    274     /**
    275      * Log a message object at the INFO level.
    276      *
    277      * @param msg
    278      *          - the message object to be logged
    279      */
    280     public void info(String msg) {
    281         log(Log.INFO, msg, null);
    282     }
    283
    284     /**
    285      * Log a message at level INFO according to the specified format and argument.
    286      *
    287      * <p>
    288      * This form avoids superfluous object creation when the logger is disabled
    289      * for the INFO level.
    290      * </p>
    291      *
    292      * @param format
    293      *          the format string
    294      * @param arg
    295      *          the argument
    296      */
    297     public void info(String format, Object arg) {
    298         formatAndLog(Log.INFO, format, arg);
    299     }
    300
    301     /**
    302      * Log a message at the INFO level according to the specified format and
    303      * arguments.
    304      *
    305      * <p>
    306      * This form avoids superfluous object creation when the logger is disabled
    307      * for the INFO level.
    308      * </p>
    309      *
    310      * @param format
    311      *          the format string
    312      * @param arg1
    313      *          the first argument
    314      * @param arg2
    315      *          the second argument
    316      */
    317     public void info(String format, Object arg1, Object arg2) {
    318         formatAndLog(Log.INFO, format, arg1, arg2);
    319     }
    320
    321     /**
    322      * Log a message at level INFO according to the specified format and
    323      * arguments.
    324      *
    325      * <p>
    326      * This form avoids superfluous object creation when the logger is disabled
    327      * for the INFO level.
    328      * </p>
    329      *
    330      * @param format
    331      *          the format string
    332      * @param argArray
    333      *          an array of arguments
    334      */
    335     public void info(String format, Object... argArray) {
    336         formatAndLog(Log.INFO, format, argArray);
    337     }
    338
    339     /**
    340      * Log an exception (throwable) at the INFO level with an accompanying
    341      * message.
    342      *
    343      * @param msg
    344      *          the message accompanying the exception
    345      * @param t
    346      *          the exception (throwable) to log
    347      */
    348     public void info(String msg, Throwable t) {
    349         log(Log.INFO, msg, t);
    350     }
    351
    352     /**
    353      * Is this logger instance enabled for the WARN level?
    354      *
    355      * @return True if this Logger is enabled for the WARN level, false
    356      *         otherwise.
    357      */
    358     public boolean isWarnEnabled() {
    359         return isLoggable(Log.WARN);
    360     }
    361
    362     /**
    363      * Log a message object at the WARN level.
    364      *
    365      * @param msg
    366      *          - the message object to be logged
    367      */
    368     public void warn(String msg) {
    369         log(Log.WARN, msg, null);
    370     }
    371
    372     /**
    373      * Log a message at the WARN level according to the specified format and
    374      * argument.
    375      *
    376      * <p>
    377      * This form avoids superfluous object creation when the logger is disabled
    378      * for the WARN level.
    379      * </p>
    380      *
    381      * @param format
    382      *          the format string
    383      * @param arg
    384      *          the argument
    385      */
    386     public void warn(String format, Object arg) {
    387         formatAndLog(Log.WARN, format, arg);
    388     }
    389
    390     /**
    391      * Log a message at the WARN level according to the specified format and
    392      * arguments.
    393      *
    394      * <p>
    395      * This form avoids superfluous object creation when the logger is disabled
    396      * for the WARN level.
    397      * </p>
    398      *
    399      * @param format
    400      *          the format string
    401      * @param arg1
    402      *          the first argument
    403      * @param arg2
    404      *          the second argument
    405      */
    406     public void warn(String format, Object arg1, Object arg2) {
    407         formatAndLog(Log.WARN, format, arg1, arg2);
    408     }
    409
    410     /**
    411      * Log a message at level WARN according to the specified format and
    412      * arguments.
    413      *
    414      * <p>
    415      * This form avoids superfluous object creation when the logger is disabled
    416      * for the WARN level.
    417      * </p>
    418      *
    419      * @param format
    420      *          the format string
    421      * @param argArray
    422      *          an array of arguments
    423      */
    424     public void warn(String format, Object... argArray) {
    425         formatAndLog(Log.WARN, format, argArray);
    426     }
    427
    428     /**
    429      * Log an exception (throwable) at the WARN level with an accompanying
    430      * message.
    431      *
    432      * @param msg
    433      *          the message accompanying the exception
    434      * @param t
    435      *          the exception (throwable) to log
    436      */
    437     public void warn(String msg, Throwable t) {
    438         log(Log.WARN, msg, t);
    439     }
    440
    441     /**
    442      * Is this logger instance enabled for level ERROR?
    443      *
    444      * @return True if this Logger is enabled for level ERROR, false otherwise.
    445      */
    446     public boolean isErrorEnabled() {
    447         return isLoggable(Log.ERROR);
    448     }
    449
    450     /**
    451      * Log a message object at the ERROR level.
    452      *
    453      * @param msg
    454      *          - the message object to be logged
    455      */
    456     public void error(String msg) {
    457         log(Log.ERROR, msg, null);
    458     }
    459
    460     /**
    461      * Log a message at the ERROR level according to the specified format and
    462      * argument.
    463      *
    464      * <p>
    465      * This form avoids superfluous object creation when the logger is disabled
    466      * for the ERROR level.
    467      * </p>
    468      *
    469      * @param format
    470      *          the format string
    471      * @param arg
    472      *          the argument
    473      */
    474     public void error(String format, Object arg) {
    475         formatAndLog(Log.ERROR, format, arg);
    476     }
    477
    478     /**
    479      * Log a message at the ERROR level according to the specified format and
    480      * arguments.
    481      *
    482      * <p>
    483      * This form avoids superfluous object creation when the logger is disabled
    484      * for the ERROR level.
    485      * </p>
    486      *
    487      * @param format
    488      *          the format string
    489      * @param arg1
    490      *          the first argument
    491      * @param arg2
    492      *          the second argument
    493      */
    494     public void error(String format, Object arg1, Object arg2) {
    495         formatAndLog(Log.ERROR, format, arg1, arg2);
    496     }
    497
    498     /**
    499      * Log a message at level ERROR according to the specified format and
    500      * arguments.
    501      *
    502      * <p>
    503      * This form avoids superfluous object creation when the logger is disabled
    504      * for the ERROR level.
    505      * </p>
    506      *
    507      * @param format
    508      *          the format string
    509      * @param argArray
    510      *          an array of arguments
    511      */
    512     public void error(String format, Object... argArray) {
    513         formatAndLog(Log.ERROR, format, argArray);
    514     }
    515
    516     /**
    517      * Log an exception (throwable) at the ERROR level with an accompanying
    518      * message.
    519      *
    520      * @param msg
    521      *          the message accompanying the exception
    522      * @param t
    523      *          the exception (throwable) to log
    524      */
    525     public void error(String msg, Throwable t) {
    526         log(Log.ERROR, msg, t);
    527     }
    528
    529     private void formatAndLog(int priority, String format, Object... argArray) {
    530         if (isLoggable(priority)) {
    531             FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
    532             logInternal(priority, ft.getMessage(), ft.getThrowable());
    533         }
    534     }
    535
    536     private void log(int priority, String message, Throwable throwable) {
    537         if (isLoggable(priority)) {
    538             logInternal(priority, message, throwable);
    539         }
    540     }
    541
    542     private boolean isLoggable(int priority) {
    543         return Log.isLoggable(name, priority);
    544     }
    545
    546     private void logInternal(int priority, String message, Throwable throwable) {
    547         if (throwable != null) {
    548             message += '\n' + Log.getStackTraceString(throwable);
    549         }
    550         Log.println(priority, name, message);
    551     }
    552 }