由Logback configuration error detected问题想到的

今天在springboot项目中引入其他JAR包后发现项目启动时报错。

错误日志

Logging system failed to initialize using configuration from 'classpath:log4j2-staging.xml'
java.lang.IllegalStateException: Logback configuration error detected: 
ERROR in ch.qos.logback.core.joran.spi.Interpreter@3:16 - no applicable action for [appenders], current ElementPath  is [[configuration][appenders]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:67 - no applicable action for [Console], current ElementPath  is [[configuration][appenders][Console]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@5:96 - no applicable action for [PatternLayout], current ElementPath  is [[configuration][appenders][Console][PatternLayout]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@10:119 - no applicable action for [RollingFile], current ElementPath  is [[configuration][appenders][RollingFile]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@11:96 - no applicable action for [PatternLayout], current ElementPath  is [[configuration][appenders][RollingFile][PatternLayout]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@12:23 - no applicable action for [Policies], current ElementPath  is [[configuration][appenders][RollingFile][Policies]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@13:45 - no applicable action for [TimeBasedTriggeringPolicy], current ElementPath  is [[configuration][appenders][RollingFile][Policies][TimeBasedTriggeringPolicy]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@14:57 - no applicable action for [SizeBasedTriggeringPolicy], current ElementPath  is [[configuration][appenders][RollingFile][Policies][SizeBasedTriggeringPolicy]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@16:48 - no applicable action for [DefaultRolloverStrategy], current ElementPath  is [[configuration][appenders][RollingFile][DefaultRolloverStrategy]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@21:79 - no applicable action for [RollingFile], current ElementPath  is [[configuration][appenders][RollingFile]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@22:96 - no applicable action for [PatternLayout], current ElementPath  is [[configuration][appenders][RollingFile][PatternLayout]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@23:23 - no applicable action for [Policies], current ElementPath  is [[configuration][appenders][RollingFile][Policies]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@24:45 - no applicable action for [TimeBasedTriggeringPolicy], current ElementPath  is [[configuration][appenders][RollingFile][Policies][TimeBasedTriggeringPolicy]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@25:57 - no applicable action for [SizeBasedTriggeringPolicy], current ElementPath  is [[configuration][appenders][RollingFile][Policies][SizeBasedTriggeringPolicy]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@27:48 - no applicable action for [DefaultRolloverStrategy], current ElementPath  is [[configuration][appenders][RollingFile][DefaultRolloverStrategy]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@28:79 - no applicable action for [ThresholdFilter], current ElementPath  is [[configuration][appenders][RollingFile][ThresholdFilter]]

刚开始我认为是日志文件log4j2-staging.xml配置错了,或者路径找不到,其实不然。

正解是我们pom文件配置的有问题,jar包存在冲突,下面来看下我们的pom文件吧。

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

乍一看没什么问题,我们需使用log4j2日志的starter已经引入了。

在引入spring-boot-starter-web包的时候他里面默认使用了logback日志,这样就会产生日志包的冲突(其实不只是starter-web包默认引入的logback还有很多的包默认引入的logback包),
我们在配置中已经用了 <exclusion>标签排除了logback,但是还是不行,这是为什么呢?

很多包都默认使用的logback,你单独排除了web包还会出现这个问题,这里就需要知道pom文件的加载顺序了,pom文件的加载顺序也是从上至下执行,那么我们就需要把web包放到pom文件中的第一位,在向下执行的时候也会排除所有的默认logger了。

什么是log4j2

(1)log4j

log4j是apache的一个开源项目,表示log for java.是一个日志工具,可以将日志信息输出到文件,控制台等其他地方 ,还可以定义日志的输出格式,另外还有日志级别的区分,可通过配置文件去配置输出格式,输出目的地等信息.

(2)log4j2

log4j2从名字就知道了,是log4j的升级版本,性能有了很大提升,增加了很多新特性(如自定义级别,lambda表达式)与新的API,直接与tomcat等服务器集成.

log4j2的配置文件

只能是.xml或.json或.jsn文件,默认会在classpath下寻找(在这里classpath相当于图中的src).
默认情况下系统选择配置文件的优先级如下:

1.classpath下名为 log4j-test.json 或者log4j-test.jsn文件
2.classpath下名为 log4j2-test.xml
3.classpath下名为 log4j.json 或者log4j.jsn文件
4.classpath下名为 log4j2.xml

这里使用log4j2. xml.log4j2.xml如下:

<?xml version="1.0" encoding="UTF-8"?>    
<configuration status="OFF">    
  <appenders>    
    <Console name="Console" target="SYSTEM_OUT">    
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>    
    </Console>    
  </appenders>    
  <loggers>    
    <logger name="test" level="info" additivity="false">    
      <appender-ref ref="Console"/>    
    </logger>    
    <root level="info">    
      <appender-ref ref="Console"/>    
    </root>    
  </loggers>    
</configuration>  

Logger三个主要的组件为

  • logger(记录器)
  • appender(输出目的地)
  • layout(布局,定义日志的格式)

<appenders>了输出目的地,<Console>表示控制台,<PatternLayout>定义了布局,里面的布局表示时间格式(%d,HH:mm:ss.SSS),接着是日志线程名(%t),%-5表示最小长度为5左对齐,level表示输出日志级别.

%logger表示输出logger名称.
%m是%msg与%message的缩写,表示输出应用提供的与记录事件有关的信息.
%n表示换行.

<loggers>定义的logger与logger使用的appender.root为log默认的输出形式,如果一个类的没有明确loggers中的输出格式就会采用root的格式.

Log4j2的性能

Log4j2最牛逼的地方在于异步输出日志时的性能表现,Log4j2在多线程的环境下吞吐量与Log4j和Logback的比较如下图。下图比较中Log4j2有三种模式:1)全局使用异步模式;2)部分Logger采用异步模式;3)异步Appender。可以看出在前两种模式下,Log4j2的性能较之Log4j和Logback有很大的优势。

常用的日志框架

日志对于项目的重要性不言而喻,现在市面上的日志框架多种多样:Log4j、Log4j2、Slf4j、JDKLog、Logback等等,如果没有真正深入了解过,可能会被搞得眼花缭乱。目前Java项目中最常见的Log4j2 + Slf4j的使用组合。

Log4j目前已经停止更新了。Apache推出了新的Log4j2来代替Log4j,Log4j2是对Log4j的升级,与其前身Log4j相比有了显着的改进,并提供了许多Logback可用的改进,同时解决了Logback体系结构中的一些固有问题。因此,Log4j2 + Slf4j应该是未来的大势所趋。

maven依赖原则以及jar包冲突

一、maven依赖原则

1、依赖路径最短优先原则
一个项目Demo依赖了两个jar包,其中A-B-C-X(1.0) , A-D-X(2.0)。由于X(2.0)路径最短,所以项目使用的是X(2.0)。

2、pom文件中申明顺序优先
如果A-B-X(1.0) ,A-C-X(2.0) 这样的路径长度一样怎么办呢?这样的情况下,maven会根据pom文件声明的顺序加载,如果先声明了B,后声明了C,那就最后的依赖就会是X(1.0)。

3,覆写优先
子pom内声明的优先于父pom中的依赖。

二、如何解决jar冲突

遇到冲突的时候第一步要找到maven加载的到时是什么版本的jar包,通过们mvn dependency:tree查看依赖树,通过maven的依赖原则来调整坐标在pom文件的申明顺序是最好的办法。

参考:
https://blog.csdn.net/m0_37034294/article/details/82801294
https://juejin.im/post/6844903974559023118
https://zhuanlan.zhihu.com/p/36554554
https://www.jianshu.com/p/a26c1d8c4d1b

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容