服务器跑得好好的,突然发现磁盘满了,服务开始报错。一查才发现,是应用日志文件涨到了几十个GB。这种情况在运维中太常见了,而解决它的关键,就是日志轮转。
什么是日志轮转
简单说,日志轮转就是把一个不断增长的日志文件“切分”成多个小文件,并定期清理过期的旧日志。比如今天生成 access.log,明天就变成 access.log.1,再往后变成 access.log.2.gz,老的日志可以自动删除或压缩归档。
这样做有两个好处:一是防止单个日志文件无限膨胀,吃光磁盘;二是方便管理,按天、按大小分开查看,排查问题更清晰。
常见的轮转方式
Linux 下最常用的工具是 logrotate。它不依赖应用程序,通过配置文件定义策略,定时检查并处理日志。
比如你想每天轮转 Nginx 的访问日志,保留7天,超过100MB就提前触发,还能自动通知服务重载,配置长这样:
/var/log/nginx/*.log {
daily
missingok
rotate 7
compress
delaycompress
notifempty
maxsize 100M
postrotate
systemctl reload nginx > /dev/null 2>&1 || true
endscript
}
这个配置放在 /etc/logrotate.d/nginx 里,系统会自动执行。其中 postrotate 到 endscript 之间的命令会在轮转后运行,告诉 Nginx 使用新的日志文件。
应用自身支持轮转
有些服务自带轮转功能。比如 Java 应用常用 Logback 或 Log4j2,可以直接在配置文件里设置按天或按大小拆分。
Logback 的配置片段:
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>app.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d %level [%thread] %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>
这段配置会让日志每天生成一个新文件,保留最近30天。
别忘了权限和测试
配置写完不是就完了。得确认 logrotate 有权限读写日志目录,不然轮转失败也没提醒。可以用 logrotate -d /etc/logrotate.conf 模拟运行,看看会不会报错。
还有个小细节:如果服务以特定用户运行(比如 www-data),轮转后的新日志也得确保该用户能写入,否则程序可能因无法打日志而异常。
轮转不是万能的
开了轮转,不代表就能放任不管。压缩归档虽然省空间,但查老日志时得先解压,效率低。如果业务对日志分析要求高,建议结合 ELK 这类系统,把日志采集到专门平台,本地只保留短期文件。
另外,日志级别也要合理设置。调试信息全打开,哪怕轮转再勤快,磁盘照样扛不住。