By Shuailing
Recently, a colleague from my team reported an issue with the logback-spring.xml file not working as expected. Since I haven't applied for a new application in a while, I'm not very familiar with configuration matters. Most of the time, I just maintain existing applications and use logs directly without paying much attention to the configuration. So, troubleshooting took a lot of my time. In this article, I will describe the entire troubleshooting process, covering the configuration of Logback and the analysis of reasons for its ineffectiveness. I hope this will provide some insights for those facing similar issues.
SLF4J (Simple Logging Facade for Java) serves as a simple facade for Java's logging API. It provides a simple and unified interface for logging, while specific logging implementation can be completed by different logging libraries.
Logback is one of these logging libraries. It is designed to integrate seamlessly with SLF4J or even replace it because one of the developers of Logback is also the founder of SLF4J.
Since pandora-boot integrates Logback by default, additional Logback dependencies are not required.
Logback is officially recommended, so all troubleshooting steps are based on the ineffectiveness of Logback.
application.properties
Add configuration items logging.config=classpath:logback-spring.xml
<?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}) ${LOG_LEVEL_PATTERN:-%5p} %magenta(${PID:- }) --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
<property name="ERROR_FILE_LOG_PATTERN_D"
value="${ERROR_FILE_LOG_PATTERN_D:-%d{yyyy-MM-dd HH:mm:ss.SSS} ${LOG_LEVEL_PATTERN:-%5p} [%X{requestId}] [%X{rpcId}][traceId:%X{EAGLEEYE_TRACE_ID}][%c{2}#%M] %logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%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>
If you reference external variables, only a few are applicable, such as ${PID}, ${LOG_FILE}, ${LOG_PATH}, and ${LOG_EXCEPTION_CONVERSION_WORD}
. For other variables, it is recommended that you define them as properties for normal use. such as the APP_NAME
mentioned above.
You can add -Dlog4j.defaultInitOverride=true
at startup.
After the preceding configuration, the custom Appender may not take effect. It means only the service_stdout.log is included in the specified directory, without customized configuration files.
All files will be output to the service_stdout.log, because in appctl.sh, the default start_pandora_boot
method has already directed the output to "$SERVICE_OUT" 2>&1 "&"
. There's nothing wrong with this part. The core issue is how the custom logback-spring.xml
is distributed.
• Enable the remote debug.
JPDA_OPTS="-agentlib:jdwp=transport=$JPDA_TRANSPORT,address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND"
• Start the IDEA Remote JVM Debug
Execute the command LoggerFactory.getLogger("ROOT")
, and view the aai
under the ROOT
(the AppenderAttachableImpl serves to manage and process multiple Appender objects associated with the logger). It is found that they are not the Appender objects defined by logback-spring.xml
, which means that they are overwritten or have different priorities.
Here, I also took a roundabout course and spent much time debugging the source code, including org.springframework.boot.context.logging.LoggingApplicationListener#initialize
. Here, logback-spring.xml
has been loaded.
After revisiting the official documents, I found a hint that the problem could stem from the package conflict.
Keep in mind the order of the official diagram:
• In theory, the use of Logback excludes SLF4J-Log4j12
.
• Because a conflict will occur between jcl-over-slf4j
and commons-logging
, so commons-logging
needs to be excluded.
If there is no conflict with pom, the sub pom.xml should also be excluded, and using Dependency Analyzer
can make this process much more efficient.
The minimum principle is used in this process to avoid affecting other business codes.
Execute the command LoggerFactory.getLogger("ROOT")
, and view the aai
of the ROOT
instance.
The result is the same as the appender
defined by logback-spring.xml
, and the file
is also normally initialized.
(1) Read official documentation of spring-boot
website carefully. Some issues may be included in the document.
(2) When introducing second-party packages, adopt the minimum principle and make good use of exclusion
.
Disclaimer: The views expressed herein are for reference only and don't necessarily represent the official views of Alibaba Cloud.
1,097 posts | 321 followers
FollowAlibaba Clouder - August 28, 2019
Alibaba Clouder - April 10, 2019
Alibaba Clouder - March 28, 2018
Alibaba Clouder - February 21, 2020
Alibaba Clouder - April 8, 2018
Alibaba Clouder - July 2, 2020
1,097 posts | 321 followers
FollowExplore Web Hosting solutions that can power your personal website or empower your online business.
Learn MoreExplore how our Web Hosting solutions help small and medium sized companies power their websites and online businesses.
Learn MoreBuild superapps and corresponding ecosystems on a full-stack platform
Learn MoreWeb App Service allows you to deploy, scale, adjust, and monitor applications in an easy, efficient, secure, and flexible manner.
Learn MoreMore Posts by Alibaba Cloud Community