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

com.noveogroup.android.log.LoggerManager Maven / Gradle / Ivy

Go to download

Useful logger for Android based on standard android.util.Log class. Simple lightweight (< 50 Kb) implementation of SLF4J API. Easy but powerful configuration via properties file and some additional helpful logging methods. Easy analogue of popular log4j library.

There is a newer version: 1.3.6
Show newest version
/*
 * Copyright (c) 2013 Noveo Group
 *
 * 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.
 *
 * Except as contained in this notice, the name(s) of the above copyright holders
 * shall not be used in advertising or otherwise to promote the sale, use or
 * other dealings in this Software without prior written authorization.
 *
 * 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 com.noveogroup.android.log;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * The logger manager.
 * 

* To configure this logger manager you can include an * {@code android-logger.properties} file in src directory. * The format of configuration file is: *

 * # root logger configuration
 * root=<level>:<tag>
 * # package / class logger configuration
 * logger.<package or class name>=<level>:<tag>
 * 
* You can use values of {@link Logger.Level} enum as level constants. * For example, the following configuration will * log all ERROR messages with tag "MyApplication" and all * messages from classes {@code com.example.server.*} with * tag "MyApplication-server": *
 * root=ERROR:MyApplication
 * logger.com.example.server=DEBUG:MyApplication-server
 * 
*

*/ public final class LoggerManager { private LoggerManager() { throw new UnsupportedOperationException(); } private static final Handler DEFAULT_HANDLER = new PatternHandler(Logger.Level.VERBOSE, "%logger", "%date %caller%n"); private static final Logger DEFAULT_LOGGER = new SimpleLogger(Logger.ROOT_LOGGER_NAME, DEFAULT_HANDLER); private static final int MAX_LOG_TAG_LENGTH = 23; private static final String PROPERTIES_NAME = "android-logger.properties"; private static final String CONF_ROOT = "root"; private static final String CONF_LOGGER = "logger."; private static final Pattern CONF_LOGGER_REGEX = Pattern.compile("(.*?):(.*?)(:(.*))?"); private static void loadProperties(Properties properties) throws IOException { InputStream inputStream = null; try { inputStream = LoggerManager.class.getClassLoader().getResourceAsStream(PROPERTIES_NAME); if (inputStream != null) { properties.load(inputStream); } else { inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream(PROPERTIES_NAME); if (inputStream != null) { properties.load(inputStream); } } } finally { if (inputStream != null) { inputStream.close(); } } } private static Handler decodeHandler(String handlerString) { Matcher matcher = CONF_LOGGER_REGEX.matcher(handlerString); if (matcher.matches()) { String levelString = matcher.group(1); String tag = matcher.group(2); String message = matcher.group(4); if (tag.length() > 23) { String trimmedTag = tag.substring(0, MAX_LOG_TAG_LENGTH); DEFAULT_LOGGER.w("Android doesn't support tags %d characters longer. Tag '%s' will be trimmed to '%s'", MAX_LOG_TAG_LENGTH, tag, trimmedTag); tag = trimmedTag; } try { return new PatternHandler(Logger.Level.valueOf(levelString), tag, message); } catch (IllegalArgumentException e) { DEFAULT_LOGGER.w("Cannot parse '%s' as logging level. Only %s are allowed", levelString, Arrays.toString(Logger.Level.values())); return null; } } else { DEFAULT_LOGGER.w("Wrong format of logger configuration: '%s'", handlerString); return null; } } private static Map loadConfiguration() { Map handlerMap = new HashMap(); // read properties file Properties properties = new Properties(); try { loadProperties(properties); } catch (IOException e) { DEFAULT_LOGGER.e(e, "Cannot configure logger from '%s'. Default configuration will be used", PROPERTIES_NAME); handlerMap.put(null, DEFAULT_HANDLER); return handlerMap; } // something is wrong if property file is empty if (!properties.propertyNames().hasMoreElements()) { DEFAULT_LOGGER.e("Logger configuration file is empty. Default configuration will be used"); handlerMap.put(null, DEFAULT_HANDLER); return handlerMap; } // parse properties to logger map for (Enumeration names = properties.propertyNames(); names.hasMoreElements(); ) { String propertyName = (String) names.nextElement(); String propertyValue = properties.getProperty(propertyName); Handler handler = decodeHandler(propertyValue); if (handler != null) { if (propertyName.equals(CONF_ROOT)) { handlerMap.put(null, handler); } else if (propertyName.startsWith(CONF_LOGGER)) { String loggerName = propertyName.substring(CONF_LOGGER.length()); if (loggerName.equalsIgnoreCase(Logger.ROOT_LOGGER_NAME)) { loggerName = null; } handlerMap.put(loggerName, handler); } else { DEFAULT_LOGGER.e("unknown key '%s' in '%s' file", propertyName, PROPERTIES_NAME); } } } // logger map should have root logger (corresponding to "null" key) if (!handlerMap.containsKey(null)) { handlerMap.put(null, DEFAULT_HANDLER); } return handlerMap; } private static final Map HANDLER_MAP = Collections.unmodifiableMap(loadConfiguration()); private static Handler findHandler(String name) { String currentKey = null; if (name != null) { for (String key : HANDLER_MAP.keySet()) { if (key != null && name.startsWith(key)) { // check that key corresponds to a name of sub-package if (key.length() >= name.length() || name.charAt(key.length()) == '.' || name.charAt(key.length()) == '$') { // update current best matching key if (currentKey == null || currentKey.length() < key.length()) { currentKey = key; } } } } } Handler handler = HANDLER_MAP.get(currentKey); return handler != null ? handler : DEFAULT_HANDLER; } private static final Map LOGGER_CACHE = new WeakHashMap(); /** * Returns logger corresponding to the specified name. * * @param name the name. * @return the {@link Logger} implementation. */ public static Logger getLogger(String name) { Logger logger; // try to find a logger in the cache synchronized (LOGGER_CACHE) { logger = LOGGER_CACHE.get(name); } // load logger from configuration if (logger == null) { logger = new SimpleLogger(name, findHandler(name)); synchronized (LOGGER_CACHE) { LOGGER_CACHE.put(logger.getName(), logger); } } // return logger return logger; } /** * Returns logger corresponding to the specified class. * * @param aClass the class. * @return the {@link Logger} implementation. */ public static Logger getLogger(Class aClass) { return getLogger(aClass == null ? null : aClass.getName()); } /** * Returns logger corresponding to the caller class. * * @return the {@link Logger} implementation. */ public static Logger getLogger() { return getLogger(Utils.getCallerClassName()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy