一台 20G 系统盘的小机器,某天 df -h 发现使用率 70%+,一查 du -sh /*,全是日志:自定义目录下的 access/error 日志从来没配过轮转,单文件几百 MB。
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,避免边写边截断。
系统自带 /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
}
rotate 7:保留 7 份(配合 daily 就是 7 天)。delaycompress:最近一个轮转文件先不压缩,避免程序还在写。postrotate 里发 USR1,让 Nginx 切到新文件。logrotate -d /etc/logrotate.d/nginx-data # 干跑,只打印不执行
logrotate -f /etc/logrotate.d/nginx-data # 强制跑一次
做完这一套,磁盘从 70% 降到 60% 左右,之后每天自动轮转,再也不用手动清。
— 本文为个人运维笔记,如有疏漏欢迎指正。