使用背景
在系统开发过程中,我们可能需要这样一个场景,需要将某个业务逻辑的运行日志单独放到一个日志文件里面,方便我们问题的排查和追踪,我就碰到过这种需求。
在我开发的一个aps(高级自动排程系统)项目中,有许多业务,核心的功能是排产逻辑(将订单排分给不同产线生产)。在执行排产的时候,需要涉及到五六个服务之间的相互调用,而每个服务都是有自己独立的日志文件。我们在分析排产过程,排查问题的的时候,需要在这五六个日志文件中来回切换的查看,定位一个问题非常难。
为了解决这个问题,这里我通过使用logback组件,对某一特定业务的日志进行单独配置,单独收集到统一一个文件中,这样就可以很直观的看到一个业务的完整流转过程。
spring boot 项目默认使用logback日志组件,但需要自己创建个性化配置文件:logback.xml,将logback.xml日志文件放到resource目录下,spring boot项目会自动扫描并加载该配置文件。
完整的logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="FILEOUT" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>applogs/%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} %msg%n</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %boldYellow(%thread) %highlight(%-5level) %boldGreen(%caller{1})
%msg%n
</Pattern>
</encoder>
</appender>
<!--不同业务逻辑的日志打印到不同文件-->
<appender name="scheduleToPlantLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- <File>${LOG_HOME}/biz.log</File>-->
<!-- <append>true</append>-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>../schedulePlantLog/%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>12</maxHistory>
</rollingPolicy>
<encoder charset="UTF-8">
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %level [%thread] %file:%line - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILEOUT"/>
</root>
<!-- 不同的业务逻辑日志打印到指定文件夹-->
<logger name="scheduleToPlantLog" additivity="false" level="INFO">
<appender-ref ref="scheduleToPlantLogAppender"/>
</logger>
</configuration>
对于上面的配置文件,这里来解释一下:
这里主要是看“scheduleToPlantLog”这个logger,它就是专门来收集某业务日志的logger,
主要分为logger和appender两部分,
logger
- 指定logger的名称为“scheduleToPlantLog”
- 指定logger的appender为scheduleToPlantLogAppender
<!-- 不同的业务逻辑日志打印到指定文件夹-->
<logger name="scheduleToPlantLog" additivity="false" level="INFO">
<appender-ref ref="scheduleToPlantLogAppender"/>
</logger>
appender
- 指定文件存储路径
- 指定日志保存时长
- 指定日志输出格式
<!--不同业务逻辑的日志打印到不同文件-->
<appender name="scheduleToPlantLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>../schedulePlantLog/%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>12</maxHistory>
</rollingPolicy>
<encoder charset="UTF-8">
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %level [%thread] %file:%line - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
用到的常量
public class LogConstants {
/**
* 业务类型
*/
public static class BizType {
/**
* 排产到工厂logger
*/
public static final String SCHEDULE_TO_PLANT = "scheduleToPlantLog";
}
}
封装的utils
public class LoggerUtils {
public static <T> Logger Logger(Class<T> clazz) {
return LoggerFactory.getLogger(clazz);
}
/**
* 打印到指定的文件下
*
* @param desc 日志文件名称
* @return
*/
public static Logger Logger(String desc) {
return LoggerFactory.getLogger(desc);
}
/**
* 获取排产到工厂logger
* @return
*/
public static Logger getScheduleToPlantLogger(){
return Logger(LogConstants.BizType.SCHEDULE_TO_PLANT);
}
}
使用该logger打印日志
logger.info("调用排序算法:SortProcessor,参数:{}", parameters.get(0).getCode());
输出结果,该日志文件在项目的上级目录的schedulePlantLog文件夹下,全部是某一业务的日志
输出结果:
这样我们针对不同的日志文件可以自定义进行处理了。