DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Top Microservices Frameworks
  • How to Debug the Spring Boot Application in Eclipse? [Video]
  • Dependency Injection in Spring
  • Spring Boot - Microservice- JaxRS Jersey - HATEOAS - JerseyTest - Integration

Trending

  • How AI Is Changing the Way Developers Write Code
  • Metrics at a Glance for Production Clusters
  • A Modern Stack for Building Scalable Systems
  • Fraud Detection Using Artificial Intelligence and Machine Learning
  1. DZone
  2. Coding
  3. Frameworks
  4. An Introduction to Logback: a Logging Framework From the Creator of Log4J

An Introduction to Logback: a Logging Framework From the Creator of Log4J

Monitoring, diagnosing, and troubleshooting are key activities in any enterprise application lifecycle, and logging is the core part of these activities. Meet Logback, a logging framework from the creator of Log4J.

By 
John Thompson user avatar
John Thompson
·
Apr. 14, 16 · Analysis
Likes (8)
Comment
Save
Tweet
Share
14.4K Views

Join the DZone community and get the full member experience.

Join For Free
Monitoring, diagnosing, and troubleshooting are key activities in any enterprise application lifecycle, and logging is the core part of these activities. Through logging you get to see what the application code is actually doing during these activities at runtime. Using System.out to print messages to the console is simply not sufficient for enterprise applications. Enterprise applications have logging requirements with varied degree of complexities. You will need generating logs with different levels of importance, such as ERROR, WARN, INFO, and DEBUG. You’ll also have requirements to send logs to different destinations, such as console, file, database, SMTP server, or JMS queue destination. These requirements are not possible with simple System.out statements. Logging frameworks such as Logback are designed to meet the needs of logging in the enterprise.

Logback Architecture

Ceki Gülcü the founder of the Log4J along with Sébastien Pennec, another Log4J contributor, designed logback. With decades of experience with logging frameworks, they designed logback to be fast and generic enough to work under different environments. Logback is comprised of three modules:

  • logback-core: Forms the foundation of logback-classic and logback-access. To perform logging, you need the more specialized logback-classic or logback-access.
  • logback-classic: Relies on logback-core for logging services.
  • logback-access: Provides HTTP-access log functionalities to servlets containers, such as Tomcat and Jetty.

In this post we will explore logback-classic, which in going forward I’ll refer to as logback. Logback natively implements the Simple Logging Facade for Java (SL4J) API. In a nutshell, SL4J is a façade for various logging frameworks. As a developer, you’ll write logging code against the SL4J API. At deployment time, you have the flexibility to plug-in a desired logging framework, made possible through an intermediate SL4J bridge layer. As logback natively implements SL4J, the additional SL4J API layer doesn’t incur any performance overhead, a slight advantage that Logback has over other frameworks.

This figure illustrates the interaction of an application with Logback.

Interaction of a Java application with the Logback logging framework

The key Logback components are loggers, appenders, and encoders/layouts. The components work together to provide the developer full control on how messages are logged, formatted, and where they are reported.

Logger

Loggers are the components that do the heavy work in logging. They capture the logging data and output it to a destination using appenders. The loggers used in an application are typically organized into a hierarchy and a root logger resides at the top of the hierarchy. It is the LoggerContext that is responsible for creating loggers and arranging them in a hierarchy.

Loggers maintain a hierarchical naming rule. As an example, a logger named guru is the parent of the logger named guru.springframework, and the ancestor of the logger named guru.springframework.blog.
 Logger Hierarchy

Apart from logger inheritance, an important logback concept is level inheritance, also referred as effective level. You can assign levels to loggers. Logback supports the TRACE, DEBUG, INFO, WARN, and ERROR levels, as shown in this figure.

Log Levels

As you can see in the figure above, TRACE is the lowest level and the level moves up through, DEBUG, INFO, WARN, until ERROR, the highest level. This means that if you set the logger level to WARN, then only the WARN and ERROR level log messages will be displayed and the rest will be ignored.

In addition to the above levels, there are two special levels:

  • ALL: Turns on all levels.
  • OFF: Turns off all levels.

If a logger is not assigned a level, then level inheritance comes into play. The logger will inherit the level from its nearest ancestor with an assigned level. If none of the application loggers in the hierarchy have assigned a level, the level of the root logger will be inherited. The default level of the root logger is DEBUG.

Note: While developing on your local machine, it is common to set the log level to DEBUG. This will give you detailed log messages for your development use. When deployed to a production environment, it’s typical to set the log level to ERROR. This is to avoid filling your logs with excessive debug information. Also, while logging is very efficient, there is still a cost to system resources.

Appenders

Once you capture logging information through a logger, you need to send it to an output destination. The output destination is called an appender, and it’s attached to the logger. Logback provides appenders for the console, files, remote socket servers, SMTP servers, many popular databases (such as MySQL, PostgreSQL, and Oracle), JMS, remote UNIX Syslog daemons, and more.

Layouts/Encoders

An appender uses a layout to format a log event. A layout, which is an implementation of the Layout interface of logback-core, transforms a log event to a string. A layout can’t control when log events get written out, and therefore can’t group events into batches. To address the limitations of layouts, logback introduced encoders in version 0.9.19. Encoders, which are implementations of the Encoder interface, transform an incoming log event into a byte array and write out the resulting array onto the appropriate output stream. Encoders have total control over the format of the bytes written out. In addition, encoders can control whether (and when) those bytes get written out. I’ll discuss more about layouts and encoders in upcoming posts on logback configuration.

Using Logback

We will start with a simple application that uses Logback for logging. To start with, we need the logback dependencies in our project. Out of the box, both Spring Boot core and web projects include the logback classic dependencies. This figure shows the logback dependencies included in Spring Boot.

Logback Dependencies via Sprint Boot
As shown in the figure above, the latest SpringBoot 1.3.3RELEASE version as of writing this post uses Logback classic 1.1.5.

If you want to use different Logback and SL4J versions or if you are not using SpringBoot, define their dependencies in your Maven POM, like this.

. . .
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.7.21</version>
</dependency>
<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>1.1.7</version>
</dependency>
. . .

In an application, you can retrieve a logger by calling the getLogger() method of the SL4J LoggerFactory class. There are two overloaded getLogger() methods. One returns a Logger instance named according to the string value passed as a parameter. The other returns a Logger instance named corresponding to the class passed as a parameter. The recommended strategy is to use the latter one. This is because in a large application with thousands of log statements, you will find it easy to identify the origin of a log message as the log output bears the name of the generating logger. Once you retrieve a Logger, you can call the log methods on it, like this.

LogbackDemo.java

package guru.springframework.blog.logbackoverview;


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

public class LogbackDemo {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    public void performTask(){
        logger.info("This is an {} message.","info");
        logger.warn("This is a warn message.");
        logger.error("This is an error message.");
        logger.debug("This is a debug message.");
    }
}

In Line 8 of the LogbackDemo class above, we retrieved a Logger object with a call to the static Loggerfactory.getLogger() method. Passing LogbackDemo.class to getLogger() instead of this.getClass() will produce the same result. But I suggest passing this.getClass() to decouple the statement from a particular class, thereby making it reusable across other logging classes. From Line 10 – Line 13, we called the log methods on the retrieved logger. Notice Line 10 that uses parameterized message in the info() method. You can use such parameterized log messages in the other logging methods too.

To test the preceding logger, we will use JUnit. The test class is this.

LogbackDemoTest.java

package guru.springframework.blog.logbackoverview;

import org.junit.Test;

import static org.junit.Assert.*;

public class LogbackDemoTest {

    @Test
    public void testPerformTask() throws Exception {
        LogbackDemo logBackDemo = new LogbackDemo();
        logBackDemo.performTask();
    }
}

When you run the test class, the log messages of LogbackDemo are sent to the console.
 Log Output in Console

Summary

In the example in this post, you may have noticed that I did not specify any appender/encoder or layout for the logger. Rather, I relied upon defaults inherited from the logback root logger. By default, the root logger is associated with the console appender and has the DEBUG level, and our logger inherited both. Therefore, debug and higher log messages were sent to the IntelliJ console. However, in enterprise applications it's likely you’ll work with external configuration files to use more advanced features of Logback. These configuration files can be XML or Groovy to specify Logback configuration options. In upcoming posts, I’ll discuss using both XML and Groovy external configuration files to help you explore what a powerful logging tool Logback is.

Framework application Log4j Spring Framework Debug (command) Creator (software)

Published at DZone with permission of John Thompson, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Top Microservices Frameworks
  • How to Debug the Spring Boot Application in Eclipse? [Video]
  • Dependency Injection in Spring
  • Spring Boot - Microservice- JaxRS Jersey - HATEOAS - JerseyTest - Integration

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!