Spring Boot Logging with Lombok

Project lombok can also be used to configure logging in spring boot applications and thus removing the boilerplate code for getting the logger instance.

Project Lombok is a very handy tool for removing the boilerplate code from the application. Lombok can also be used to configure logging in spring boot applications and thus remove the boilerplate code for getting the logger instance.

1. Setting Up Lombok with Spring Boot

Before using Lombok annotations, we must include lombok dependency in the Spring boot application. We may be required to enable the annotation processing in the IDEs such as installing Lombok into eclipse. IntelliJ automatically detects and configures lombok for us.

<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <optional>true</optional>
</dependency>

<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <configuration>
        <excludes>
          <exclude>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
          </exclude>
        </excludes>
      </configuration>
    </plugin>
  </plugins>
</build>

If we are creating a new project then we can choose Lombok in Spring Initializr page itself.

2. @Log, @Log4j2 and @Slf4j Annotations

Lombok supports the following annotations for logging statements in a spring boot application. These annotations let Lombok generate a logger field in the runtime. The logger name is always log and the field’s type depends on which logger you have selected.

@CommonsLog – Creates the logger that logs using the Apache Commons Log API. The internally generated logger is:

private static final org.apache.commons.logging.Log log = 
    org.apache.commons.logging.LogFactory.getLog(MyClass.class);

@Flogger – Uses Google’s FluentLogger API for logging. The internally generated logger is:

private static final com.google.common.flogger.FluentLogger log = 
    com.google.common.flogger.FluentLogger.forEnclosingClass();

@Log – Uses Java Util Logging API for logging. The internally generated logger is:

private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(MyClass.class.getName());

@Log4j2 – Uses Log4j2 API for logging. The internally generated logger is:

private static final org.apache.logging.log4j.Logger log = 
    org.apache.logging.log4j.LogManager.getLogger(MyClass.class);

@Slf4j – Uses SLF4j’s abstraction API and the logger library available on runtime for logging. The internally generated logger is:

private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(MyClass.class);

To use any logger in a class, annotate the class with one of the above annotations and use the log for logging statements.

@Slf4j
public class Main {
  
  public static void main(String... args) {
    log.info("App is started!");
  }
}

3. Using Log4j2 with Lombok

As we know spring boot uses logback as the default logging provider. To use log4j2, exclude logback from the classpath and include log4j2.

<dependencies>
 
  <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-log4j2</artifactId>
  </dependency>
 
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
  </dependency>
 
</dependencies>

As a best practice, we can use either @Slf4j (recommended) or @Log4j2 as underlying logging implementation.

Happy Learning !!

Leave a Comment

    • In my knowledge, Lombok itself doesn’t provide direct mechanisms to prevent log forging. If there is anything you can share how you are preventing it, it will be great for all of us.

      Reply
  1. Hi,
    I am using Log4j2 logging with Lombok. Using the same exclusion and dependency addition method, but the issue I am facing is deletion of logs. When have excluded the default logback, why are the logs getting deleted after 7 days. I want to stop this log deletion without specifying any weird value in “logging.file.max.history”.
    Please suggest a solution.

    Reply
    • Keep in mind that Lombok has nothing to do with log creation or deletion. It is simply an easy way to create a Logger class instance. Now, what’s in your log4j2 configuration file? Can you share?

      Reply
      • Yes, I am aware that lombok creates no impact, but Spring’s default logging spring-boot-starter-logging does. So I excluded it and included these :
        <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
        </dependency>

        <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>

        Apart from this, I haven’t created any log4j configuration file.

        Reply
        • Strange because default logging outputs the logs only to the console. There should not be any file logging. There must be a log configuration file in the application classpath that is configuring the file appender. Try to search for all XML and properties files in the project folder. What is the location of file logs?

          Reply
          • For file logging, have added below to application.properties :
            logging.file.name=logs/<fileName>.log
            logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
            logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

            File logs are in ‘logs’ directory of parent directory (where the jar is present)

          • As per my 1st and initial comment, I do not wish to use this property and assign any weird no. of days to it. My question goes again, when I have excluded default logging of spring and have included log4j dependency, why do I need to set this property explicitly? Is there no other way to retain logs for ever in SpringBoot without setting this property?

  2. Hello,
    Thank you! This is simple and good. I have a question on this, I understand that SLF4J is an abstraction and does not provide the implementation. So if you are using spring-boot logback provider with Lombok SLF4J logging then which implementation of log4j is used here? I mean to ask which logging jar files are used internally by the SLF4J? How do I know and how do I check it?
    I also did see in my maven repo there is a log4j-1.2*.jar file which seems an older version, how can I upgrade it to the latest version, it’s very weird since I do not have the log4j** mapping in my pom.xml and I am assuming that the Lombok SLF4J is referring this internally.

    Reply
  3. Thank you for the nice overview of logging in Spring Boot. Could you let us know about your opinion on log4j vs logback as the underlying loggin provider?

    Reply
    • Interestingly, one person is behind all three logging solutions (log4j, logback, and SLF4j). You will not see any difference in terms of performance because all work asynchronously and at the same level in OS.

      You can choose any of log4j2 or logback, based on your comfort level with the configuration syntax.

      Reply
  4. How to deal with test coverage and stuff like:

    if (log.isDebugEnabled()) {
       log.debug("Something!");
    }
    

    in my sonar checks I get: Branches should have sufficient coverage by tests. It means that my if is not part of the coverage.

    Regards

    Alfredo

    Reply
  5. Hello Lokesh
    Thank you very much with your fantastic documentation!
    A simple question, but I expect it could be with a difficult answer :-)

    I am just learning and I am not sure, but I assume slf4j is the base for both, but the logger itself is an other library.
    Which are the parameter which will help to decide if I should use “lombok.extern.slf4j.Slf4j;” or “org.slf4j.Logger;” ?
    Thank you in advance
    rgds OpaHeinz

    Reply

Leave a Comment

About Us

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

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