对于日志的认知,不同阶段是不一样的。在大学刚学Java的时候,根本不理解日志的用处,甚至觉得日志和控制台输出的内容不一样吗。后来学到log4j,通过配置输出INFO、ERROR不同等级的日志,才明白,原来日志和控制台输出是不一样。
后来参加工作,在项目中了解slf4j,作为门面设计可以在项目中不用修改代码,就可以替换不同的日志框架(例如log4j替换logback),具体可以参考文章:slf4j、log4j、log4j2、logback到底用哪些jar。
随着接触的项目越来越多,日志已经成为了排查程序故障最重要的一环。但是一个问题也浮现了出来,如何管理日志的生命周期? 。会多时候会出现日志文件把用户目录磁盘写满导致系统异常,以及日志目录下可以看到几年前日志文件的情况。
所以,对于日志的生命周期管理也是重中之重。对于上述情况,通常有两种手段。一是通过shell脚本定期清理日志,但是这种做法的弊端就是需要在每台主机部署脚本。二是在日志的配置文件中,设置清理的参数。今天主要讲讲方法二,如何通过配置实现日志生命周期的管理。
log4j和log4j2是Java初期最先接触的,也是之前项目中最常用的日志框架。这里就用log4j2来实践一下日志文件生命周期的管理。
首先,我们引入log4j2、slf4j和lombok的依赖。
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.20.0</version>
</dependency>
<!-- Log4j2 SLF4J Binding -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.20.0</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
然后配置log4j2.xml文件,整体配置如图所示:
我们拿出其中的Appender部分,来看看是如何实现日志清理策略的。
<RollingFile name="InfoFile" fileName="${log.path}/info.log" filePattern="${log.path}/info-%d{yyyy-MM-dd-HH-mm}.log.gz">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n</Pattern>
</PatternLayout>
<Policies>
<!-- 基于时间的触发策略 -->
<TimeBasedTriggeringPolicy />
</Policies>
<DefaultRolloverStrategy>
<!-- 设置清理策略 -->
<Delete basePath="${log.path}" maxDepth="1">
<IfFileName glob="info-*.log.gz" />
<!-- 删除 2 分钟前的日志文件 -->
<IfLastModified age="2m" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
只说其中的一部分配置:filePattern:指定滚动日志的存储路径和命名规则,日志文件会按时间滚动,每分钟生成一个文件,压缩为 .gz 格式。
主要通过 DefaultRolloverStrategy 配置日志文件的清理规则。basePath指定日志文件的存储目录。maxDepth限制清理目录的深度,防止误删其他文件。
IfFileName匹配要清理的文件,glob 使用通配符匹配。这里IfLastModified的age属性表示删除最后修改时间早于2分钟的文件。这里m表示分钟,h表示小时,d表示天。
使用while True实现持续输出日志的程序,代码如下:
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Log4jTest {
public static void main(String[] args) throws InterruptedException {
while (true) {
Thread.sleep(10 * 100);
log.info("aqi");
}
}
}
启动程序,日志持续写入info.log中,log4j2每分钟都会生成滚动的日志文件,然后会触发日志清理策略,如图所示:
顺便一提,在上面的Policies设置成按时间滚动,但为了避免单个日志文件在单位时间内过大或过小,还可以通过SizeBasedTriggeringPolicy标签,设置日志文件的大小。
<SizeBasedTriggeringPolicy size="10MB"/>
对于常用的logback也可以通过同样的方式,设置日志滚动和清理策略,对于使用了slf4j框架的应用来说,只需要将所有log4j2的依赖替换成logback的依赖即可,无需修改代码。
在实际生产中,通常会是以天滚动日志。但是通常我不会设置清理策略,前提是磁盘足够,,因为如果遇到一些问题的时候,可能需要对过去的日志进行分析。所以尽量保留两个月内的日志,合理的设置清理策略。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。