logrotate 规则应按服务拆分至 /etc/logrotate.d/ 下独立文件(如 /etc/logrotate.d/nginx),配置需匹配日志路径、权限、信号处理及压缩策略,并通过 -d、-f 和状态文件三步验证生效。

logrotate 的具体规则不是写在主配置文件里硬改,而是按服务/日志类型拆到 /etc/logrotate.d/ 下的独立文件中——这样既避免冲突,又方便维护和升级。
怎么给某个服务(比如 Nginx)加专属轮转规则
直接在 /etc/logrotate.d/ 下建一个同名文件,比如 /etc/logrotate.d/nginx,内容按需填:
-
/var/log/nginx/*.log是要轮转的目标路径,支持通配符,但必须真实存在或至少路径可访问 -
daily和size 100M可共存,但size优先触发;如果只想按大小走,就别写daily -
create 0640 www-data adm中的用户和组必须和 Nginx 进程实际运行身份一致,否则新日志文件创建后 Nginx 写不进去,error.log会疯狂报“Permission denied” -
sharedscripts很关键:它确保postrotate只在整个匹配块(比如多个.log文件)全部轮转完后执行一次,而不是每个文件都触发一遍
postrotate 脚本里该发什么信号
不是所有服务都响应 USR1,也不是所有场景都该用 HUP。发错信号会导致服务中断或日志丢失:
- Nginx、rsyslog、syslog-ng 等支持
USR1:它让进程“重新打开日志文件”,不中断连接,最安全 - 旧版 Apache 或某些 Java 服务可能只认
HUP,但要注意HUP可能重启 worker,有短暂请求失败风险 - 如果服务根本不支持信号重载日志(比如某些自研二进制),就得用
copytruncate——它先复制当前日志再清空原文件,但存在毫秒级写入丢失可能 -
postrotate里务必加判断:[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid),避免 pid 文件不存在时命令失败导致整个轮转中断
为什么 delaycompress 必须配 compress
delaycompress 单独用无效,它只是个开关,依赖 compress 才起作用。它的逻辑是:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 第一次轮转:
access.log→access.log.1(不压缩) - 第二次轮转:
access.log→access.log.1,原来的access.log.1→access.log.2.gz(这时才压缩) - 这样能保证正在被服务追加写的
.1文件始终是明文,便于紧急排查,同时压缩已确定不再写入的更老文件 - 漏掉
compress,delaycompress就完全没效果,旧日志会一直以未压缩形式堆积
测试配置是否生效的三步验证法
别等 cron 自动跑,手动验证才能避开“配了等于没配”的坑:
- 语法检查:
logrotate -d /etc/logrotate.d/nginx(-d是 debug 模式,只模拟不执行,看输出有没有error或skipping) - 强制执行:
logrotate -f /etc/logrotate.d/nginx(-f强制触发,观察/var/log/nginx/下是否出现.1文件、权限是否正确、postrotate是否成功) - 查状态文件:
cat /var/lib/logrotate/status | grep nginx,确认最后轮转时间是否更新——这是 cron 实际执行时依赖的唯一依据
最容易被忽略的是状态文件的时间戳和 postrotate 中的条件判断。哪怕配置全对,只要 pid 文件路径错一位或者信号发错,Nginx 就继续往旧文件写,而新文件永远空着。

















