Home | History | Annotate | Download | only in impl
      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 (at) gmail.com>
     80  */
     81 class AndroidLoggerAdapter extends MarkerIgnoringBase {
     82     private static final long serialVersionUID = -1227274521521287937L;
     83 
     84 
     85     /**
     86      * Package access allows only {@link AndroidLoggerFactory} to instantiate
     87      * SimpleLogger instances.
     88      */
     89     AndroidLoggerAdapter(String tag) {
     90         this.name = tag;
     91     }
     92 
     93     /**
     94      * Is this logger instance enabled for the VERBOSE level?
     95      *
     96      * @return True if this Logger is enabled for level VERBOSE, false otherwise.
     97      */
     98     public boolean isTraceEnabled() {
     99         return isLoggable(Log.VERBOSE);
    100     }
    101 
    102     /**
    103      * Log a message object at level VERBOSE.
    104      *
    105      * @param msg
    106      *          - the message object to be logged
    107      */
    108     public void trace(String msg) {
    109         log(Log.VERBOSE, msg, null);
    110     }
    111 
    112     /**
    113      * Log a message at level VERBOSE 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 VERBOSE.
    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         formatAndLog(Log.VERBOSE, format, arg);
    128     }
    129 
    130     /**
    131      * Log a message at level VERBOSE according to the specified format and
    132      * arguments.
    133      *
    134      * <p>
    135      * This form avoids superfluous object creation when the logger is disabled
    136      * for the VERBOSE level.
    137      * </p>
    138      *
    139      * @param format
    140      *          the format string
    141      * @param arg1
    142      *          the first argument
    143      * @param arg2
    144      *          the second argument
    145      */
    146     public void trace(String format, Object arg1, Object arg2) {
    147         formatAndLog(Log.VERBOSE, format, arg1, arg2);
    148     }
    149 
    150     /**
    151      * Log a message at level VERBOSE according to the specified format and
    152      * arguments.
    153      *
    154      * <p>
    155      * This form avoids superfluous object creation when the logger is disabled
    156      * for the VERBOSE level.
    157      * </p>
    158      *
    159      * @param format
    160      *          the format string
    161      * @param argArray
    162      *          an array of arguments
    163      */
    164     public void trace(String format, Object... argArray) {
    165         formatAndLog(Log.VERBOSE, format, argArray);
    166     }
    167 
    168     /**
    169      * Log an exception (throwable) at level VERBOSE with an accompanying message.
    170      *
    171      * @param msg
    172      *          the message accompanying the exception
    173      * @param t
    174      *          the exception (throwable) to log
    175      */
    176     public void trace(String msg, Throwable t) {
    177         log(Log.VERBOSE, msg, t);
    178     }
    179 
    180     /**
    181      * Is this logger instance enabled for the DEBUG level?
    182      *
    183      * @return True if this Logger is enabled for level DEBUG, false otherwise.
    184      */
    185     public boolean isDebugEnabled() {
    186         return isLoggable(Log.DEBUG);
    187     }
    188 
    189     /**
    190      * Log a message object at level DEBUG.
    191      *
    192      * @param msg
    193      *          - the message object to be logged
    194      */
    195     public void debug(String msg) {
    196         log(Log.DEBUG, msg, null);
    197     }
    198 
    199     /**
    200      * Log a message at level DEBUG according to the specified format and argument.
    201      *
    202      * <p>
    203      * This form avoids superfluous object creation when the logger is disabled
    204      * for level DEBUG.
    205      * </p>
    206      *
    207      * @param format
    208      *          the format string
    209      * @param arg
    210      *          the argument
    211      */
    212     public void debug(String format, Object arg) {
    213         formatAndLog(Log.DEBUG, format, arg);
    214     }
    215 
    216     /**
    217      * Log a message at level DEBUG according to the specified format and
    218      * arguments.
    219      *
    220      * <p>
    221      * This form avoids superfluous object creation when the logger is disabled
    222      * for the DEBUG level.
    223      * </p>
    224      *
    225      * @param format
    226      *          the format string
    227      * @param arg1
    228      *          the first argument
    229      * @param arg2
    230      *          the second argument
    231      */
    232     public void debug(String format, Object arg1, Object arg2) {
    233         formatAndLog(Log.DEBUG, format, arg1, arg2);
    234     }
    235 
    236     /**
    237      * Log a message at level DEBUG according to the specified format and
    238      * arguments.
    239      *
    240      * <p>
    241      * This form avoids superfluous object creation when the logger is disabled
    242      * for the DEBUG level.
    243      * </p>
    244      *
    245      * @param format
    246      *          the format string
    247      * @param argArray
    248      *          an array of arguments
    249      */
    250     public void debug(String format, Object... argArray) {
    251         formatAndLog(Log.DEBUG, format, argArray);
    252     }
    253 
    254     /**
    255      * Log an exception (throwable) at level DEBUG with an accompanying message.
    256      *
    257      * @param msg
    258      *          the message accompanying the exception
    259      * @param t
    260      *          the exception (throwable) to log
    261      */
    262     public void debug(String msg, Throwable t) {
    263         log(Log.VERBOSE, msg, t);
    264     }
    265 
    266     /**
    267      * Is this logger instance enabled for the INFO level?
    268      *
    269      * @return True if this Logger is enabled for the INFO level, false otherwise.
    270      */
    271     public boolean isInfoEnabled() {
    272         return isLoggable(Log.INFO);
    273     }
    274 
    275     /**
    276      * Log a message object at the INFO level.
    277      *
    278      * @param msg
    279      *          - the message object to be logged
    280      */
    281     public void info(String msg) {
    282         log(Log.INFO, msg, null);
    283     }
    284 
    285     /**
    286      * Log a message at level INFO according to the specified format and argument.
    287      *
    288      * <p>
    289      * This form avoids superfluous object creation when the logger is disabled
    290      * for the INFO level.
    291      * </p>
    292      *
    293      * @param format
    294      *          the format string
    295      * @param arg
    296      *          the argument
    297      */
    298     public void info(String format, Object arg) {
    299         formatAndLog(Log.INFO, format, arg);
    300     }
    301 
    302     /**
    303      * Log a message at the INFO level according to the specified format and
    304      * arguments.
    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 arg1
    314      *          the first argument
    315      * @param arg2
    316      *          the second argument
    317      */
    318     public void info(String format, Object arg1, Object arg2) {
    319         formatAndLog(Log.INFO, format, arg1, arg2);
    320     }
    321 
    322     /**
    323      * Log a message at level INFO according to the specified format and
    324      * arguments.
    325      *
    326      * <p>
    327      * This form avoids superfluous object creation when the logger is disabled
    328      * for the INFO level.
    329      * </p>
    330      *
    331      * @param format
    332      *          the format string
    333      * @param argArray
    334      *          an array of arguments
    335      */
    336     public void info(String format, Object... argArray) {
    337         formatAndLog(Log.INFO, format, argArray);
    338     }
    339 
    340     /**
    341      * Log an exception (throwable) at the INFO level with an accompanying
    342      * message.
    343      *
    344      * @param msg
    345      *          the message accompanying the exception
    346      * @param t
    347      *          the exception (throwable) to log
    348      */
    349     public void info(String msg, Throwable t) {
    350         log(Log.INFO, msg, t);
    351     }
    352 
    353     /**
    354      * Is this logger instance enabled for the WARN level?
    355      *
    356      * @return True if this Logger is enabled for the WARN level, false
    357      *         otherwise.
    358      */
    359     public boolean isWarnEnabled() {
    360         return isLoggable(Log.WARN);
    361     }
    362 
    363     /**
    364      * Log a message object at the WARN level.
    365      *
    366      * @param msg
    367      *          - the message object to be logged
    368      */
    369     public void warn(String msg) {
    370         log(Log.WARN, msg, null);
    371     }
    372 
    373     /**
    374      * Log a message at the WARN level according to the specified format and
    375      * argument.
    376      *
    377      * <p>
    378      * This form avoids superfluous object creation when the logger is disabled
    379      * for the WARN level.
    380      * </p>
    381      *
    382      * @param format
    383      *          the format string
    384      * @param arg
    385      *          the argument
    386      */
    387     public void warn(String format, Object arg) {
    388         formatAndLog(Log.WARN, format, arg);
    389     }
    390 
    391     /**
    392      * Log a message at the WARN level according to the specified format and
    393      * arguments.
    394      *
    395      * <p>
    396      * This form avoids superfluous object creation when the logger is disabled
    397      * for the WARN level.
    398      * </p>
    399      *
    400      * @param format
    401      *          the format string
    402      * @param arg1
    403      *          the first argument
    404      * @param arg2
    405      *          the second argument
    406      */
    407     public void warn(String format, Object arg1, Object arg2) {
    408         formatAndLog(Log.WARN, format, arg1, arg2);
    409     }
    410 
    411     /**
    412      * Log a message at level WARN according to the specified format and
    413      * arguments.
    414      *
    415      * <p>
    416      * This form avoids superfluous object creation when the logger is disabled
    417      * for the WARN level.
    418      * </p>
    419      *
    420      * @param format
    421      *          the format string
    422      * @param argArray
    423      *          an array of arguments
    424      */
    425     public void warn(String format, Object... argArray) {
    426         formatAndLog(Log.WARN, format, argArray);
    427     }
    428 
    429     /**
    430      * Log an exception (throwable) at the WARN level with an accompanying
    431      * message.
    432      *
    433      * @param msg
    434      *          the message accompanying the exception
    435      * @param t
    436      *          the exception (throwable) to log
    437      */
    438     public void warn(String msg, Throwable t) {
    439         log(Log.WARN, msg, t);
    440     }
    441 
    442     /**
    443      * Is this logger instance enabled for level ERROR?
    444      *
    445      * @return True if this Logger is enabled for level ERROR, false otherwise.
    446      */
    447     public boolean isErrorEnabled() {
    448         return isLoggable(Log.ERROR);
    449     }
    450 
    451     /**
    452      * Log a message object at the ERROR level.
    453      *
    454      * @param msg
    455      *          - the message object to be logged
    456      */
    457     public void error(String msg) {
    458         log(Log.ERROR, msg, null);
    459     }
    460 
    461     /**
    462      * Log a message at the ERROR level according to the specified format and
    463      * argument.
    464      *
    465      * <p>
    466      * This form avoids superfluous object creation when the logger is disabled
    467      * for the ERROR level.
    468      * </p>
    469      *
    470      * @param format
    471      *          the format string
    472      * @param arg
    473      *          the argument
    474      */
    475     public void error(String format, Object arg) {
    476         formatAndLog(Log.ERROR, format, arg);
    477     }
    478 
    479     /**
    480      * Log a message at the ERROR level according to the specified format and
    481      * arguments.
    482      *
    483      * <p>
    484      * This form avoids superfluous object creation when the logger is disabled
    485      * for the ERROR level.
    486      * </p>
    487      *
    488      * @param format
    489      *          the format string
    490      * @param arg1
    491      *          the first argument
    492      * @param arg2
    493      *          the second argument
    494      */
    495     public void error(String format, Object arg1, Object arg2) {
    496         formatAndLog(Log.ERROR, format, arg1, arg2);
    497     }
    498 
    499     /**
    500      * Log a message at level ERROR according to the specified format and
    501      * arguments.
    502      *
    503      * <p>
    504      * This form avoids superfluous object creation when the logger is disabled
    505      * for the ERROR level.
    506      * </p>
    507      *
    508      * @param format
    509      *          the format string
    510      * @param argArray
    511      *          an array of arguments
    512      */
    513     public void error(String format, Object... argArray) {
    514         formatAndLog(Log.ERROR, format, argArray);
    515     }
    516 
    517     /**
    518      * Log an exception (throwable) at the ERROR level with an accompanying
    519      * message.
    520      *
    521      * @param msg
    522      *          the message accompanying the exception
    523      * @param t
    524      *          the exception (throwable) to log
    525      */
    526     public void error(String msg, Throwable t) {
    527         log(Log.ERROR, msg, t);
    528     }
    529 
    530     private void formatAndLog(int priority, String format, Object... argArray) {
    531         if (isLoggable(priority)) {
    532             FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
    533             _log(priority, ft.getMessage(), ft.getThrowable());
    534         }
    535     }
    536 
    537     private void log(int priority, String message, Throwable throwable) {
    538         if (isLoggable(priority)) {
    539             _log(priority, message, throwable);
    540         }
    541     }
    542 
    543     private boolean isLoggable(int priority) {
    544         return Log.isLoggable(name, priority);
    545     }
    546 
    547     private void _log(int priority, String message, Throwable throwable) {
    548         if (throwable != null) {
    549             message += '\n' + Log.getStackTraceString(throwable);
    550         }
    551         Log.println(priority, name, message);
    552     }
    553 }