All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.psdev.slf4j.android.logger.AndroidLoggerAdapter Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2013 Philip Schiffer
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 *
 * This file incorporates code covered by the following terms:
 * Copyright (c) 2004-2013 QOS.ch
 * All rights reserved.
 *
 * Permission is hereby granted, free  of charge, to any person obtaining
 * a  copy  of this  software  and  associated  documentation files  (the
 * "Software"), to  deal in  the Software without  restriction, including
 * without limitation  the rights to  use, copy, modify,  merge, publish,
 * distribute,  sublicense, and/or sell  copies of  the Software,  and to
 * permit persons to whom the Software  is furnished to do so, subject to
 * the following conditions:
 *
 * The  above  copyright  notice  and  this permission  notice  shall  be
 * included in all copies or substantial portions of the Software.
 *
 * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
 * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
 * MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package de.psdev.slf4j.android.logger;

import android.util.Log;
import org.slf4j.Marker;
import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MarkerIgnoringBase;
import org.slf4j.helpers.MessageFormatter;

import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;
import java.util.Properties;
import java.util.regex.Pattern;

/**
 * 

A simple implementation that delegates all log requests to the Google Android * logging facilities. Note that this logger does not support {@link Marker}. * Methods taking marker data as parameter simply invoke the eponymous method * without the Marker argument, discarding any marker data in the process.

*

*

The logging levels specified for SLF4J can be almost directly mapped to * the levels that exist in the Google Android platform. The following table * shows the mapping implemented by this logger.

*

*

* * * * * * *
SLF4JAndroid
TRACE{@link Log#VERBOSE}
DEBUG{@link Log#DEBUG}
INFO{@link Log#INFO}
WARN{@link Log#WARN}
ERROR{@link Log#ERROR}
*

*

Use loggers as usual: *

    *
  • * Declare a logger
    * private static final Logger logger = LoggerFactory.getLogger(MyClass.class); *
  • *
  • * Invoke logging methods, e.g.,
    * logger.debug("Some log message. Details: {}", someObject);
    * logger.debug("Some log message with varargs. Details: {}, {}, {}", someObject1, someObject2, someObject3); *
  • *
*

*

*

Logger instances created using the LoggerFactory are named according to the fully qualified * class name of the class given as a parameter. * * @author Andrey Korzhevskiy * @author Philip Schiffer *

* This form avoids superfluous object creation when the logger is disabled * for level VERBOSE. *

* * @param format the format string * @param arg the argument */ @Override public void trace(final String format, final Object arg) { formatAndLog(LogLevel.TRACE, format, arg); } /** * Log a message at level VERBOSE according to the specified format and * arguments. *

*

* This form avoids superfluous object creation when the logger is disabled * for the VERBOSE level. *

* * @param format the format string * @param arg1 the first argument * @param arg2 the second argument */ @Override public void trace(final String format, final Object arg1, final Object arg2) { formatAndLog(LogLevel.TRACE, format, arg1, arg2); } /** * Log a message at level VERBOSE according to the specified format and * arguments. *

*

* This form avoids superfluous object creation when the logger is disabled * for the VERBOSE level. *

* * @param format the format string * @param argArray an array of arguments */ @Override public void trace(final String format, final Object... argArray) { formatAndLog(LogLevel.TRACE, format, argArray); } /** * Log an exception (throwable) at level VERBOSE with an accompanying message. * * @param msg the message accompanying the exception * @param t the exception (throwable) to log */ @Override public void trace(final String msg, final Throwable t) { log(LogLevel.TRACE, msg, t); } /** * Is this logger instance enabled for the DEBUG level? * * @return True if this Logger is enabled for level DEBUG, false otherwise. */ @Override public boolean isDebugEnabled() { return isLevelEnabled(LogLevel.DEBUG); } /** * Log a message object at level DEBUG. * * @param msg - the message object to be logged */ @Override public void debug(final String msg) { log(LogLevel.DEBUG, msg, null); } /** * Log a message at level DEBUG according to the specified format and argument. *

*

* This form avoids superfluous object creation when the logger is disabled * for level DEBUG. *

* * @param format the format string * @param arg the argument */ @Override public void debug(final String format, final Object arg) { formatAndLog(LogLevel.DEBUG, format, arg); } /** * Log a message at level DEBUG according to the specified format and * arguments. *

*

* This form avoids superfluous object creation when the logger is disabled * for the DEBUG level. *

* * @param format the format string * @param arg1 the first argument * @param arg2 the second argument */ @Override public void debug(final String format, final Object arg1, final Object arg2) { formatAndLog(LogLevel.DEBUG, format, arg1, arg2); } /** * Log a message at level DEBUG according to the specified format and * arguments. *

*

* This form avoids superfluous object creation when the logger is disabled * for the DEBUG level. *

* * @param format the format string * @param argArray an array of arguments */ @Override public void debug(final String format, final Object... argArray) { formatAndLog(LogLevel.DEBUG, format, argArray); } /** * Log an exception (throwable) at level DEBUG with an accompanying message. * * @param msg the message accompanying the exception * @param t the exception (throwable) to log */ @Override public void debug(final String msg, final Throwable t) { log(LogLevel.DEBUG, msg, t); } /** * Is this logger instance enabled for the INFO level? * * @return True if this Logger is enabled for the INFO level, false otherwise. */ @Override public boolean isInfoEnabled() { return isLevelEnabled(LogLevel.INFO); } /** * Log a message object at the INFO level. * * @param msg - the message object to be logged */ @Override public void info(final String msg) { log(LogLevel.INFO, msg, null); } /** * Log a message at level INFO according to the specified format and argument. *

*

* This form avoids superfluous object creation when the logger is disabled * for the INFO level. *

* * @param format the format string * @param arg the argument */ @Override public void info(final String format, final Object arg) { formatAndLog(LogLevel.INFO, format, arg); } /** * Log a message at the INFO level according to the specified format and * arguments. *

*

* This form avoids superfluous object creation when the logger is disabled * for the INFO level. *

* * @param format the format string * @param arg1 the first argument * @param arg2 the second argument */ @Override public void info(final String format, final Object arg1, final Object arg2) { formatAndLog(LogLevel.INFO, format, arg1, arg2); } /** * Log a message at level INFO according to the specified format and * arguments. *

*

* This form avoids superfluous object creation when the logger is disabled * for the INFO level. *

* * @param format the format string * @param argArray an array of arguments */ @Override public void info(final String format, final Object... argArray) { formatAndLog(LogLevel.INFO, format, argArray); } /** * Log an exception (throwable) at the INFO level with an accompanying * message. * * @param msg the message accompanying the exception * @param t the exception (throwable) to log */ @Override public void info(final String msg, final Throwable t) { log(LogLevel.INFO, msg, t); } /** * Is this logger instance enabled for the WARN level? * * @return True if this Logger is enabled for the WARN level, false * otherwise. */ @Override public boolean isWarnEnabled() { return isLevelEnabled(LogLevel.WARN); } /** * Log a message object at the WARN level. * * @param msg - the message object to be logged */ @Override public void warn(final String msg) { log(LogLevel.WARN, msg, null); } /** * Log a message at the WARN level according to the specified format and * argument. *

*

* This form avoids superfluous object creation when the logger is disabled * for the WARN level. *

* * @param format the format string * @param arg the argument */ @Override public void warn(final String format, final Object arg) { formatAndLog(LogLevel.WARN, format, arg); } /** * Log a message at the WARN level according to the specified format and * arguments. *

*

* This form avoids superfluous object creation when the logger is disabled * for the WARN level. *

* * @param format the format string * @param arg1 the first argument * @param arg2 the second argument */ @Override public void warn(final String format, final Object arg1, final Object arg2) { formatAndLog(LogLevel.WARN, format, arg1, arg2); } /** * Log a message at level WARN according to the specified format and * arguments. *

*

* This form avoids superfluous object creation when the logger is disabled * for the WARN level. *

* * @param format the format string * @param argArray an array of arguments */ @Override public void warn(final String format, final Object... argArray) { formatAndLog(LogLevel.WARN, format, argArray); } /** * Log an exception (throwable) at the WARN level with an accompanying * message. * * @param msg the message accompanying the exception * @param t the exception (throwable) to log */ @Override public void warn(final String msg, final Throwable t) { log(LogLevel.WARN, msg, t); } /** * Is this logger instance enabled for level ERROR? * * @return True if this Logger is enabled for level ERROR, false otherwise. */ @Override public boolean isErrorEnabled() { return isLevelEnabled(LogLevel.ERROR); } /** * Log a message object at the ERROR level. * * @param msg - the message object to be logged */ @Override public void error(final String msg) { log(LogLevel.ERROR, msg, null); } /** * Log a message at the ERROR level according to the specified format and * argument. *

*

* This form avoids superfluous object creation when the logger is disabled * for the ERROR level. *

* * @param format the format string * @param arg the argument */ @Override public void error(final String format, final Object arg) { formatAndLog(LogLevel.ERROR, format, arg); } /** * Log a message at the ERROR level according to the specified format and * arguments. *

*

* This form avoids superfluous object creation when the logger is disabled * for the ERROR level. *

* * @param format the format string * @param arg1 the first argument * @param arg2 the second argument */ @Override public void error(final String format, final Object arg1, final Object arg2) { formatAndLog(LogLevel.ERROR, format, arg1, arg2); } /** * Log a message at level ERROR according to the specified format and * arguments. *

*

* This form avoids superfluous object creation when the logger is disabled * for the ERROR level. *

* * @param format the format string * @param argArray an array of arguments */ @Override public void error(final String format, final Object... argArray) { formatAndLog(LogLevel.ERROR, format, argArray); } /** * Log an exception (throwable) at the ERROR level with an accompanying * message. * * @param msg the message accompanying the exception * @param t the exception (throwable) to log */ @Override public void error(final String msg, final Throwable t) { log(LogLevel.ERROR, msg, t); } private void formatAndLog(final LogLevel logLevel, final String format, final Object... argArray) { if (isLevelEnabled(logLevel)) { final FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); log(logLevel, ft.getMessage(), ft.getThrowable()); } } private void log(final LogLevel logLevel, final String message, final Throwable throwable) { if (isLevelEnabled(logLevel)) { switch (logLevel.getAndroidLogLevel()) { case Log.VERBOSE: logAndroidVerbose(message, throwable); break; case Log.DEBUG: logAndroidDebug(message, throwable); break; case Log.INFO: logAndroidInfo(message, throwable); break; case Log.WARN: logAndroidWarn(message, throwable); break; case Log.ERROR: logAndroidError(message, throwable); break; default: // nop break; } } } private void logAndroidVerbose(final String message, final Throwable throwable) { if (throwable != null) { Log.v(getLogTag(), enhanced(message), throwable); } else { Log.v(getLogTag(), enhanced(message)); } } private void logAndroidDebug(final String message, final Throwable throwable) { if (throwable != null) { Log.d(getLogTag(), enhanced(message), throwable); } else { Log.d(getLogTag(), enhanced(message)); } } private void logAndroidInfo(final String message, final Throwable throwable) { if (throwable != null) { Log.i(getLogTag(), enhanced(message), throwable); } else { Log.i(getLogTag(), enhanced(message)); } } private void logAndroidWarn(final String message, final Throwable throwable) { if (throwable != null) { Log.w(getLogTag(), enhanced(message), throwable); } else { Log.w(getLogTag(), enhanced(message)); } } private void logAndroidError(final String message, final Throwable throwable) { if (throwable != null) { Log.e(getLogTag(), enhanced(message), throwable); } else { Log.e(getLogTag(), enhanced(message)); } } // Property getter private static String getStringProperty(final String propertyName) { String propertyValue = null; try { propertyValue = System.getProperty(propertyName); } catch (SecurityException ignored) { } return propertyValue == null ? ANDROID_LOGGER_PROPERTIES.getProperty(propertyName) : propertyValue; } private static String getStringProperty(final String propertyName, final String defaultValue) { final String prop = getStringProperty(propertyName); return prop == null ? defaultValue : prop; } private static boolean getBooleanProperty(final String propertyName, final boolean defaultValue) { final String prop = getStringProperty(propertyName); return prop == null ? defaultValue : "true".equalsIgnoreCase(prop); } private String enhanced(final String message) { final StackTraceElement caller = determineCaller(); final String classNameOnly = getClassNameOnly(caller.getClassName()); final String methodName = caller.getMethodName(); final int lineNumber = caller.getLineNumber(); final Thread thread = Thread.currentThread(); return String.format(Locale.ENGLISH, "%s [%s:%s:%s] %s", message, classNameOnly, methodName, lineNumber, thread); } private StackTraceElement determineCaller() { final StackTraceElement[] stackTrace = new DetermineCallerException().getStackTrace(); for (final StackTraceElement element : stackTrace) { if (mClassNamePattern.matcher(element.getClassName()).matches()) { return element; } } return NOT_FOUND; } private static String getClassNameOnly(final String classNameWithPackage) { final int lastDotPos = classNameWithPackage.lastIndexOf('.'); if (lastDotPos == -1) { return classNameWithPackage; } return classNameWithPackage.substring(lastDotPos + 1); } /** * Is the given log level currently enabled? * * @param logLevel is this level enabled? */ protected static boolean isLevelEnabled(final LogLevel logLevel) { // log level are numerically ordered so can use simple numeric comparison return logLevel.getAndroidLogLevel() >= sLogLevel.getAndroidLogLevel(); } private static LogLevel stringToLevel(final String levelStr) { if ("trace".equalsIgnoreCase(levelStr)) { return LogLevel.TRACE; } if ("verbose".equalsIgnoreCase(levelStr)) { return LogLevel.TRACE; } if ("debug".equalsIgnoreCase(levelStr)) { return LogLevel.DEBUG; } if ("info".equalsIgnoreCase(levelStr)) { return LogLevel.INFO; } if ("warn".equalsIgnoreCase(levelStr)) { return LogLevel.WARN; } if ("error".equalsIgnoreCase(levelStr)) { return LogLevel.ERROR; } // assume INFO by default return LogLevel.INFO; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy