Java日志框架
作为一个Java程序员,肯定离不开日志框架,现在最优秀的Java日志框架是Log4j2,没有之一。根据官方的测试表明,在多线程环境下,Log4j2的异步日志表现更加优秀。在异步日志中,Log4j2使用独立的线程去执行I/O操作,可以极大地提升应用程序的性能。
在官方的测试中,下图比较了Sync、Async Appenders和Loggers all async三者的性能。其中Loggers all async表现最为出色,而且线程数越多,Loggers all async性能越好。
除了对Log4j2自身的不同模式做对比以外,官方还做了Log4j2/Log4j1/Logback的对比,如下图所示
其中,Loggers all async是基于LMAX Disruptor实现的。
使用Log4j2
需要哪些JAR
使用Log4j2最少需要两个JAR,分别是log4j-api-2.x和log4j-core-2.x,其它JAR包根据应用程序需要添加。
配置文件位置
默认的,Log4j2在classpath下寻找名为log4j2.xml的配置文件。也可以使用system property指定配置文件的全路径。-Dlog4j.configurationFile=path/to/log4j2.xml,在Java代码中指定路径如下所示
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import java.io.File;
public class Demo {
public static void main(String[] args) {
LoggerContext loggerContext = (LoggerContext) LogManager.getContext(false);
File file = new File("path/to/a/different/log4j2.xml");
loggerContext.setConfigLocation(file.toURI());
}
}
一般的,不需要手动关闭Log4j2,如果想手动在代码中关闭Log4j2如下所示
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configurator;
public class Demo {
public static void main(String[] args) {
Configurator.shutdown((LoggerContext) LogManager.getContext());
}
}
不同的线程输出日志到不同的文件中有关Log4j2的内容很多,不能一一列出,如果在开发中遇到任何问题,推荐去官方文档中寻找解决方案。
方法一使用ThreadContext
在多线程编程中,如果不做特殊的设置,那么多个线程的日志会输出到同一个日志文件中,这样在查阅日志的时候,会带来诸多不便。很自然地,我们想到了让不同的线程输出日志到不同的文件中,这样不是更好吗?在翻阅官方文档过程中,找到了FAQ(Frequently Asked Questions),其中有个问题log4j2.xml配置如下:
filePattern="./logs/${date:yyyy-MM}/${ctx:ROUTINGKEY}-special-%d{yyyy-MM-dd}-%i.log.gz">
%d{ISO8601} [%t] %p %c{3} - %m%n
filePattern="./logs/${date:yyyy-MM}/default-%d{yyyy-MM-dd}-%i.log.gz">
%d{ISO8601} [%t] %p %c{3} - %m%n
filePattern="./logs/${date:yyyy-MM}