Setting Up SLF4J with Logback, Log4j2 and JUL

SLF4J (Simple Logging Facade for Java) is a simple facade or abstraction for various logging frameworks, such as Java Util Logging (JUL), Logback and Log4j2. We use the abstract SLF4J API in the application, and later we can plug in any desired logging framework as underlying implementation.

Using SLF4J helps in migrating from one logging framework to another, just by replacing the configuration files. The application code is untouched.

In this SLF4J tutorial, we will learn to use various logging frameworks with SLF4J.

1. SLF4J Dependency and API

Note that the only mandatory dependency for using the SLF4J API is slf4j-api. Other dependencies are logging framework-specific, so we will be importing different dependencies for different logging framework integration.

  • If no binding is found on the classpath, then SLF4J will default to a no-operation implementation. It means that no logging will happen in runtime.
  • Since version 2.0.0, SLF4J requires Java 8 and introduces a backward-compatible fluent logging API. The fluent API through SLF4j works with all existing logging frameworks.
  • If we are using Spring boot starter spring-boot-starter-logging configures SLF4J with Logback.
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-api</artifactId>
	<version>${slf4j-api-version}</version>
</dependency>

To log messages in the classes, we need to use Logger and LoggerFactory from the org.slf4j package.

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

//Create Logger
Logger logger = LoggerFactory.getLogger(Main.class);

//Log messages
logger.info("Info Message Logged !!!");

2. Configuring Logback with SLF4J

To use Logback, include logback-classic dependency. Note that logback-classic transitively includes the slf4j-api and logback-core, so only having the logback-classic is enough to setup logback with slf4j.

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>${logback-classic-version}</version>
</dependency>

When using Logback with SLF4j, a console appender with DEBUG log level is configured automatically. For custom logback configuration, we need to create logback.xml file and place it in the classpath.

<configuration debug="true">
  <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>

3. Configuring Log4j2 with SLF4J

To make Log4j2 work with SLF4J, we need to include three dependencies.

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>${log4j2-version}</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>${log4j2-version}</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>${log4j2-version}</version>
</dependency>

Next, we need to provide a log4j2.properties, log4j2.xml or log4j2.json file which will configure the required loggers and appenders.

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30">
    <Properties>
        <Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n</Property>
    </Properties>
 
    <Appenders>
        <Console name="console" target="SYSTEM_OUT" follow="true">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </Console>
    </Appenders>
 
    <Loggers>
        <Root level="info">
            <AppenderRef ref="console"/>
        </Root>
    </Loggers>
</Configuration>

4. Configuring Java Util Logging with SLF4J

To use the JUL as a logging implementation, we need to import slf4j-jdk14 dependency.

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-jdk14</artifactId>
    <version>${jul-version}</version>
</dependency>

Note that JUL logging default loads logging.properties from the $JAVA_HOME/jre/lib/ (Java 8 and before); for Java 9 and above, the logging.properties file moved to $JAVA_HOME/conf.

A sample configuration file is:

# Logging handlers
handlers = java.util.logging.FileHandler, java.util.logging.ConsoleHandler

# Default global logging level
.level = ALL

# File Logging
# default file output is in user's home directory
java.util.logging.FileHandler.pattern = %h/myApp.log
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.FileHandler.level = INFO

# Console Logging
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

5. Conclusion

Using SLF4J abstract logging API is a highly recommended way to implement the logging in Java applications. It frees the developers from creating tight coupling between the application code and the logging framework.

SLF4J provides other benefits as well. For example, fluent API support, more readable log messages using variable substitution in place of string concatenation. This helps in improving the performance of the overall logging in the application.

Happy Learning !!

Was this post helpful?

Join 8000+ Awesome Developers, Like YOU!

Leave a Comment

About HowToDoInJava

This blog provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions, and frequently asked interview questions.

Our Blogs

REST API Tutorial