/* * Cuelib library for manipulating cue sheets. * Copyright (C) 2007-2008 Jan-Willem van den Broek * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package jwbroek.util; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.Logger; /** * Class containing utility methods related to logging. * @author jwbroek */ public final class LogUtil { /** * The logger for this class. */ private final static Logger logger = Logger.getLogger(LogUtil.class.getCanonicalName()); /** * This constructor need never be called as all members of this class are static. */ private LogUtil() { // Intentionally empty (except for logging). This class does not need to be instantiated. LogUtil.logger.entering(LogUtil.class.getCanonicalName(), "TrackCutterCommand()"); LogUtil.logger.warning("jwbroek.util.LogUtil should not be instantiated."); LogUtil.logger.exiting(LogUtil.class.getCanonicalName(), "TrackCutterCommand()"); } /** * Convenience method to log the stack trace of a Throwable to the specified Logger at the specified Level. * @param logger Logger to log to. * @param level Level to log at. * @param throwable Throwable to log the stack strace of. */ public static void logStacktrace(final Logger logger, final Level level, final Throwable throwable) { LogUtil.logger.entering ( LogUtil.class.getCanonicalName() , "logStacktrace(Logger,Level,Throwable)" , new Object[] {logger, level, throwable} ); final StringWriter sw = new StringWriter(); throwable.printStackTrace(new PrintWriter(sw)); logger.log(level, sw.toString()); LogUtil.logger.exiting(LogUtil.class.getCanonicalName(), "logStacktrace(Logger,Level,Throwable)"); } /** * Get the Level that is currently active on the specified Logger. Will search though parent Logger as necessary. * @param logger The Logger to determine the Level of. * @return The Level that is currently active on the specified Logger. */ public static Level getActiveLoggingLevel(Logger logger) { LogUtil.logger.entering(LogUtil.class.getCanonicalName(), "getActiveLoggingLevel(Logger)", logger); Logger currentLogger = logger; Level result = null; do { result = logger.getLevel(); if (currentLogger.getUseParentHandlers()) { currentLogger = currentLogger.getParent(); } else { currentLogger = null; } } while (result==null && currentLogger != null); LogUtil.logger.exiting(LogUtil.class.getCanonicalName(), "getActiveLoggingLevel(Logger)", result); return result; } /** * Get whether or not the information that is logged at the specified Level to the specified Logger * will be handled by a Handler that is an instance of the specified class. Note that since loggers * may be added and removed at any time, this information is not guaranteed to be correct at any moment. * Also, even when this method return true, messages logged to the specified logger, at the specified level, * may still not be logged by a handler of the specified type due to Filters that are configured. * @param logger The Logger to check for. * @param level The level to check for. * @param handlerClass The class of Handler to check for. * @return Whether or not the information that is logged at the specified Level to the specified Logger * will be handled by a Handler that is an instance of the specified class. */ public static boolean hasHandlerActive(final Logger logger, final Level level, final Class handlerClass) { LogUtil.logger.entering ( LogUtil.class.getCanonicalName() , "hasHandlerActive(Logger,Level,Class)" , new Object[] {logger, level, handlerClass} ); Logger currentLogger = logger; boolean result = false; loopOverLoggers: while (currentLogger != null && currentLogger.isLoggable(level)) { for (Handler handler : currentLogger.getHandlers()) { // Handler is correct type of class and has low enough logging level. if ( handlerClass.isInstance(handler) && handler.getLevel().intValue() <= level.intValue() ) { result = true; break loopOverLoggers; } } if (currentLogger.getUseParentHandlers()) { currentLogger = currentLogger.getParent(); } else { currentLogger = null; } } LogUtil.logger.exiting(LogUtil.class.getCanonicalName(), "hasHandlerActive(Logger,Level,Class)", result); return result; } /** * Get a list of all currently active Handlers on the specified Logger. Note that handlers can be * dynamically added and removed, so this information is not guaranteed to be correct at any moment. * @param logger * @return A list of all currently active Handlers on the specified Logger. */ public static Set<Handler> getAllActiveHandlers(final Logger logger) { LogUtil.logger.entering(LogUtil.class.getCanonicalName(), "getAllActiveHandlers(Logger)", logger); final Set<Handler> handlers = new HashSet<Handler>(); Logger currentLogger = logger; while (currentLogger != null) { handlers.addAll(Arrays.asList(currentLogger.getHandlers())); if (currentLogger.getUseParentHandlers()) { currentLogger = currentLogger.getParent(); } else { currentLogger = null; } } LogUtil.logger.exiting(LogUtil.class.getCanonicalName(), "getAllActiveHandlers(Logger)", handlers); return handlers; } }