极简工具箱

免费在线工具 · 本地计算 · 无需上传

日志切割怎么做:logrotate 配置与磁盘写满的预防

服务跑三个月,磁盘突然 100%——日志文件涨到 20GB 没人管。logrotate 是系统自带、配置五行就能解决问题的工具。

广告位(百度联盟)

一、基本原理

logrotate 由 cron/timer 每天触发,按配置把当前日志改名归档、创建新文件、删除超期归档,并可选地通知服务重新打开日志文件。

配置文件在 /etc/logrotate.conf(全局)与 /etc/logrotate.d/(各服务)。

二、一个完整配置

/var/log/myapp/*.log {
    daily
    rotate 7
    size 100M
    compress
    delaycompress
    missingok
    notifempty
    dateext
    create 0640 www-data www-data
    sharedscripts
    postrotate
        systemctl reload myapp > /dev/null 2>&1 || true
    endscript
}

逐项说明:

指令作用
daily / weekly / monthly切割周期
rotate 7保留 7 份,多的删掉
size 100M超过 100M 也切(与 daily 同时写时,满足其一就切)
compress归档用 gzip 压缩
delaycompress延后一轮再压缩,避免刚写完的文件被压
missingok文件不存在不报错
notifempty空文件不切
dateext用日期做后缀,而不是 .1 .2
create 0640 user group切完新建文件并设权限属主
sharedscripts多个文件只执行一次脚本

三、最关键的 postrotate

日志文件被改名后,正在写它的进程仍然持有旧文件的句柄,会继续往 myapp.log.1 里写,新文件一直是空的,磁盘也不会释放。所以必须让进程重新打开日志:

postrotate
    systemctl reload myapp
endscript

或者给进程发信号(Nginx 是 kill -USR1):

postrotate
    [ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript

四、copytruncate 的取舍

有些程序不支持重开日志,可以用:

copytruncate

它先复制文件再清空原文件,进程句柄不变。缺点是复制与清空之间写入的日志会丢,高写入量场景不推荐。

五、手动测试

# 预演,只显示会做什么,不实际执行
logrotate -d /etc/logrotate.d/myapp

# 强制执行一次(忽略周期限制)
logrotate -f /etc/logrotate.d/myapp

# 看状态记录
cat /var/lib/logrotate/status

改完配置一定先 -d 预演,看清楚它会动哪些文件。

六、几个常见坑

七、容器环境的做法

容器里通常没有 cron,常见方案:

八、配套监控

切割只是控制增长,不是解决增长。建议同时做:

小结

daily + rotate 7 + compress + postrotate reload 是标准配置;切完必须让进程重开日志,否则旧文件继续变大;容器里没有 cron,优先把日志交给 stdout 收集。

本文相关工具(本地计算,无需上传)

更多使用教程