title | url | tags | categories | date | |||||
---|---|---|---|---|---|---|---|---|---|
使用SLF4J在多线程下输出到不同的日志文件 |
Use_SLF4J_to_output_to_different_log_files_under_multi_threading |
|
|
2018-10-16 13:06:00 -0700 |
最近做了个数据传输的模块, 用到了线程池多线程, 要求将市平台的文章导入到公司的项目中进行管理, 每个栏目都有对应的文章, 但是打印日志时出现了日志混乱的问题。
栏目A传输文章1: 开始
栏目B传输文章2: 开始
栏目B传输文章2: 成功
栏目C传输文章3: 开始
栏目A传输文章1: 成功
栏目C传输文章3: 失败
每个线程输出到不同的日志文件下, 这个功能应该是可以做到的, 只要在初始化Logger
时指定对应的文件名就可以了。
除了Logback
的基础模块, 需要追加引用logback-access
模块。
slf4j
提供了Mapped Diagnostic Context (MDC)
这个工具, 来设置自定义变量。
MDC.put("logName", "LogFile1");
logger.debug("Test" + System.currentTimeMillis());
MDC.remove("logName");
在代码中这样使用, 即可在配置文件中取到value
。
Logback
提供了SiftingAppender
来进行日志记录, 并且可以读取MDC
的值到日志路径的变量中。
下面代码是从我之前写的Logback
日志配置中复制并加以微调的。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 使用 MDC 的 appender -->
<appender name="FILE_CUSTOM" class="ch.qos.logback.classic.sift.SiftingAppender">
<!-- discriminator 的默认实现类 ch.qos.logback.classic.sift.MDCBasedDiscriminator -->
<discriminator>
<key>logName</key>
<defaultValue>MyFile</defaultValue>
</discriminator>
<sift>
<!-- 标准的文件输出 Appender, 文件名根据 MDC 动态生成 -->
<appender name="FILE-${logName}" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>自定义文件路径/${logName}.log</file>
<!-- 最常用的滚动策略,它根据时间来制定滚动策略.既负责滚动也负责出发滚动 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志输出位置 可相对、和绝对路径 -->
<fileNamePattern>自定义文件路径/%d{yyyy-MM-dd}/${logName}.log</fileNamePattern>
</rollingPolicy>
<encoder charset="UTF-8">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
</sift>
</appender>
<!-- root级别 INFO -->
<root level="INFO">
<!-- 文件输出 -->
<appender-ref ref="FILE_CUSTOM" />
</root>
</configuration>
log4j
没有SiftingAppender
, 并且也不能读取MDC
到日志路径的变量中(但是可以读取到日志格式中)。
用编程的方式为每个对象示例初始化Logger
, 然后为其添加Appender
。
public class MyTask {
public org.apache.log4j.Logger getLogger(int id){
org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger("日志"+id);
logger.setLevel(Level.DEBUG);
// 注意要判断是否已存在Appender, 否则会重复创建
String appenderName = "log"+id+"Appender";
if(logger.getAppender(appenderName) == null) {
RollingFileAppender appender = new RollingFileAppender();
appender.setName(appenderName);
appender.setFile("D:\\mylog\\"+id+".log");
appender.setLayout(new PatternLayout("[S][%d{yyyyMMdd HH:mm:ss}][%-5p][%C:%L] - %m%n"));
appender.setMaxFileSize("10240KB");
appender.setMaxBackupIndex(10);
appender.activateOptions();
logger.addAppender(appender);
}
return logger;
}
}