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 !!
Leave a Reply