SpringBoot 使用Log4j2日志2:异步输出

原创
2021/04/25 22:34
阅读数 133

Log4j2 默认使用的是同步日志模式。因为使用了 Disruptor 高速并发框架,我们也可以将其改成异步日志模式,提升性能。Log4j2 支持完全异步模式,也支持异步/同步混合模式,它们性能梯度为:完全异步模式 > 混合模式 > 同步模式。

 

一、添加依赖

除了要引入 Log4j2 依赖外,还需要引入 disruptor 并发框架。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!-- 去掉springboot默认配置 -->
    <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>
 
<!-- 引入disruptor并发框架 -->
<dependency>
    <groupId>com.lmax</groupId>
    <artifactId>disruptor</artifactId>
    <version>3.4.2</version>
</dependency>

 

二、异步模式

异步模式可以最大提升性能,也是官方也比较推荐的模式。一种方法是在启动类中加入相关属性参数。

@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
		//下面语句使得日志输出使用异步处理,减小输出日志对性能的影响
		System.setProperty("Log4jContextSelector",
				"org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");
		SpringApplication.run(DemoApplication.class, args);
	}

}

或者我们也可以在启动参数里设置。

java -jar -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector xxx.jar

我们启动项目,查看线程,看到有两个线程是关于 Log4j2 说明我们的配置是成功的。

 

三、异步/同步混合模式

如果需要采用混合模式的话,可以通过 log4j2 配置文件中的 Logger 部分进行设置(不需要在启动类或者启动命令中设置参数)。只有该 APP 日志(com.example 包下的代码产生的日志)采用异步模式,其他日志仍然使用同步模式:

<loggers>
    <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
    <logger name="org.mybatis" level="info" additivity="false">
        <AppenderRef ref="Console"/>
    </logger>
    <!--监控系统信息-->
    <Logger name="org.springframework" level="info" additivity="false">
        <AppenderRef ref="Console"/>
    </Logger>
 
    <!-- com.example 包下日志采用异步模式 -->
    <AsyncLogger name="com.example" level="info" additivity="false">
        <AppenderRef ref="Console" />
        <AppenderRef ref="Filelog" />
        <AppenderRef ref="RollingFileInfo" />
        <AppenderRef ref="RollingFileWarn" />
        <AppenderRef ref="RollingFileError" />
    </AsyncLogger>
 
    <root level="info">
        <appender-ref ref="Console"/>
        <appender-ref ref="Filelog"/>
        <appender-ref ref="RollingFileInfo"/>
        <appender-ref ref="RollingFileWarn"/>
        <appender-ref ref="RollingFileError"/>
    </root>
</loggers>

 

四、异步模式下类方法和行数信息不显示问题解决

1、当我们使用异步模式时,会发现打印的类方法或者行号都无法显示。这是由于默认情况下,异步日志记录器不会将 location 信息传递给 I/O 线程。

2、解决方法

通过设置 includeLocation="true" 可以解决这个问题。设置后 log4j2 将会获取堆栈的快照(snapshot),并遍历堆栈跟踪以查找位置信息。当然这种方式对性能会有影响,所以如果打印日志的行数和所在方法并非十分必要的话能不用尽量不用。

异步模式可以如此配置该参数:

<loggers>
    <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
    <logger name="org.mybatis" level="info" additivity="false">
        <AppenderRef ref="Console"/>
    </logger>
    <!--监控系统信息-->
    <Logger name="org.springframework" level="info" additivity="false">
        <AppenderRef ref="Console"/>
    </Logger>
  
    <root level="info" includeLocation="true">
        <appender-ref ref="Console"/>
        <appender-ref ref="Filelog"/>
        <appender-ref ref="RollingFileInfo"/>
        <appender-ref ref="RollingFileWarn"/>
        <appender-ref ref="RollingFileError"/>
    </root>
</loggers>

混合模式时可以如此配置该参数:

<loggers>
    <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
    <logger name="org.mybatis" level="info" additivity="false">
        <AppenderRef ref="Console"/>
    </logger>
    <!--监控系统信息-->
    <Logger name="org.springframework" level="info" additivity="false">
        <AppenderRef ref="Console"/>
    </Logger>
 
    <!-- com.example 包下日志采用异步模式 -->
    <AsyncLogger name="com.example" level="info" additivity="false" includeLocation="true">
        <AppenderRef ref="Console" />
        <AppenderRef ref="Filelog" />
        <AppenderRef ref="RollingFileInfo" />
        <AppenderRef ref="RollingFileWarn" />
        <AppenderRef ref="RollingFileError" />
    </AsyncLogger>
 
    <root level="info">
        <appender-ref ref="Console"/>
        <appender-ref ref="Filelog"/>
        <appender-ref ref="RollingFileInfo"/>
        <appender-ref ref="RollingFileWarn"/>
        <appender-ref ref="RollingFileError"/>
    </root>
</loggers>

我们设置后,重新启动发现出现了行数。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部