8

I am trying to use log4j2 instead of logback in my spring application but it keep throwing error. The pom file looks like

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.7.RELEASE</version>
    <relativePath /> 
</parent>

<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-web</artifactId>
    </dependency>

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

The log4j2 xml files looks like

<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="60">
    <Properties>
        <Property name="path">logs</Property>
    </Properties>
    <Appenders>
        <Console name="Console-Appender" target="SYSTEM_OUT">
            <PatternLayout>
                <pattern>
                    [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
                </pattern>>
            </PatternLayout>
        </Console>
        <File name="App-Appender" fileName="${path}/app_log.log" >
            <PatternLayout>
                <pattern>
                    [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
                </pattern>
            </PatternLayout>
        </File>
        <File name="SpringBoot-Appender" fileName="${path}/springboot_log.log" >
            <PatternLayout>
                <pattern>
                    [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
                </pattern>
            </PatternLayout>
        </File>
    </Appenders>
    <Loggers>
        <Logger name="master.dt" level="info" additivity="false">
            <AppenderRef ref="SpringBoot-Appender"/>
            <AppenderRef ref="Console-Appender"/>
        </Logger>
        <Logger name="master.dt" level="info" additivity="false">
            <AppenderRef ref="App-Appender"/>
            <AppenderRef ref="Console-Appender"/>
         </Logger>
        <Root>
            <AppenderRef ref="Console-Appender"/>
        </Root>
    </Loggers>
</Configuration>

however when i run the spring boot app it throws an error

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/Users/asd.asd/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.6.2/log4j-slf4j-impl-2.6.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/asd.asd/.m2/repository/ch/qos/logback/logback-classic/1.1.7/logback-classic-1.1.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
[WARNING] 
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:483)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.apache.logging.slf4j.Log4jLoggerFactory loaded from file:/Users/karan.shah/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.6.2/log4j-slf4j-impl-2.6.2.jar). If you are using WebLogic you will need to add 'org.slf4j' to prefer-application-packages in WEB-INF/weblogic.xml Object of class [org.apache.logging.slf4j.Log4jLoggerFactory] must be an instance of class ch.qos.logback.classic.LoggerContext
    at org.springframework.util.Assert.isInstanceOf(Assert.java:346)
    at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLoggerContext(LogbackLoggingSystem.java:221)
    at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLogger(LogbackLoggingSystem.java:213)
    at org.springframework.boot.logging.logback.LogbackLoggingSystem.beforeInitialize(LogbackLoggingSystem.java:98)
    at org.springframework.boot.logging.LoggingApplicationListener.onApplicationStartedEvent(LoggingApplicationListener.java:222)

I followed multiple blog but none of them are working. What is the correct way to get log4j2 work?

7 Answers 7

11

Exclude the default spring boot starter logging dependency from spring boot starter web dependency also.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
      <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
Sign up to request clarification or add additional context in comments.

1 Comment

from the tutorial, spring default not using log library except for Logback, to use log4j2 need to first exclude Logback from our dependencies,so I choose to use Logback in spring, which is default.
3

I faced this issue in Microservice based project which is based on many services. Because of lot of conflicts between log4j, slf4j , apache common logging etc. Hence log files is not creating even sufficient privileged are there. First run command to resolved the jar conflict from dependency tree.

**mvn dependency:tree**
Exclude those jars from spring-boot starter dependencies and other component dependencies.

Following Code is perfectly working for me after lot of struggle.

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</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>

****Log4j.xml files:****

        <?xml version="1.0" encoding="UTF-8"?>
        <Configuration>
            <Appenders>
                <Console name="Console" target="SYSTEM_OUT">
                    <PatternLayout
                        pattern="%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable" />
                </Console>

                <RollingFile name="RollingFile"
                    fileName="./logs/gateway-log4j2.log"
                    filePattern="./logs/$${date:yyyy-MM}/spring-boot-logger-log4j2-%d{-dd-MMMM-yyyy}-%i.log.gz">
                    <PatternLayout>
                        <pattern>%d %p %C{1.} [%t] %m%n</pattern>
                    </PatternLayout>
                    <Policies>
                        <!-- rollover on startup, daily and when the file reaches 
                            10 MegaBytes -->
                        <OnStartupTriggeringPolicy />
                        <SizeBasedTriggeringPolicy
                            size="10 MB" />
                        <TimeBasedTriggeringPolicy />
                    </Policies>
                </RollingFile>
            </Appenders>

            <Loggers>
                <!-- LOG everything at INFO level -->
                <Root level="info">
                    <AppenderRef ref="Console" />
                    <AppenderRef ref="RollingFile" />
                </Root>

                <!-- LOG "com.mytest.project*" at TRACE level -->
                <Logger name="com.mytest.project" level="trace"></Logger>
            </Loggers>

        </Configuration>

        Try it. It perfectly working for me.

Comments

1

You have a jar conflict with slf4j. Look at your dependency tree to figure out which jar to exclude.

Comments

0

This problem like me mad for an hour. There are very less probability that you might be having any issue with log4j2.xml or log4j2-spring.xml. Most likely problem is in your pom.

I would suggest to run mvn:dependeny:tree and exclude spring-boot-starter-logging from all the dependencies in your class path.

        <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-web</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>

I hope this would help. No need to explicitly give logging config file location in application.properties unless it is outside your project classpath.

Comments

0

You put a double ending bracket in the Console layout definition in your log4j.xml file : it should be corrected first.

1 Comment

This should not be an answer as it doesn't address the question, you should have added that as a comment to the question, so the person who asked the question would update it.
0

For Spring Boot 3

If you are using "spring-boot-starter-web" then you need to exclude default logging

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

If you are using "spring-boot-starter-security" then you need to exclude default logging

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>

        </dependency>

After excluding starter logging from web and security, Log4j2 configuration is working..

1 Comment

If you exclude the dependency from spring-boot-starter, you don't need to exclude it from all the other starters.
0

Check for duplicate dependencies and add below code in your pom.xml.

Configure Log4j for Logging

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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>

Also check for this configuration

Spring Boot provides a number of logback configurations that be included from your own configuration. These includes are designed to allow certain common Spring Boot conventions to be re-applied

A typical custom logback.xml file would look something like this:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/default.xml"/>
    <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
    </root>
    <logger name="org.springframework.web" level="DEBUG"/>
</configuration>

Configure Logback for File-only Output

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
    <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
    <include resource="org/springframework/boot/logging/logback/file-appender.xml" />
    <root level="INFO">
        <appender-ref ref="FILE" />
    </root>
</configuration>

You also need to add logging.file to your application.properties, as shown in the following example:

logging.file=myapplication.log

Check this tutorial for reference https://docs.spring.io/spring-boot/docs/2.1.8.RELEASE/reference/html/howto-logging.html

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.