小弟最近无聊,想把项目(springboot3.0)的日志框架logback换成传说比较牛掰的log4j2,享受一下异步零拷贝的快乐。
新建项目,把默认日志框架排除掉
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<!-- 排除springboot自带的日志 -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
</exclusion>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</exclusion>
</exclusions>
</dependency>
加入log4j2框架
<!-- 已经包含了log4j-api 不需要再引入-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.19.0</version>
</dependency>
<!-- 引入异步框架 如果不需要用async logger 可不引用 -->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.4</version>
</dependency>
配置log4j
- 我需要的日志目录结构:
logs:
- info_history(文件夹)
- error_history(文件夹)
- warn_history(文件夹)
- latest_info.log
- latest_error.log
- latest_warn.log
<!--输出到日志文件,滚动分割日志文件,自动打包gz-->
<!-- fileName 如果指定 就不能动态 不指定就会根据filePattern动态生成-->
<RollingFile name="Info_File" fileName="${baseDir}/latest_info.log" filePattern="${baseDir}/info_history/$${date:yyyy-MM-dd}/%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="${LOG_PATTERN}"/>
<LevelRangeFilter minLevel="INFO" maxLevel="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
<Policies>
<!--默认一天一个文件-->
<!-- <TimeBasedTriggeringPolicy />-->
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<!--一天内大于size就单独分隔-->
<SizeBasedTriggeringPolicy size="1 GB"/>
<!-- <SizeBasedTriggeringPolicy size="1 kb"/>-->
</Policies>
<!--删除超过20秒创立的文件-->
<DefaultRolloverStrategy>
<Delete basePath="${baseDir}/info_history" maxDepth="2">
<IfFileName glob="*/*.log.gz">
<IfLastModified age="PT20S">
</IfLastModified>
</IfFileName>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
使用:AsyncLogger
要引用disruptor
<AsyncLogger name="com.test.demo" level="trace" includeLocation="true">
<AppenderRef ref="Info_File"/>
</AsyncLogger>
使用:Async Appender
<Async name="Async">
<AppenderRef ref="Info_File"/>
</Async>
<AppenderRef ref="Async"/>
Async Appenders use ArrayBlockingQueue internally and do not need the disruptor jar on the classpath Async Appenders 用的是ArrayBlockingQueue队列,不需要引用其他框架
Loggers All async, Async Appender,Sync 三者的吞吐量对比
所以建议 Making All Loggers Asynchronous
1.引入
<!-- 引入异步框架 如果不需要用async logger 可不引用 -->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.4</version>
</dependency>
2.yaml配置
log4j2:
contextSelector: org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
除了上述设置所有logger为异步之外,还可以单独设置
1.引入
<!-- 引入异步框架 如果不需要用async logger 可不引用 -->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.4</version>
</dependency>
2.log4j2.xml 设置AsyncLogger
<AsyncLogger name="com.test.demo" level="trace" includeLocation="true">
<AppenderRef ref="Info_File"/>
</AsyncLogger>
注意事项:
1.删除过期文件:
<DefaultRolloverStrategy>
<Delete basePath="${baseDir}/info_history" maxDepth="2">
<IfFileName glob="*/*.log.gz">
<IfLastModified age="PT20S">
</IfLastModified>
</IfFileName>
</Delete>
</DefaultRolloverStrategy>
删除过期的时间格式: Examples:
"PT20S" -- parses as "20 seconds"
"PT15M" -- parses as "15 minutes" (where a minute is 60 seconds)
"PT10H" -- parses as "10 hours" (where an hour is 3600 seconds)
"P2D" -- parses as "2 days" (where a day is 24 hours or 86400 seconds)
"P2DT3H4M" -- parses as "2 days, 3 hours and 4 minutes
类使用说明链接: logging.apache.org/log4j/2.x/l…
2.log4j.xml 小记
<Configuration xmlns:xi="http://www.w3.org/2001/XInclude"
status="warn" name="XInclude">
其中status 是指log4j自身框架的日志输出级别