简介
异步Appender
ref: https://juejin.cn/post/7197778998439706682
介绍
使用AsyncAppender来异步打印日志时,每个AsyncAppender持有一个ArrayBlockingQueue,并且每个AsyncAppender还会启动一个后台线程来消费阻塞队列中的待打印日志,后台线程每消费一条待打印日志,就会遍历当前AsyncAppender持有的Appender来完成日志打印。
使用
测试程序中的logger会继承使用根日志打印器的LoggerConfig,也就持有了name为MyAsync的异步Appender
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO"> <Appenders> <Console name="MyConsole" target="SYSTEM_OUT"> <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="%msg%n"/> </Console> <RollingFile name="MyFile" fileName="mylog.log" filePattern="mylog.log.%i"> <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY" /> <PatternLayout pattern="%msg%n"/> <SizeBasedTriggeringPolicy size="20M"/> </RollingFile>
<Async name="MyAsync"> <AppenderRef ref="MyConsole"/> <AppenderRef ref="MyFile"/> </Async> </Appenders>
<Loggers> <Root level="INFO"> <Appender-ref ref="MyAsync"/> </Root> </Loggers> </Configuration>
|
异步Logger
ref: https://juejin.cn/post/7198126784764182586
介绍
使用AsyncAppender来异步打印日志时,每个AsyncAppender持有一个ArrayBlockingQueue,并且每个AsyncAppender还会启动一个后台线程来消费阻塞队列中的待打印日志,后台线程每消费一条待打印日志,就会遍历当前AsyncAppender持有的Appender来完成日志打印。
使用
在Log4j2的配置文件中使用<AsyncLogger**>标签配置一个异步Logger,并为这个异步Logger配置普通Appender**
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO"> <Appenders> <Console name="MyConsole" target="SYSTEM_OUT"> <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="%msg%n"/> </Console> <RollingFile name="MyFile" fileName="mylog.log" filePattern="mylog.log.%i"> <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY" /> <PatternLayout pattern="%msg%n"/> <SizeBasedTriggeringPolicy size="20M"/> </RollingFile> </Appenders>
<Loggers> <Root level="INFO"> <Appender-ref ref="MyConsole"/> <Appender-ref ref="MyFile"/> </Root> <AsyncLogger name="com.lee.learn.log4j2.asynclogger.LearnLog4j2Async" level="INFO" additivity="false"> <appender-ref ref="MyConsole"/> </AsyncLogger> </Loggers> </Configuration>
|
全量异步
ref: https://juejin.cn/post/7199620944339337274
介绍
异步日志打印,实际就是将打印日志时最终涉及到的I/O操作放在一个单独的后台线程中执行,从而让业务线程能够快速的从Logger.log() 方法返回。
使用
日志配置
同步日志打印时的一份简单配置,并未使用到异步标签例如<**AsyncLogger**>,<**Async**>等,而要开启全量异步日志打印
<?xml version="1.0" encoding="UTF-8"?>
<Configuration> <Appenders> <Console name="MyConsole" target="SYSTEM_OUT"> <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %p [%l] %m%n"/> </Console> </Appenders>
<Loggers> <Root level="INFO" includeLocation="true"> <Appender-ref ref="MyConsole"/> </Root> </Loggers> </Configuration>
|
增加依赖
<dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.4.2</version> </dependency>
|
配置开启全量
JVM参数实现: -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelecto
properties配置文件: log4j2.component.properties
log4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
log4j2.discardThreshold=ERROR log4j2.asyncQueueFullPolicy=Discard log4j2.asyncLoggerConfigWaitStrategy=Sleep log4j2.asyncLoggerWaitStrategy=Sleep
log4j2.asyncLoggerRingBufferSize=8388608 log4j2.asyncLoggerTimeout=10
log4j2.asyncLoggerSleepTimeNs=100
log4j2.asyncLoggerRetries=200
|
参考配置
<?xml version="1.0" encoding="UTF-8"?> <Configuration>
<Properties> <Property name="LOG_INFO_LEVEL" value="info"/> <Property name="LOG_ERROR_LEVEL" value="error"/> <Property name="LOG_HOME" value="./log"/> <Property name="LOG_ARCHIVE" value="./log/archive"/> <Property name="LOG_MODULE_NAME" value="spring-boot"/> <Property name="LOG_MAX_SIZE" value="100 MB"/> <Property name="LOG_DAYS" value="15"/> <Property name="LOG_PATTERN" value="%d [%t] %-5level %logger{0} - %msg%n"/> <Property name="TIME_BASED_INTERVAL" value="1"/> </Properties>
<Appenders> <Console name="STDOUT" target="SYSTEM_OUT"> <PatternLayout pattern="${LOG_PATTERN}"/> <ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/> </Console>
<RollingRandomAccessFile name="RollingRandomAccessFileInfo" fileName="${LOG_HOME}/${LOG_MODULE_NAME}-infoLog.log" filePattern="${LOG_ARCHIVE}/${LOG_MODULE_NAME}-infoLog-%d{yyyy-MM-dd}-%i.log.gz" immediateFlush="false"> <Filters> <ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="DENY" onMismatch="NEUTRAL"/> <ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/> </Filters> <PatternLayout pattern="${LOG_PATTERN}"/> <Policies> <TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/> <SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/> </Policies> <DefaultRolloverStrategy max="${LOG_DAYS}"/> </RollingRandomAccessFile>
<RollingRandomAccessFile name="RollingRandomAccessFileError" fileName="${LOG_HOME}/${LOG_MODULE_NAME}-errorLog.log" filePattern="${LOG_ARCHIVE}/${LOG_MODULE_NAME}-errorLog-%d{yyyy-MM-dd}-%i.log.gz" immediateFlush="false"> <Filters> <ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/> </Filters> <PatternLayout pattern="${LOG_PATTERN}"/> <Policies> <TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/> <SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/> </Policies> <DefaultRolloverStrategy max="${LOG_DAYS}"/> </RollingRandomAccessFile>
</Appenders>
<Loggers>
<Root level="${LOG_INFO_LEVEL}" includeLocation="false"> <AppenderRef ref="RollingRandomAccessFileInfo"/> <AppenderRef ref="RollingRandomAccessFileError"/> </Root> </Loggers>
</Configuration>
|