Spring Boot 2 Logging SLF4j Logback and LOG4j2 Example


In this article, we learn how to log effectively with Spring Boot. We will look at Spring Boot Starter for Logging. We will look at the defaults in Spring Boot for Logging - Logback, and SLF4J. We will also be looking at the Spring Boot starter for log4j2.
First, we will discuss a few important points about Spring Boot logging feature and then we will create a simple example to demonstrate the same.

Spring Boot 2 Logging Feature Overview

Logging is a very important part of any application and it helps with debugging issues. Spring Boot, by default, includes spring-boot-starter-logging as a transitive dependency for the spring-boot-starter module. By default, Spring Boot includes SLF4J along with Logback implementations.
If Logback is available, Spring Boot will choose it as the logging handler. You can easily configure logging levels within the application.properties file without having to create logging provider-specific configuration files such as logback.xml or log4j.properties.
logging.level.org.springframework.web=INFO
logging.level.org.hibernate=ERROR
logging.level.net.guides=DEBUG
If you want to log the data into a file in addition to the console, specify the filename as follows
logging.path=/var/logs/app.log
or
logging.file=myapp.log
If you want to have more control over the logging configuration, create the logging provider-specific configuration files in their default locations, which Spring Boot will automatically use.
For example, if you place the logback.xml file in the root classpath, Spring Boot will automatically use it to configure the logging system

The logback.xml File

<configuration>
    <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>
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>app.log</file>
        <encoder>
            <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n </pattern>
        </encoder>
    </appender>
    <logger name="com.apress" level="DEBUG" additivity="false">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
    </logger>
    <root level="INFO">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
    </root>
</configuration>

Using Log4j2 for logging with Spring Boot

If you want to use other logging libraries, such as Log4J or Log4j2, instead of Logback, you can exclude spring-boot-starter-logging and include the respective logging starter, as follows:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j</artifactId>
</dependency>
Now you can add the log4j.properties file to the root classpath, which Spring Boot will automatically use for logging.

Log Format

The default log output from Spring Boot resembles the following example:
2014-03-05 10:57:51.112  INFO 45469 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.52
2014-03-05 10:57:51.253  INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2014-03-05 10:57:51.253  INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1358 ms
2014-03-05 10:57:51.698  INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
2014-03-05 10:57:51.702  INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
The following items are output:
  • Date and Time: Millisecond precision and easily sortable.
  • Log Level: ERROR, WARN, INFO, DEBUG, or TRACE.
  • Process ID.
  • A --- separator to distinguish the start of actual log messages.
  • Thread name: Enclosed in square brackets (may be truncated for console output).
  • Logger name: This is usually the source class name (often abbreviated).
  • The log message.

Console Output

The default log configuration echoes messages to the console as they are written. By default, ERROR-level, WARN-level, and INFO-level messages are logged. You can also enable a “debug” mode by starting your application with a --debug flag.
$ java -jar myapp.jar --debug
You can also specify debug=true in your application.properties.

File Output

By default, Spring Boot logs only to the console and does not write log files. If you want to write log files in addition to the console output, you need to set a logging.file or logging.path property (for example, in your application.properties).
So far we understood, how logging works in Spring Boot and default configurations. Now it's time to use Spring Boot 2 logging feature in our project so let's create an example to demonstrate how to use Spring Boot 2 logging feature.

Simple Spring Boot 2 logging Application

Let's develop a simple in-memory Spring Boot 2 logging application.

1. Creating and Importing a Project

There are many ways to create a Spring Boot application. The simplest way is to use Spring Initializr at http://start.spring.io/, which is an online Spring Boot application generator.
Look at the above diagram, we have specified the following details:
  • Generate: Maven Project
  • Java Version: 1.8 (Default)
  • Spring Boot:2.0.4
  • Group: net.guides.springboot2
  • Artifact: springboot2-logging
  • Name: springboot2-logging
  • Package Name : net.guides.springboot2.springboot2-logging
  • Packaging: jar (This is the default value)
  • Dependencies: Web
Once, all the details are entered, click on Generate Project button will generate a spring boot project and downloads it. Next, Unzip the downloaded zip file and import it into your favorite IDE.

2. Packaging Structure

Once we will import generated spring boot project in IDE, we will see some auto-generated files. Refer above diagram for project structure.

3. The pom.xml File

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

    <groupId>net.guides.springboot2</groupId>
    <artifactId>springboot2-logging</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>springboot2-logging</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>  
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency> 
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

4. The Springboot2LoggingApplication.java File

This class provides an entry point with the public static void main(String[] args) method, which you can run to start the application.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Springboot2LoggingApplication {
    public static void main(String[] args) {
        SpringApplication.run(Springboot2LoggingApplication.class, args);
    }
}

5. Create Simple POJO Class - Article.java

package net.guides.springboot2.springboot2logging;

public class Article {
    private int id;
    private String name;
 
 
    public Article(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
 
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

6. Create Simple Service Class - ArticleService.java

package net.guides.springboot2.springboot2logging;

import java.util.Arrays;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class ArticleService {
    private static final Logger logger = LoggerFactory.getLogger(ArticleService.class);
    public List<Article> getArticles(){
        logger.debug("inside getArticles() method");
        return Arrays.asList(new Article(100, "article"),new Article(200, "article2"));
    }
}
Note that we have added slf4j Logger and also added debug statements.
private static final Logger logger = LoggerFactory.getLogger(ArticleService.class);

7. Create Simple Rest Controller - ArticleController.java

package net.guides.springboot2.springboot2logging;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ArticleController {
    private static final Logger logger = LoggerFactory.getLogger(ArticleService.class);
    @Autowired
    private ArticleService articleService;
    @GetMapping("/articles")
    public List<Article> getArticles() {
        logger.debug("inside ArticleController.getArticles() method");
        return articleService.getArticles();
    }
}
Note that we have added slf4j Logger and also added debug statements. These debug statements printed in a console:

8. The application.properties File

Let's configure logging properties in an application.properties file. Open an application.properties file and add following logging configuration to it.
logging.level.org.springframework.web=INFO
logging.level.org.hibernate=ERROR
logging.level.net.guides=DEBUG

logging.file=myapp.log

9. Running an Application

Now run Springboot2LoggingApplication.java as a Java application. Call REST API: http://localhost:8080/articles. You should see the list of articles in a JSON format.
[{"id":100,"name":"article"},{"id":200,"name":"article2"}]
Note that myapp.log file is created at your correct project location.


Reference

Comments