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

org.slf4j.bridge.SLF4JBridgeHandler Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (c) 2004-2011 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 org.slf4j.bridge;

import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.spi.LocationAwareLogger;

// Based on http://jira.qos.ch/browse/SLF4J-30

/**
 * 

Bridge/route all JUL log records to the SLF4J API. *

Essentially, the idea is to install on the root logger an instance of * {@link SLF4JBridgeHandler} as the sole JUL handler in the system. Subsequently, the * SLF4JBridgeHandler instance will redirect all JUL log records are redirected * to the SLF4J API based on the following mapping of levels: * *

 * FINEST  -> TRACE
 * FINER   -> DEBUG
 * FINE    -> DEBUG
 * INFO    -> INFO
 * WARNING -> WARN
 * SEVERE  -> ERROR
*

Programmatic installation: *

 * // Optionally remove existing handlers attached to j.u.l root logger
 * SLF4JBridgeHandler.removeHandlersForRootLogger();  // (since SLF4J 1.6.5)

 * // add SLF4JBridgeHandler to j.u.l's root logger, should be done once during
 * // the initialization phase of your application
 * SLF4JBridgeHandler.install();
*

Installation via logging.properties configuration file: *

 * // register SLF4JBridgeHandler as handler for the j.u.l. root logger
 * handlers = org.slf4j.bridge.SLF4JBridgeHandler
*

Once SLF4JBridgeHandler is installed, logging by j.u.l. loggers will be directed to * SLF4J. Example: *

 * import  java.util.logging.Logger;
 * ...
 * // usual pattern: get a Logger and then log a message
 * Logger julLogger = Logger.getLogger("org.wombat");
 * julLogger.fine("hello world"); // this will get redirected to SLF4J
* *

Please note that translating a java.util.logging event into SLF4J incurs the * cost of constructing {@link LogRecord} instance regardless of whether the * SLF4J logger is disabled for the given level. Consequently, j.u.l. to * SLF4J translation can seriously increase the cost of disabled logging * statements (60 fold or 6000% increase) and measurably impact the performance of enabled log * statements (20% overall increase). Please note that as of logback-version 0.9.25, * it is possible to completely eliminate the 60-fold translation overhead for disabled * log statements with the help of LevelChangePropagator. * * *

If you are concerned about application performance, then use of SLF4JBridgeHandler * is appropriate only if any of the following conditions is true: *

    *
  1. few j.u.l. logging statements are in play
  2. *
  3. LevelChangePropagator has been installed
  4. *
* *

As a Java 9/Jigsaw module

* *

As of SLF4J 2.0x, the module name for jul-to-slf4j.jar is * jul.to.slf4j. In SLF4J 1.7.x it was declared via an Automatic-Module-Name statement * as jul_to_slf4j (note the two underscores). * * @author Christian Stein * @author Joern Huxhorn * @author Ceki Gülcü * @author Darryl Smith * @since 1.5.1 */ public class SLF4JBridgeHandler extends Handler { // The caller is java.util.logging.Logger private static final String FQCN = java.util.logging.Logger.class.getName(); private static final String UNKNOWN_LOGGER_NAME = "unknown.jul.logger"; private static final int TRACE_LEVEL_THRESHOLD = Level.FINEST.intValue(); private static final int DEBUG_LEVEL_THRESHOLD = Level.FINE.intValue(); private static final int INFO_LEVEL_THRESHOLD = Level.INFO.intValue(); private static final int WARN_LEVEL_THRESHOLD = Level.WARNING.intValue(); /** * Adds a SLF4JBridgeHandler instance to jul's root logger. * *

This handler will redirect j.u.l. logging to SLF4J. However, only logs enabled * in j.u.l. will be redirected. For example, if a log statement invoking a * j.u.l. logger is disabled, then the corresponding non-event will not * reach SLF4JBridgeHandler and cannot be redirected. */ public static void install() { LogManager.getLogManager().getLogger("").addHandler(new SLF4JBridgeHandler()); } private static java.util.logging.Logger getRootLogger() { return LogManager.getLogManager().getLogger(""); } /** * Removes previously installed SLF4JBridgeHandler instances. See also * {@link #install()}. * * @throws SecurityException A SecurityException is thrown, if a security manager * exists and if the caller does not have * LoggingPermission("control"). */ public static void uninstall() throws SecurityException { java.util.logging.Logger rootLogger = getRootLogger(); Handler[] handlers = rootLogger.getHandlers(); for (Handler handler : handlers) { if (handler instanceof SLF4JBridgeHandler) { rootLogger.removeHandler(handler); } } } /** * Returns true if SLF4JBridgeHandler has been previously installed, returns false otherwise. * * @return true if SLF4JBridgeHandler is already installed, false otherwise * */ public static boolean isInstalled() { java.util.logging.Logger rootLogger = getRootLogger(); Handler[] handlers = rootLogger.getHandlers(); for (Handler handler : handlers) { if (handler instanceof SLF4JBridgeHandler) { return true; } } return false; } /** * Invoking this method removes/unregisters/detaches all handlers currently attached to the root logger * @since 1.6.5 */ public static void removeHandlersForRootLogger() { java.util.logging.Logger rootLogger = getRootLogger(); java.util.logging.Handler[] handlers = rootLogger.getHandlers(); for (Handler handler : handlers) { rootLogger.removeHandler(handler); } } /** * Initialize this handler. */ public SLF4JBridgeHandler() { } /** * No-op implementation. */ public void close() { // empty } /** * No-op implementation. */ public void flush() { // empty } /** * Return the Logger instance that will be used for logging. * * @param record a LogRecord * @return an SLF4J logger corresponding to the record parameter's logger name */ protected Logger getSLF4JLogger(LogRecord record) { String name = record.getLoggerName(); if (name == null) { name = UNKNOWN_LOGGER_NAME; } return LoggerFactory.getLogger(name); } protected void callLocationAwareLogger(LocationAwareLogger lal, LogRecord record) { int julLevelValue = record.getLevel().intValue(); int slf4jLevel; if (julLevelValue <= TRACE_LEVEL_THRESHOLD) { slf4jLevel = LocationAwareLogger.TRACE_INT; } else if (julLevelValue <= DEBUG_LEVEL_THRESHOLD) { slf4jLevel = LocationAwareLogger.DEBUG_INT; } else if (julLevelValue <= INFO_LEVEL_THRESHOLD) { slf4jLevel = LocationAwareLogger.INFO_INT; } else if (julLevelValue <= WARN_LEVEL_THRESHOLD) { slf4jLevel = LocationAwareLogger.WARN_INT; } else { slf4jLevel = LocationAwareLogger.ERROR_INT; } String i18nMessage = getMessageI18N(record); lal.log(null, FQCN, slf4jLevel, i18nMessage, null, record.getThrown()); } protected void callPlainSLF4JLogger(Logger slf4jLogger, LogRecord record) { String i18nMessage = getMessageI18N(record); int julLevelValue = record.getLevel().intValue(); if (julLevelValue <= TRACE_LEVEL_THRESHOLD) { slf4jLogger.trace(i18nMessage, record.getThrown()); } else if (julLevelValue <= DEBUG_LEVEL_THRESHOLD) { slf4jLogger.debug(i18nMessage, record.getThrown()); } else if (julLevelValue <= INFO_LEVEL_THRESHOLD) { slf4jLogger.info(i18nMessage, record.getThrown()); } else if (julLevelValue <= WARN_LEVEL_THRESHOLD) { slf4jLogger.warn(i18nMessage, record.getThrown()); } else { slf4jLogger.error(i18nMessage, record.getThrown()); } } /** * Get the record's message, possibly via a resource bundle. * * @param record * @return */ private String getMessageI18N(LogRecord record) { String message = record.getMessage(); if (message == null) { return null; } ResourceBundle bundle = record.getResourceBundle(); if (bundle != null) { try { message = bundle.getString(message); } catch (MissingResourceException e) { } } Object[] params = record.getParameters(); // avoid formatting when there are no or 0 parameters. see also // http://jira.qos.ch/browse/SLF4J-203 if (params != null && params.length > 0) { try { message = MessageFormat.format(message, params); } catch (IllegalArgumentException e) { // default to the same behavior as in java.util.logging.Formatter.formatMessage(LogRecord) // see also http://jira.qos.ch/browse/SLF4J-337 return message; } } return message; } /** * Publish a LogRecord. *

* The logging request was made initially to a Logger object, which * initialized the LogRecord and forwarded it here. *

* This handler ignores the Level attached to the LogRecord, as SLF4J cares * about discarding log statements. * * @param record Description of the log event. A null record is silently ignored * and is not published. */ public void publish(LogRecord record) { // Silently ignore null records. if (record == null) { return; } Logger slf4jLogger = getSLF4JLogger(record); // this is a check to avoid calling the underlying logging system // with a null message. While it is legitimate to invoke j.u.l. with // a null message, other logging frameworks do not support this. // see also http://jira.qos.ch/browse/SLF4J-99 if (record.getMessage() == null) { record.setMessage(""); } if (slf4jLogger instanceof LocationAwareLogger) { callLocationAwareLogger((LocationAwareLogger) slf4jLogger, record); } else { callPlainSLF4JLogger(slf4jLogger, record); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy