slf4j的配置参考--
slf4j介绍及配置详解(log4j):https://blog.csdn.net/qq_36330643/article/details/71250465
而Log4j2的一个重要特性,日志异步输出。日志异步输出的好处在于,使用单独的进程来执行日志打印的功能,可以提高日志执行效率,减少日志功能对正常业务的影响。异步日志在程序的classpath需要加载disruptor-3.0.0.jar或者更高的版本,详见官方文档。
一个log4j2的配置示例:
一、pom添加依赖:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.3.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.19</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
</dependency>
二、log4j2.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="error" shutdownHook="disable">
<appenders>
<!-- 打印info日志 -->
<RollingFile name="infoLogFile" fileName="/logs/info.log"
filePattern="/logs/info.log.%d{yyyyMMdd}.%i.gz" immediateFlush="false">
<PatternLayout pattern="%d{HHmmss:SSS}\t%X{ip}\t%c%L\t%t\t%X{txnid}\t%p\t%m%n" />
<Filters>
<ThresholdFilter level="warn" onMatch="DENY" onMismatch="NEUTRAL" />
<ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY" />
</Filters>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
<SizeBasedTriggeringPolicy size="1GB" />
</Policies>
<!-- 每天日志上限为20个,并且删除91天之前的以wx.xxx.info.log开头的日志文件 -->
<DefaultRolloverStrategy max="20">
<Delete basePath="/logs/" maxDepth="1">
<IfFileName glob="info.log.*" />
<IfLastModified age="91d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<!-- 打印error日志 -->
<RollingFile name="monitorLogFile" fileName="/logs/monitor.log"
filePattern="/logs/monitor.log.%d{yyyyMMdd}.%i.gz" immediateFlush="false">
<PatternLayout pattern="%d{HHmmss:SSS}\t%X{ip}\t%c%L\t%t\t%X{txnid}\t%p\t%m%n" />
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
<SizeBasedTriggeringPolicy size="1GB" />
</Policies>
<DefaultRolloverStrategy max="20">
<Delete basePath="/logs/" maxDepth="1">
<IfFileName glob="monitor.log.*" />
<IfLastModified age="91d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</appenders>
<Loggers>
<AsyncRoot level="info" includeLocation="true">
<AppenderRef ref="infoLogFile" />
<AppenderRef ref="monitorLogFile" level="error" />
</AsyncRoot>
</Loggers>
</configuration>
三、测试
package com.jupiter.log4j2.test;
import lombok.extern.slf4j.Slf4j;
/**
* @author Jupiter
* @description Slf4j+log4j2测试
* @date 2018年12月7日
*/
@Slf4j
public class Test {
public static void main(String[] args) throws InterruptedException {
try {
String name = null;
name.length();
} catch (Exception e) {
// StackTraceElement[] se = e.getStackTrace();
// for(StackTraceElement s:se) {
// System.out.println(s);
// log.error("获取当前时间异常,栈信息:"+s);
// }
log.info("获取当前时间异常,栈信息:[{}]"+e);
log.error("获取当前时间异常,栈信息:{}",e);
// Thread.sleep(10);
}
}
}
以上是一种slf4j+log4j2的配置;但是,在实际项目中会遇到没有日志打印的情况,可能是log4j2的异步日志输出在一个异步进程中实现,而在catch异常的主线程已经结束的情况下,日志无法输出就结束了(很少见),如有其他见解,欢迎留言。
解决方法,上面的测试代码中,第一种解决方法是手动打印错误栈信息;第二种是让主线程休息一会儿,再检查是否有日志输出。