SLF4J overview

The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks, such as java.util.logging, logback and log4j. SLF4J allows the end-user to plug in the desired logging framework at deployment time.

Simple Logging Facade for Java (SLF4J) can be used as a Simple Facade or abstraction for various Logging frameworks, such as java.util.logging, Logback, and log4j. SLF4J allows end users to plug in the required logging framework at deployment time.

Binding with a logging framework at deployment time

The SLF4J distribution ships with several jar files referred to as SLF4J bindings, with each binding corresponding to a supported framework.

  • Slf4j log4j12-1.7.27. Jar

    Binding for log4j version 1.2, a widely used logging framework. You also need to place log4j.jar on your class path.

  • Slf4j jdk14-1.7.27. Jar

    Binding for java.util.logging, also referred to as JDK 1.4 logging

  • Slf4j – nop – 1.7.27. Jar

    Binding for NOP, silently discarding all logging.

  • Slf4j – simple – 1.7.27. Jar

    Binding for Simple implementation, which outputs all events to System.err. Only messages of level INFO and higher are printed. This binding may be useful in the context of small applications.

  • Slf4j JCL – 1.7.27. Jar

    Binding for Jakarta Commons Logging. This binding will delegate all SLF4J logging to JCL.

  • Logback – classic – 1.2.3. Jar (the requires logback – core – 1.2.3. Jar)

    There are also SLF4J bindings external to the SLF4J project, Logback's ch.qos.logback.classic.Loggerclass is a direct implementation of SLF4J’s org.slf4j.Logger interface.

To switch logging frameworks, just replace slf4j bindings on your class path. For example, to switch from java.util.logging to log4j, just replace slf4j-jdk14-1.7.27.jar with slf4j-log4j12-1.7.27.jar.

To switch the logging framework, simply replace the SLF4J binding on the classpath. For example, to switch from java.util.logging to log4j, simply replace slf4J-jdk14-1.7.27.jar with slf4j-log4j12-1.7.27.jar.

SLF4J does not rely on any special class loader machinery. In fact, each SLF4J binding is hardwired at compile time to use one and only one specific logging framework. For example, The slf4J-log4j12-1.7.27. jar binding is bound at compile time to use log4j. In your code, In addition to slf4j – API – 1.7.27. Jar, you simply drop one and only one binding of your choice onto the appropriate class path location. Do not place more than one binding on your class path.

Consolidate logging via SLF4J

SLF4J caters for this common use-case by providing bridging modules for JCL, java.util.logging and log4j.

SLF4J satisfies this common use case by providing bridge modules for JCL, java.util.logging, and log4j.

Mapped Diagnostic Context (MDC) support

Mapped Diagnostic Context is essentially a map maintained by the logging framework where the application code provides key-value pairs which can then be inserted by the logging framework in log messages. MDC data can also be highly helpful in filtering messages or triggering certain actions.

A mapping diagnostic context is essentially a mapping maintained by the logging framework, where application code provides key-value pairs that can then be inserted by the logging framework in log messages. MDC data is also useful in filtering messages or triggering certain operations.

SLF4J supports MDC, or mapped diagnostic context. If the underlying logging framework offers MDC functionality, then SLF4J will delegate to the underlying framework’s MDC. Note that at this time, only log4j and logback offer MDC functionality. If the underlying framework does not offer MDC, for example java.util.logging, then SLF4J will still store MDC data but the information therein will need to be retrieved by custom user code.

SLF4J supports MDC or mapped diagnostic contexts. If the underlying logging framework provides MDC functionality, SLF4J delegates to the MDC of the underlying framework. Note that only Log4J and LogBack currently provide MDC functionality. If the underlying framework does not provide MDC, such as java.util.logging, SLF4J will still store MDC data, but the information in it needs to be retrieved by custom user code.

The principle of analysis

SLF4J abstracts various concrete logging frameworks, which is done by the StaticLoggerBinder class. Bind () looks for StaticLoggerBinder.

private final static void bind(a) {
    try {
        // Find all StaticLoggerBinder classes in the classpath
        Set<URL> staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
        // If more than one StaticLoggerBinder class exists, the log is printed
        reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
        // Get StaticLoggerBinder instance, if not present, raise NoClassDefFoundError exception
        StaticLoggerBinder.getSingleton();
        INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
        // Print using the StaticLoggerBinder class
        reportActualBinding(staticLoggerBinderPathSet);
        fixSubstitutedLoggers();
    } catch (NoClassDefFoundError ncde) {
        String msg = ncde.getMessage();
        if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
            INITIALIZATION_STATE = NOP_FALLBACK_INITIALIZATION;
            Util.report("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");
            Util.report("Defaulting to no-operation (NOP) logger implementation");
            Util.report("See " + NO_STATICLOGGERBINDER_URL + " for further details.");
        } else {
            failedBinding(ncde);
            throwncde; }}catch (java.lang.NoSuchMethodError nsme) {
        String msg = nsme.getMessage();
        if(msg ! =null && msg.indexOf("org.slf4j.impl.StaticLoggerBinder.getSingleton()") != -1) {
            INITIALIZATION_STATE = FAILED_INITIALIZATION;
            Util.report("slf4j-api 1.6.x (or later) is incompatible with this binding.");
            Util.report("Your binding is version 1.5.5 or earlier.");
            Util.report("Upgrade your binding to version 1.6.x.");
        }
        throw nsme;
    } catch (Exception e) {
        failedBinding(e);
        throw new IllegalStateException("Unexpected initialization failure", e); }}private static String  STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";

private static Set<URL> findPossibleStaticLoggerBinderPathSet(a) {
    Set<URL> staticLoggerBinderPathSet = new LinkedHashSet<URL>();
    try {
        ClassLoader loggerFactoryClassLoader = LoggerFactory.class.getClassLoader();
        Enumeration<URL> paths;
        if (loggerFactoryClassLoader == null) {
            paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
        } else {
            paths = loggerFactoryClassLoader.getResources(STATIC_LOGGER_BINDER_PATH);
        }
        while(paths.hasMoreElements()) { URL path = (URL) paths.nextElement(); staticLoggerBinderPathSet.add(path); }}catch (IOException ioe) {
        Util.report("Error getting resources from path", ioe);
    }
    return staticLoggerBinderPathSet;
}
Copy the code

SLF4J integrates with LogBack

  1. Maven dependencies are as follows:

    <! -- slf4j-api -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.12</version>
    </dependency>
    <! -- logback -->
    <dependency> 
        <groupId>ch.qos.logback</groupId> 
        <artifactId>logback-core</artifactId> 
        <version>1.1.3</version> 
    </dependency>
    <! -- logback-classic (already includes slf4J integration package) --> 
    <dependency> 
        <groupId>ch.qos.logback</groupId> 
        <artifactId>logback-classic</artifactId> 
        <version>1.1.3</version> 
    </dependency>
    Copy the code
  2. Write the logback configuration file logback.xml as follows:

    <?xml version="1.0" encoding="UTF-8"? >
    <configuration>
      <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
          <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
      </appender>
      <root level="DEBUG">          
        <appender-ref ref="STDOUT" />
      </root>  
    </configuration>
    Copy the code
  3. use

    private static final Logger logger=LoggerFactory.getLogger(LogbackTest.class);
    public static void main(String[] args){
        if(logger.isDebugEnabled()){
            logger.debug("slf4j-logback debug message");
        }
        if(logger.isInfoEnabled()){
            logger.info("slf4j-logback info message");
        }
        if(logger.isTraceEnabled()){
            logger.trace("slf4j-logback trace message"); }}Copy the code
  4. Org. Slf4j. Impl. StaticLoggerBinder class implements


SLF4J is integrated with Log4

  1. Maven dependencies are as follows:

    <! -- slf4j -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.12</version>
    </dependency>
    
    <! -- slf4j-log4j -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.12</version>
    </dependency>
    
    <! -- log4j -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    Copy the code
  2. Write the log4j.properties configuration file and place it in the classpath

    log4j.rootLogger = debug, console
    log4j.appender.console = org.apache.log4j.ConsoleAppender
    log4j.appender.console.layout = org.apache.log4j.PatternLayout
    log4j.appender.console.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} %m%n
    Copy the code
  3. use

    private static Logger logger=LoggerFactory.getLogger(Log4j2Slf4jTest.class);
    public static void main(String[] args){
        if(logger.isTraceEnabled()){
            logger.trace("slf4j-log4j2 trace message");
        }
        if(logger.isDebugEnabled()){
            logger.debug("slf4j-log4j2 debug message");
        }
        if(logger.isInfoEnabled()){
            logger.info("slf4j-log4j2 info message"); }}Copy the code
  4. Org. Slf4j. Impl. StaticLoggerBinder class implements


The resources

JCL and JUL, log4J1, log4j2, logback integration principle