๐Ÿ”ฐ for beginner

As a Java developer, you have noticed the code like

logger.info("user added in database : " + user.getUserId());

Such lines are responsible to write logs from your application, which you normally find in the log files which are created on the servers where you run your application.

๐Ÿ“˜ Normally the classes you use in your applications to log the information come from the thing called logging facade or logging API.

commons-logging, SLF4J, log4j-api are various logging facade or logging APIs not the actual logging framework. โฌ

๐Ÿ“™ And the thing which is responsible to write your logs into the log file is called as logging implementation or logging framework.

While log4j-core, logback, java.util.logging(JUL) are logging frameworks or logging implementations. โฌ

Logging APIs in Java

While logging frameworks provide extensive logging capabilities, there are also logging APIs that serve as bridges or facades, allowing developers to abstract away the underlying logging implementation. This section explores three notable logging APIs in the Java ecosystem.

๐ŸŽ Please focus on the import statements.

1. Commons Logging

Commons Logging is an abstraction layer for logging in Java that provides a simple interface while allowing developers to choose their preferred logging implementation. It’s often used in Apache projects.

๐Ÿ”– Spring framework uses commons-logging.

Implementation Example:

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class MyClass {
    private static final Log logger = 
        LogFactory.getLog(MyClass.class);

    public void performAction() {
        logger.info("Performing action...");
    }
}

2. SLF4J (Simple Logging Facade for Java)

SLF4J serves as a simple and efficient logging facade for various logging frameworks, including Logback, Log4j, and java.util.logging. It allows developers to switch between logging implementations easily.

๐ŸŽฌ SLF4J is default logging API for logback framework.

Implementation Example:

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

public class MyClass {
    private static final Logger logger = 
        LoggerFactory.getLogger(MyClass.class);

    public void performAction() {
        logger.info("Performing action...");
    }
}

3. Log4j API

Log4j API is a logging API designed to work seamlessly with different logging frameworks, providing a flexible and extensible approach to logging. Though log4J is implementation but that is written in log4j-core while log4j-api is a facade or API library. You can use any logging framework with log4j-api, like log4j-core or you can send logs from log4j-api to aother facade like slf4j.

Implementation Example:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class MyClass {
    private static final Logger logger = 
        LogManager.getLogger(MyClass.class);

    public void performAction() {
        logger.info("Performing action...");
    }
}

Logging Implementations in Java:

Java applications leverage various logging implementations to record runtime events, errors, and performance metrics. This section explores three prominent logging implementations: java.util.logging, Log4j, and Logback.

1. java.util.logging (JUL):

Java’s built-in logging facility, JUL, is part of the Java standard library. It provides a simple and lightweight logging API, making it a natural choice for many Java applications. However, some developers find it lacking in advanced features compared to dedicated logging frameworks.

Implementation Example:

import java.util.logging.Logger;

public class MyClass {
    private static final Logger logger = 
    Logger.getLogger(MyClass.class.getName());

    public void performAction() {
        logger.info("Performing action...");
    }
}

2. Log4j:

Log4j is a robust logging framework that has been widely adopted in the Java ecosystem. Known for its configurability and flexibility, Log4j allows developers to fine-tune logging behaviors and outputs according to their application’s requirements.

When here we talk about log4j, we talk about org.apache.logging.log4j with version 2.x.x, but not log4j.log4j which was predecessor of apache Log4j version 2 also called as log4j2.

Configuration Example:

<!-- log4j.xml -->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-5p %c{1} - %m%n"/>
        </layout>
    </appender>

    <root>
        <priority value="debug"/>
        <appender-ref ref="console"/>
    </root>

</log4j:configuration>

3. Logback:

Logback, developed as a successor to Log4j, offers improved features and performance. It is designed to be backward-compatible with Log4j while providing a more efficient and flexible logging solution. Logback incorporates SLF4J, a simple logging facade for Java.

logback uses similar setup like log4j however instead of writing logback-api, it relies on slf4j-api but it has its own core logback-core. Both logback-core and slf4j-api will be pulled together into your project if you use logback-classic dependency.

Configuration Example:

<!-- logback.xml -->
<configuration>

    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%-5p %c{1} - %m%n</pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="console"/>
    </root>

</configuration>

Which Logging API and Logging Framework to choose

๐ŸŽด Logging APIs in Java provide a layer of abstraction that enables developers to write log statements without being tied to a specific logging implementation. Whether it’s the simplicity of Commons Logging, the flexibility of SLF4J, or the compatibility of Log4j API, these logging APIs empower developers to choose the logging approach that best fits their application’s needs. Understanding these APIs is crucial for seamlessly integrating logging into Java applications and facilitating efficient log management and analysis.

๐ŸŽด Selecting the right logging implementation for a Java application involves considering factors such as ease of use, configurability, performance, and community support. Whether opting for the simplicity of java.util.logging, the configurability of Log4j, or the performance improvements offered by Logback, developers can tailor their logging strategy to match the specific needs of their projects. Understanding the key aspects of these logging implementations empowers developers to make informed decisions and implement effective logging solutions in their Java applications.

Things to consider

  • ๐Ÿฉ When you write a library, use facade becuase you don’t know that the application which is going to use your library, what logging framework that application is going to use at runtime.

  • ๐Ÿฉ Though applications use actual framework to write their logs in log files, and framework like log4j bring their facade api with the implementation library then it doesn’t mean you use the facade api of log4j which is log4j-api, you are free to use any facade like SLF4J, commons-logging etc. This makes changing the logging framework easy in the future.

  • ๐Ÿฉ A perticular logging framework can’t work with all the logging facade. But developers of facade and logging framework created bridges to have inter-operatibility between popular logging facade and logging frameworks. So that they can work with each other.

SLF4J Bridge

Now you saw that SLF4J API is widely accepted by the implementations hence you prefer SLF4J while writing the logs in your application. But it is possible that the libraries you are using in your application, are using other APIs like commons logging or log4j-api. In such cases, SLF4J has created brifges to pull the logs from all those different API logs.

More details here. https://www.slf4j.org/legacy.html