本文概览:选择打印日志方案为:使用log4j,并且使用AsyncLogger异步打印。
1 日志框架方案
1、项目中选择日志框架是log4j2。
目前常遇见的日志框架有log4j、logback、log4j2,logback是为了优化log4j而生的,log4j2又在logback基础上做了优化。所以日志框架选型顺序为:log4j2 > logback > log4j。这三个都是同一个作者所写,都实现字sl4j的接口,sl4j全称Simple logging Facade for Java。
2、log4j2使用AsyncLogger的异步方式
使用同步方式,在高并发情况下会对接口性能有影响,所以使用异步方式,通过异步方式可以将记录日志的I/O操作独立成一个线程来执行。log4j2的异步日志有AsyncAppender和AsyncLogger两种方式,建议使用AsyncLogger方式。AsyncLogger是log4j2新增的功能,使用LMAX Disruptor来实现高吞吐量;Async Appender在log4j1的时候就已经有了。log4j2的AsyncLogger具有高吞吐量和低延迟的特性
(1)吞吐量对比
(2)低延迟(Low-Latency)对比
2 AsyncLogger配置异步日志
1、maven配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<!--配置4j--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.3</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.3</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.3</version> </dependency> <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.4.2</version> </dependency> |
2、log4j2.xml配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<?xml version="1.0" encoding="UTF-8"?> <!-- No need to set system property "Log4jContextSelector" to any value when using <asyncLogger> or <asyncRoot>. --> <Configuration status="WARN"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout> <Pattern>%d %p %class{1.} [%t] %location %m %ex%n</Pattern> </PatternLayout> </Console> <!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. --> <RandomAccessFile name="RandomAccessFile" fileName="./sync.log" immediateFlush="false" append="false"> <PatternLayout> <Pattern>%d %p %class{1.} [%t] %location %m %ex%n</Pattern> </PatternLayout> </RandomAccessFile> </Appenders> <Loggers> <!-- pattern layout actually uses location, so we need to include it --> <AsyncLogger name="com.test" level="info" includeLocation="true" additivity="false"> <AppenderRef ref="RandomAccessFile"/> <AppenderRef ref="Console"/> </AsyncLogger> <AsyncRoot level="info" includeLocation="true"> <AppenderRef ref="RandomAccessFile"/> </AsyncRoot> </Loggers> </Configuration> |
3 相关问题
3.1 log4j2和logback冲突问题
一个项目中只能使用log4j2或者logback。假设在项目中使用了log4j2,此时使用外部依赖jar时候,发现外部依赖使用了logbakc,如何解决这个问题?将外部依赖的logback的包通过exclude排除掉。
3.2 spring boot使用log4j2
spring boot默认使用logback,通过如下maven配置来使用log4j2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<!-- Spring boot默认使用logback --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <!-- 添加log4j2 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> <!-- log4j2使用AsyncLogger异步 --> <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.3.6</version> </dependency> |
如果报错“but there’s no log4j-web module available”,则添加如下:
1 2 3 4 5 |
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-web</artifactId> <version>2.10.0</version> </dependency> |
参考文献
Log4j2中的同步日志与异步日志 https://www.cnblogs.com/yeyang/p/7944906.html
高性能队列——Disruptor https://tech.meituan.com/2016/11/18/disruptor.html
Asynchronous Loggers for Low-Latency Logging https://logging.apache.org/log4j/log4j-2.3/manual/async.html