Saturday, December 11, 2021

SLF4J - Simple Logging Facade for Java | How to identify which logging library SLF4J using for logging?

The Simple Logging Façade for Java (SLF4J) serves as a simple façade 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. It enables a generic API making the logging independent of the actual implementation.

SimpleLogger(org.slf4j.simple.SimpleLoggerFactory) - sends all log messages to the console using the “standard” error output stream (System.err).

NOPLogger(org.slf4j.helpers.NOPLoggerFactory) - All logging will be silently discarded. Starting with version 1.6.0, if no binding(logger implementation) is found on the classpath, this one will be used by default. 

SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See for further details.

Log4j(org.slf4j.log4j12.Log4jLoggerFactory/org.apache.logging.slf4j.Log4jLogger) - A wrapper over the Log4j 1.2.2 Logger's

Java Util Logging(org.slf4j.jul.JDK14LoggerFactory) - wrapper for the Java Util Logging logger

Logback Logging Framework(ch.qos.logback.classic.LoggerContext) - Wrapper for Logback Logging Framework


SLF4J API Dependency:


Implementation Dependencies:



The logger configuration can be enabled by adding "" file to the class path(src/main/resources)


Log4j 1.2:


While enabling Log4j logging Framework, the log4j.proerties should be added into the classpath(src/main/resources), sample log4j file

log4j.rootLogger=info, stdout
log4j.appender.stdout.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

Log4j 2:

<!-- SLF4J Bridge -->

In this case remove SLF4J API dependency(slf4j-api) - only add the above dependency 

While enabling Log4j 2 logging Framework, the log4j2.xml should be added into the classpath(src/main/resources), sample log4j2.xml file


<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
        <Console name="console" target="SYSTEM_OUT">
                pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" />
        <Root level="debug" additivity="false">
            <AppenderRef ref="console" />

Java Util Logging:


The default logger configuration is available in $JAVA_HOME/conf/, custom can be enabled if required(there are multiple ways to load the custom - JVM parameter -, System.setProperty("java.util.logging.config.file", ""); etc)

handlers= java.util.logging.ConsoleHandler
.level= INFO
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter


Logback Logging Framework


The logger configuration can be enabled by adding "logback.xml" file to the class path(src/main/resources)

<appender name="CONSOLE"
<layout class="ch.qos.logback.classic.PatternLayout">
%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n

<logger name="com.demo" level="debug" additivity="false">
<appender-ref ref="CONSOLE" />

<root level="error">
<appender-ref ref="CONSOLE" />

Ensure only one implementation is enabled to the project, the latest SLF4J versions use the first implementation loaded as the actual implementation.

SLF4J: Class path contains multiple SLF4J providers.
SLF4J: Found provider [[email protected]]
SLF4J: Found provider [[email protected]]
SLF4J: Found provider [[email protected]]
SLF4J: Found provider [[email protected]]
SLF4J: See for an explanation.
SLF4J: Actual provider is of type [ch.qos.logback.clas[email protected]]

Some of the time, we may have the use case to identify the logging implementation SLF4J is using to log the messages, this can be easily identified by looking into the logger implementation dependency added to the project. But sometimes the dependencies may come from external projects, the below APIs can be used to identify the same.

org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(Application.class);

Output - class org.slf4j.simple.SimpleLogger



Output - ch.qos.logback.classic.LoggerContext


In earlier versions, even the below API is supported


Output - ch.qos.logback.classic.LoggerContext[default]

Sample Java Class:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Sample {

private static final Logger log = LoggerFactory.getLogger(VulnerableLog4jExampleHandlerLocal.class);

public static void main(String[] args) {"test");;;

No comments:

Post a Comment