Spring Boot与Log4j2集成之java.lang.IllegalStateException: Logback configuration error detected:

原创 2017年09月27日 11:54:23

引言: 一个问题的分析与解决过程是表与里的过程,是一个大胆猜测与小心求证的过程,spring boot与log4j2的集成过程中,我将描述一下分析这个问题的思路和过程。 我一直强调一点: 重要的不是解决问题的结论,而是解决问题的思路和方法,即使在解决完问题之后,依然需要回过头复盘,在问题分析过程中的走过的弯路。

1 项目情况介绍

Spring Boot 1.5.7 , JDK 1.8, Log4j2.7
在这个项目中,希望集成Log4j2作为默认的日志系统输出器。
Log4j2.xml的定义如下:

"><Configuration status="off">
    <Properties>
        <Property name="LOG_PATH">.</Property>
    </Properties>
    <Appenders>
        <!-- Console -->
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %logger{36}.%M@%L - %msg%n"/>
            <!--<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %C{5} (%F:%L) - %msg%n"/>-->
        </Console>
        <!-- RollingFile -->
        <RollingRandomAccessFile name="RollingFile"
                                 fileName="./aifasion.log"
                                 filePattern="${LOG_PATH}/aifasion.log.%d{yyyy-MM-dd-HH}">
            <PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{36}.%M@%L - %msg%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
            </Policies>
            <DefaultRolloverStrategy max="30"/>
        </RollingRandomAccessFile>
   </Appenders>

    <Loggers>
        <!-- Spring Loggers -->
        <Logger  name="org.springframework" level="info"/>

        <!-- App Loggers -->
        <Logger name="org.jd.test" level="debug" additivity="false">
            <AppenderRef  ref="Console"/>
            <AppenderRef  ref="RollingFile"/>
        </Logger>

        <!-- Root Logger -->
        <Root  level="info">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="RollingFile"/>
        </Root >
    </Loggers>
</Configuration>

application.properties的文件定义如下:

server.port=8080
logging.config=classpath:log4j2.xml
debug=true

上述为核心的配置文件信息。
在pom.xml中,针对spring-boot-web中对于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>

2 问题描述

基于Spring Boot的向导创建基础项目,集成Log4j2,在项目启动过程中,报出如下的错误信息:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/D:/DevSpace/M2Space/ch/qos/logback/logback-classic/1.1.11/logback-classic-1.1.11.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/D:/DevSpace/M2Space/org/apache/logging/log4j/log4j-slf4j-impl/2.7/log4j-slf4j-impl-2.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 [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
The Class-Path manifest attribute in D:\DevSpace\M2Space\org\apache\derby\derby\10.13.1.1\derby-10.13.1.1.jar referenced one or more files that do not exist: D:\DevSpace\M2Space\org\apache\derby\derby\10.13.1.1\derbyLocale_cs.jar,D:\DevSpace\M2Space\org\apache\derby\derby\10.13.1.1\derbyLocale_de_DE.jar,D:\DevSpace\M2Space\org\apache\derby\derby\10.13.1.1\derbyLocale_es.jar,D:\DevSpace\M2Space\org\apache\derby\derby\10.13.1.1\derbyLocale_fr.jar,D:\DevSpace\M2Space\org\apache\derby\derby\10.13.1.1\derbyLocale_hu.jar,D:\DevSpace\M2Space\org\apache\derby\derby\10.13.1.1\derbyLocale_it.jar,D:\DevSpace\M2Space\org\apache\derby\derby\10.13.1.1\derbyLocale_ja_JP.jar,D:\DevSpace\M2Space\org\apache\derby\derby\10.13.1.1\derbyLocale_ko_KR.jar,D:\DevSpace\M2Space\org\apache\derby\derby\10.13.1.1\derbyLocale_pl.jar,D:\DevSpace\M2Space\org\apache\derby\derby\10.13.1.1\derbyLocale_pt_BR.jar,D:\DevSpace\M2Space\org\apache\derby\derby\10.13.1.1\derbyLocale_ru.jar,D:\DevSpace\M2Space\org\apache\derby\derby\10.13.1.1\derbyLocale_zh_CN.jar,D:\DevSpace\M2Space\org\apache\derby\derby\10.13.1.1\derbyLocale_zh_TW.jar
10:00:46.441 [main] DEBUG org.springframework.boot.devtools.settings.DevToolsSettings - Included patterns for restart : []
10:00:46.444 [main] DEBUG org.springframework.boot.devtools.settings.DevToolsSettings - Excluded patterns for restart : [/spring-boot-starter/target/classes/, /spring-boot-autoconfigure/target/classes/, /spring-boot-starter-[\w-]+/, /spring-boot/target/classes/, /spring-boot-actuator/target/classes/, /spring-boot-devtools/target/classes/]
10:00:46.444 [main] DEBUG org.springframework.boot.devtools.restart.ChangeableUrls - Matching URLs for reloading : [file:/D:/workspace/testdemo/target/classes/]
Logging system failed to initialize using configuration from ‘classpath:log4j2.xml’
java.lang.IllegalStateException: Logback configuration error detected:
ERROR in ch.qos.logback.core.joran.spi.Interpreter@3:17 - no applicable action for [Properties], current ElementPath is [[Configuration][Properties]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:35 - no applicable action for [Property], current ElementPath is [[Configuration][Properties][Property]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@7:16 - no applicable action for [Appenders], current ElementPath is [[Configuration][Appenders]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@9:53 - no applicable action for [Console], current ElementPath is [[Configuration][Appenders][Console]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@10:92 - no applicable action for [PatternLayout], current ElementPath is [[Configuration][Appenders][Console][PatternLayout]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@16:91 - no applicable action for [RollingRandomAccessFile], current ElementPath is [[Configuration][Appenders][RollingRandomAccessFile]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@17:106 - no applicable action for [PatternLayout], current ElementPath is [[Configuration][Appenders][RollingRandomAccessFile][PatternLayout]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@18:23 - no applicable action for [Policies], current ElementPath is [[Configuration][Appenders][RollingRandomAccessFile][Policies]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@19:45 - no applicable action for [TimeBasedTriggeringPolicy], current ElementPath is [[Configuration][Appenders][RollingRandomAccessFile][Policies][TimeBasedTriggeringPolicy]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@21:48 - no applicable action for [DefaultRolloverStrategy], current ElementPath is [[Configuration][Appenders][RollingRandomAccessFile][DefaultRolloverStrategy]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@25:14 - no applicable action for [Loggers], current ElementPath is [[Configuration][Loggers]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@27:59 - no applicable action for [Logger], current ElementPath is [[Configuration][Loggers][Logger]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@30:69 - no applicable action for [Logger], current ElementPath is [[Configuration][Loggers][Logger]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@31:42 - no applicable action for [AppenderRef], current ElementPath is [[Configuration][Loggers][Logger][AppenderRef]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@32:46 - no applicable action for [AppenderRef], current ElementPath is [[Configuration][Loggers][Logger][AppenderRef]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@36:29 - no applicable action for [Root], current ElementPath is [[Configuration][Loggers][Root]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@37:41 - no applicable action for [AppenderRef], current ElementPath is [[Configuration][Loggers][Root][AppenderRef]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@38:45 - no applicable action for [AppenderRef], current ElementPath is [[Configuration][Loggers][Root][AppenderRef]]
at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:162)
at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithSpecificConfig(AbstractLoggingSystem.java:66)
at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:56)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:115)
at org.springframework.boot.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:308)
at org.springframework.boot.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:276)
at org.springframework.boot.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:239)
at org.springframework.boot.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:212)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:122)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:74)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:54)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:325)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:296)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107)
at org.jd.test.TestdemoApplication.main(TestdemoApplication.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)

以上是在系统启动过程中的错误信息,关键错误信息是:

Logging system failed to initialize using configuration from ‘classpath:log4j2.xml’
java.lang.IllegalStateException: Logback configuration error detected:

3 问题分析过程

3.1 配置文件的格式或者定义错误

根据刚才看到的错误信息,第一反应是log4j2.xml中定义的错误信息或者格式信息有误。
根据这个判断,就直接在Log4j2的官方文档上,重新查阅了一番,结合定义中的内容格式,感觉格式都是完全正确的,没有什么出入问题。
于是,我就使用排除法,将Log4j2.xml中的内容按照步骤,一部分一部分的进行验证排除,如果哪个部分中存在配置文件的配置错误,则可以定位出来。
在一番定位之后,发现只要配置文件中存在内容,就会报出类似错误信息。
结论是,应该不是配置文件的配置错误信息。

3.2 下载样例项目进行分析

于是,从网上直接下来了spring-boot中自带的spring-boot-sample-actuator-log4j2项目,进行分析:
发现其中pom.xml中的不同之处为:

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

而之前的exclusion是在spring-boot-web-starter中排除的,就是这各位置的不同造成的。
换个角度来分析,可以得出在spring-boot-web-starter中exclude掉的logging并未完全清楚干净,还有其他的类库或者包存在类似的以来。

4. 问题的解决

将spring-boot-starter-logging的包在spring-boot-starter中直接排除掉,从spring boot整体上进行替换,就可以解决这个问题:

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

5 反思分析过程

在这个分析过程中,在看到日志的错误之时,第一反应就是配置文件的配置错误,这个方向从一开始就是错误的。
在Pom.xml中虽然进行了exclude操作,但是并未真正的彻底排除掉logging;在看到样例程序之后,才感知到时logging的遗漏引用存在导致了问题。
我又重新查看一遍项目中报出的异常日志,发现了一个我疏忽的细节问题:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/D:/DevSpace/M2Space/ch/qos/logback/logback-classic/1.1.11/logback-classic-1.1.11.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/D:/DevSpace/M2Space/org/apache/logging/log4j/log4j-slf4j-impl/2.7/log4j-slf4j-impl-2.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 [ch.qos.logback.classic.util.ContextSelectorStaticBinder]

在这个提示信息里面,明确了告知logging有多个绑定,logback、log4j2两种实现;目前使用的是logback的绑定,这个提示信息竟然忽略了…….

其实这个提示信息已经明确告知了问题出现的根源,只是当时被无意或者有意的忽略了…..

6 总结

经过这个问题的分析过程,我们可以得知,异常日志或者错误日志的分析是第一现场,非常的重要,它给了我们大量而丰富的第一手信息,为我们分析和解决问题提示了非常多的方向,需要进行慎重和小心的求证与验证。
之后是exclude logging的依赖,虽然进行exclude排除操作,却并未完全进行替换掉,这个是在包的依赖中遗漏掉的。

Spring Boot日志配置logback,log4j

spring boot默认日志输出内容比较简单而且少,所以要改一下配置。  目前实现slf4j有logbak和log4j,logback性能好点,目前在用。  具体做法:  resource目录...

Logback、Log4J及slf4J日志框架分析对比及在Spring Boot中的使用

Logback、Log4J及slf4J日志框架分析对比及在Spring Boot中的使用

使用Log4J2.properties作为Spring Boot的日志工具

Spring Boot 的官网教材 说可以使用 Log4J 作为日志工具,但是并没有给出详细的说明,也陆续找了下网友的例子,跟着上面做,在 application.properties 里注册了 lo...

Spring Boot系列教程六:日志输出配置log4j2

pring boot支持的日志框架有,logback,Log4j2,Log4j和Java Util Logging,默认使用的是logback日志框架,笔者一直在使用log4j2,并且看过某博主写的...

Spring Boot系列教程六:日志输出配置log4j2

一.前言  spring boot支持的日志框架有,logback,Log4j2,Log4j和Java Util  Logging,默认使用的是logback日志框架,笔者一直在使用log4j2...

Spring Boot 整合 log4j2 实现日志管理

摘要:上一篇,我们讲了Spring Boot 整合 log4j实现日志管理,这一篇接着说一下Spring Boot 整合 log4j2,。 一:还是新建一个java工程: 二:增加log4...

spring boot + log4j2 配置

spring boot + log4j2 配置 首先自定义一个log4j2.xml文件: Java代码   "1.0" encoding="UTF-8"?>   "WARN">   ...

spring boot 使用log4j2日志工具

spring boot 配置log4j2使用的spring版本 org.springframework.boot spring-boot-starter-parent 1.5...

spring中使用logback日志组件替换log4j

logback比log4j的强大之处,请到logback的主页去看,我就不啰嗦了,你懂、或者不懂,logback就在那里,无比强大,傲视绝伦。 复制log4j-over-slf4j.jar,logb...

Log4j2介绍和特性实例(二)--一个实例和初学注意事项(configuration标签中的 status 和 monitorInterval)

上一篇对官方手册中给出的Log4j2新特性进行了翻译,本篇给出一个Log4j2使用的例子。 本例子包括XML配置文件,需要引用的Jar包,需要Import的文件和代码,这样大家对Log4j2的使...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Spring Boot与Log4j2集成之java.lang.IllegalStateException: Logback configuration error detected:
举报原因:
原因补充:

(最多只允许输入30个字)