Using SLF4J/JUL with Log4j in Spring Boot

[Updated: Oct 4, 2017, Created: Oct 2, 2017]

This example shows how to use SLF4J API or JUL (Java Util Logging) API with Log4j implementation in a Spring Boot application.

Example

pom.xml dependencies

Since for Log4j, we don't have a starter like spring-boot-starter-log4j2 (last example), we have to step up dependencies ourselves:

pom.xml

<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.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>1.8.0-alpha2</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jul-to-slf4j</artifactId>
        <version>1.8.0-alpha2</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.8.0-alpha2</version>
    </dependency>
</dependencies>

Using SLF4J API

package com.logicbig.example;

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

@Component
public class MyBean {
  private static final Logger logger = LoggerFactory.getLogger(MyBean.class.getName());

  public void doSomething() {
      logger.info("some message using SLF4J API");
  }
}

Using JUL API

We are also using JUL API with Log4J implementation. This is only for demo purpose, in real application we are likely to use only one API.

package com.logicbig.example;

import org.springframework.stereotype.Component;

import java.util.logging.Logger;

@Component
public class MyBean2 {
  private static final Logger logger = java.util.logging.Logger.getLogger(MyBean2.class.getName());

  public void doSomething() {
      logger.info("some message using JUL API");
  }
}

Log4j configuration

src/main/resources/log4j.properties

log4j.rootCategory=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%d{yy-MMM-dd E HH:mm:ss:SSS}] [%p] [%c{2}:%L] - %m%n

Boot properties

src/main/resources/application.properties

spring.main.banner-mode=off 

The Main class

@SpringBootApplication
public class ExampleMain {
  public static void main(String[] args) throws InterruptedException {
      ConfigurableApplicationContext context =
              SpringApplication.run(ExampleMain.class, args);

      //MyBean using SLF4J API
      MyBean bean = context.getBean(MyBean.class);
      bean.doSomething();

      ///installing JUL bridge
      LogManager.getLogManager().reset();
      SLF4JBridgeHandler.install();
      //MyBean2 using JUL API
      MyBean2 bean2 = context.getBean(MyBean2.class);
      bean2.doSomething();
  }
}

Output

[17-Oct-02 Mon 10:48:27:477] [INFO] [example.ExampleMain:48] - Starting ExampleMain on JoeMchn with PID 13448 (D:\LogicBig\example-projects\spring-boot\boot-log4j-logging\target\classes started by Joe in D:\LogicBig\example-projects\spring-boot\boot-log4j-logging)
[17-Oct-02 Mon 10:48:27:479] [INFO] [example.ExampleMain:593] - No active profile set, falling back to default profiles: default
[17-Oct-02 Mon 10:48:27:937] [INFO] [annotation.AnnotationMBeanExporter:431] - Registering beans for JMX exposure on startup
[17-Oct-02 Mon 10:48:27:947] [INFO] [example.ExampleMain:57] - Started ExampleMain in 0.684 seconds (JVM running for 3.994)
[17-Oct-02 Mon 10:48:27:948] [INFO] [example.MyBean:13] - some message using SLF4J API
[17-Oct-02 Mon 10:48:27:950] [INFO] [example.MyBean2:13] - some message using JUL API
[17-Oct-02 Mon 10:48:28:059] [INFO] [annotation.AnnotationMBeanExporter:449] - Unregistering JMX-exposed beans on shutdown

In the main class above, we used SLF4JBridgeHandler which is an implementation of java.util.logging.Handler. It was needed to install the jul-to-slf4j bridge. Note that in case of Logback or Log4j2 we don't have to install this bridge ourselves as it is done by their LoggingSystem implementation during the initialization.

Example Project

Dependencies and Technologies Used :

  • spring-boot-starter 1.5.6.RELEASE: Core starter, including auto-configuration support, logging and YAML.
    Corresponding Spring version: 4.3.10.RELEASE
  • jcl-over-slf4j 1.8.0-alpha2: JCL 1.2 implemented over SLF4J.
  • jul-to-slf4j 1.8.0-alpha2: JUL to SLF4J bridge.
  • slf4j-log4j12 1.8.0-alpha2: SLF4J LOG4J-12 Binding.
  • JDK 1.8
  • Maven 3.3.9

Spring Boot with Log4j Example Select All Download
  • boot-log4j-logging
    • src
      • main
        • java
          • com
            • logicbig
              • example
        • resources

See Also