logback-spring.xml配置不生效的排查与解决

原文标题:你的应用是不是只有service_stdout.log?

原文作者:阿里云开发者

冷月清谈:

本文主要介绍了logback-spring.xml文件不生效的排查思路,包括logback配置、不生效的原因分析等。

一、背景
近期遇到同组同学反馈logback-spring.xml文件不生效的问题,本文记录了整个排查思路,包括logback配置、不生效的原因分析等,希望给大家提供一些经验参考。

二、logback配置
因为pandora-boot默认集成logback,不需要额外logback依赖。

三、不生效原因分析
3.1、远程debug
3.2、查看logback appender
3.3 排查日志冲突问题
3.4 double check

四、总结
1、仔细阅读spring-boot官方文档,自己踩过的坑绝不是独一无二的。
2、引入二方包时养成最小原则,善用exclusion(虽然这只是美好愿望,希望排查时不要泪两行)




怜星夜思:


1、配置文件中${XXX}变量能使用哪些?
2、遇到logback配置不生效的情况,可以采取哪些排查步骤?
3、在使用logback进行日志配置时,需要注意哪些常见问题?




原文内容



阿里妹导读


本文记录了logback-spring.xml文件不生效问题的整体排查思路。

一、背景

近期遇到同组同反馈logback-spring.xml文件不生效的问题,由于本人很久没申请过新应用,所以对于配置类的事宜有点陌生(大部分是应用交接维护,直接使用log也没过多关注配置,知道大概但细节有点脱节,虚了),导致自己在排查阶段花了很长时间,本文记录了整个排查思路,包括logback配置、不生效的原因分析等,希望给大家提供一些经验参考。


1.1 Logback简介

SLF4J(Simple Logging Facade for Java)是一个Java的日志API的简单门面,它提供了一个简单统一的记录日志的接口,而具体的日志实现则可以通过不同的日志库来完成。

Logback是一个日志库,Logback被设计为能够与SLF4J无缝集成,也可替代SLF4J,因为Logback的开发者之一是SLF4J的创始人。

二、logback配置

因为pandora-boot默认集成logback,不需要额外logback依赖。


2.1 配置姿势

官方推荐使用logback,排查思路均以logback不生效为主线。

图片

1)指定配置文件路径

application.properties添加配置项logging.config=classpath:logback-spring.xml

2)自定义配置文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
<!-- https://github.com/spring-projects/spring-boot/blob/v1.5.13.RELEASE/spring-boot/src/main/resources/org/springframework/boot/logging/logback/defaults.xml -->
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<property name="APP_NAME" value="xxxx" />
<property name="LOG_PATH" value="${user.home}/logs/eleme/${APP_NAME}/" />
<property name="LOG_FILE" value="${LOG_PATH}/application.log" />
<property name="ERROR_LOG_FILE" value="${LOG_PATH}/common-error.log"/>
<property name="TRACE_FILE_LOG_PATTERN" value="[%X{requestId}][%X{rpcId}] -%green(%d{yyyy-MM-dd HH:mm:ss.SSS}) %5p %magenta( ) --- [%t] %-40.40logger{39} : %m%n%wEx"/>
<property name="ERROR_FILE_LOG_PATTERN_D"
value="%d{yyyy-MM-dd HH:mm:ss.SSS %5p [%X{requestId}] [%X{rpcId}][traceId:%X{EAGLEEYE_TRACE_ID}][%c{2}#%M] %logger{39} : %m%n%wEx}"/>

<appender name=“APPLICATION”
class=“ch.qos.logback.core.rolling.RollingFileAppender”>
<file>${LOG_FILE}</file>
<encoder>
<pattern>${TRACE_FILE_LOG_PATTERN}</pattern>
</encoder>
<rollingPolicy class=“ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy”>
<fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>7</maxHistory>
<maxFileSize>50MB</maxFileSize>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
</appender>

<appender name=“ERROR_APPENDER”
class=“ch.qos.logback.core.rolling.RollingFileAppender”>
<file>${ERROR_LOG_FILE}</file>
<encoder>
<pattern>${ERROR_FILE_LOG_PATTERN_D}</pattern>
</encoder>
<rollingPolicy class=“ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy”>
<fileNamePattern>${ERROR_LOG_FILE}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>7</maxHistory>
<maxFileSize>50MB</maxFileSize>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<filter class=“ch.qos.logback.classic.filter.LevelFilter”>
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>

<appender name=“CONSOLE” class=“ch.qos.logback.core.ConsoleAppender”>
<encoder>
<pattern>${TRACE_CONSOLE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>

<root level=“INFO”>
<!-- <appender-ref ref=“CONSOLE” />–>
<appender-ref ref=“APPLICATION” />
<appender-ref ref=“ERROR_APPENDER” />
</root>
</configuration>


2.2 配置可能遇到的一些问题

1)自定义变量不生效?

如果引用外部的变量,只有几个变量适用,比如${PID}、${LOG_FILE}、${LOG_PATH}、${LOG_EXCEPTION_CONVERSION_WORD},其它变量建议定义成property才能正常使用。如上文中的APP_NAME

2)如何看更多报错信息?

可以在启动时加上`-Dlog4j.defaultInitOverride=true`


2.3 完成配置后未生效表象

按照如上配置后,可能出现自定义的Appender不生效,即指定目录下只有service_stdout.log,无自定义的file配置。





所有的文件都会输出到service_stdout.log,因为在appctl.sh中,默认start_pandora_boot方法中已指定输出到"$SERVICE_OUT" 2>&1 "&" ,这里是无问题,核心在于自定义的logback-spring.xml如何分发。

三、不生效原因分析


3.1、远程debug

  • 首先要开启远程debug,

    JPDA_OPTS="-agentlib:jdwp=transport=$JPDA_TRANSPORT,address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND"

  • idea启动Remote JVM Debug


3.2、查看logback appender

执行命令LoggerFactory.getLogger("ROOT"),查看ROOT下的aai(AppenderAttachableImpl作用是管理和处理与日志记录器相关联的多个Appender对象),发现并不是logback-spring.xml自己定义的Appender对象,意味着被覆盖或优先级有所不同。





这里也走了弯路,不断debug源码找问题,包括org.springframework.boot.context.logging.LoggingApplicationListener#initialize其中logback-spring.xml已被加载。





回头看了下官方文档,提示可能包冲突导致的问题。


3.3 排查日志冲突问题





牢记官方这个图的顺序:

  • 理论上使用logback,就要排除SLF4J-Log4j12
  • 因为jcl-over-slf4j commons-logging冲突, 需要排除commons-logging

如果跟pom无冲突, 子pom.xml也要排除,使用Dependency Analyzer事半功倍。





排除过程中采用最小原则,避免影响其它业务代码。


3.4 double check

执行命令LoggerFactory.getLogger("ROOT"),再次查看ROOT实例下的aai





与`logback-spring.xml`定义的appender一样, 同时定义的file也被正常初始化了。

图片

四、总结

1、仔细阅读spring-boot官方文档,自己踩过的坑绝不是独一无二的。

2、引入二方包时养成最小原则,善用exclusion(虽然这只是美好愿望,希望排查时不要泪两行)。

参考文章:

PandoraBoot文档: https://mw.alibaba-inc.com/products/pandoraboot/_book/log-config.html

网站静态资源访问加速


本方案使用阿里云CDN产品来分发OSS上的网站静态文件,不仅可以降低源站的负载压力,还能够提升网站的访问性能,同时还能在高并发场景下为您节约成本。快点击阅读原文查看详情。


如果仍然无法解决问题,可以尝试以下步骤:

  1. 启用远程调试,连接到正在运行的应用,并检查logback的初始化过程。
  2. 排查是否存在日志框架冲突,比如是否同时存在logback和log4j。
  3. 检查应用的类路径中是否存在多个logback版本导致的冲突。

养成良好的日志配置习惯,定期检查和维护日志配置,确保日志系统高效稳定地运行。不要嫌麻烦,越早发现问题解决问题,越能避免更大的损失。哈哈哈~

变量的使用范围受logback配置的控制,具体请参考logback官方文档。但是,在pandora-boot中,只支持上述几个特定的变量。其他变量可能需要通过自定义代码实现。

如果以上步骤都无法解决问题,可以尝试在社区论坛或logback官方网站上寻求帮助,提供详细的日志信息和配置信息。

  1. 检查logback配置文件的路径是否正确。
  2. 检查配置文件的语法是否正确,是否存在错误或遗漏。
  3. 查看日志文件中是否有报错信息,并根据报错信息进行排查。
  4. 尝试重新启动应用,查看问题是否解决。
  1. 日志级别配置:确保日志级别配置正确,避免输出过多或过少的日志信息。
  2. 日志文件路径和权限:检查日志文件路径是否正确,以及应用是否有足够的权限写入日志文件。
  3. 日志格式化:自定义日志格式时,需要确保格式化字符串正确,以免出现日志解析错误。
  4. 日志文件滚动策略:配置日志文件滚动策略时,需要考虑日志文件的大小和保留时间,避免日志文件过大或丢失重要日志信息。
  5. 日志Appender:选择合适的日志Appender,根据需要将日志输出到文件、控制台或其他目的地。

除了上述常见问题外,还需要注意:

  1. 日志框架冲突:避免同时使用多个日志框架,如logback和log4j,以免造成冲突。
  2. 第三方库的影响:某些第三方库可能会修改日志配置,导致logback配置不生效。
  3. 应用环境变量:检查应用运行环境中是否存在与logback配置冲突的环境变量。

只适用于几个特定的变量,比如${PID}、${LOG_FILE}、${LOG_PATH}、${LOG_EXCEPTION_CONVERSION_WORD},其它变量建议定义成property才能正常使用。

要使用其他变量,需要在配置文件中定义成property,然后再使用${property_name}引用。