日志把磁盘写满了?logrotate 实战与按天保留策略

Linux运维 发布于 2026-08-15 · 分类:Linux 运维 · 阅读 4,561

一台 20G 系统盘的小机器,某天 df -h 发现使用率 70%+,一查 du -sh /*,全是日志:自定义目录下的 access/error 日志从来没配过轮转,单文件几百 MB。

先救急:按日期过滤保留最近 7 天

Nginx 的 access 日志时间形如 [29/Aug/2026:12:01:50 +0800],error 日志形如 2026/08/29 12:00:09 [error]。用 awk 按日期过滤:

# access: 只保留 [dd/Mon/yyyy: 中 yyyy-mm-dd >= cutoff 的行
# error : 只保留行首 yyyy/mm/dd >= cutoff 的行
gawk -v cutoff=20260822 -f acc.awk access.log > access.log.tmp && mv access.log.tmp access.log

替换文件后,Nginx 还握着旧文件句柄在写,需要发 USR1 信号让它重新打开日志:

kill -USR1 $(cat /var/run/nginx.pid)
注意:直接 > access.log 清空也行,但会丢掉最近的日志;按日期过滤更可控。过滤时用临时文件再 mv,避免边写边截断。

再治本:配置 logrotate

系统自带 /etc/logrotate.d/,每日由 /etc/cron.daily/logrotate 跑一次。给自定义日志目录加一个:

/data/nginx/log/*.log
/data/ad/logs/*.log
/data/logs/*.log {
    daily
    rotate 7
    missingok
    notifempty
    compress
    delaycompress
    dateext
    dateformat -%Y%m%d
    create 640 root root
    sharedscripts
    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
    endscript
}

验证

logrotate -d /etc/logrotate.d/nginx-data   # 干跑,只打印不执行
logrotate -f /etc/logrotate.d/nginx-data   # 强制跑一次

做完这一套,磁盘从 70% 降到 60% 左右,之后每天自动轮转,再也不用手动清。

— 本文为个人运维笔记,如有疏漏欢迎指正。