nginx多站点日志轮转需用sharedscripts确保postrotate仅执行一次,避免重复reload;须配合delaycompress、create、dateext等参数,并用systemctl reload替代kill -usr1,防止服务抖动与日志丢失。

在大规模多站点环境下(比如 Nginx 托管上百个虚拟主机,日志路径为 /var/log/nginx/site-a.access.log、/var/log/nginx/site-b.access.log …),若每个站点日志单独配置一个 postrotate 脚本,logrotate 会为每个匹配文件重复执行 reload 操作——这不仅低效,还可能触发服务抖动。启用 sharedscripts 是关键优化手段,它让整个配置块只运行一次 postrotate,大幅降低系统开销。
sharedscripts 的作用与适用场景
sharedscripts 不是“提升速度”的魔法开关,而是改变脚本执行粒度的控制机制:它确保 postrotate 和 prerotate 中的命令在整个 glob 匹配块内仅执行一次,而非对每个日志文件各跑一遍。这对以下情况尤其必要:
- 所有站点共享同一进程(如单实例 Nginx),只需一次
nginx -s reload或systemctl reload nginx - 日志路径使用通配符(如
/var/log/nginx/*.access.log),匹配数十甚至上百个文件 - postrotate 中调用的是重量级操作(如远程 API 通知、数据库写入、复杂 shell 判断)
正确配置 sharedscripts 的要点
错误配置反而会导致 reload 失败或静默跳过。必须注意以下硬性约束:
- 必须将
sharedscripts和postrotate放在同一配置块内,且sharedscripts要在postrotate前声明 -
postrotate内不能使用$1(因为 shared 模式下无“当前文件”概念),只能执行不依赖具体路径的全局操作 - 所有命令需用绝对路径,例如
/usr/bin/systemctl而非systemctl - 务必以
endscript显式结束,漏写会导致语法错误且整个配置块失效
示例(/etc/logrotate.d/nginx-multi):
PyCharm 2026.2.0.1 Linux版提供 JetBrains 官方 2026.2.0.1 版本安装包,适合需要指定 PyCharm 版本进行 Python 项目开发、运行和调试的用户。
/var/log/nginx/*.access.log /var/log/nginx/*.error.log {
daily
missingok
notifempty
rotate 30
compress
delaycompress
sharedscripts
postrotate
/usr/bin/systemctl reload nginx > /dev/null 2>&1 || true
endscript
}
避免常见陷阱
sharedscripts 常被误用,导致轮转后服务未重载或报错:
- 误在
postrotate里写kill -USR1 `cat /var/run/nginx.pid`—— 若 pid 文件权限受限或路径错误,reload 会失败;推荐统一用systemctl reload,更健壮 - 把多个不相关的日志路径混在一个块里(如同时包含
nginx和php-fpm日志),却共用一个postrotate,造成语义混乱 - 未加
|| true或错误重定向,导致某条命令失败时整个 postrotate 中断,但 logrotate 不报错,现象是“轮转成功但服务没 reload” - 用 glob 匹配时,某次运行恰好没有符合的文件(如某个站点临时停用),整个配置块被跳过——
postrotate不执行,rotate计数也不增加
配合其他参数提升稳定性
sharedscripts 单独使用不够,需搭配以下参数形成完整方案:
-
delaycompress:避免压缩和 reload 同时发生竞争,确保新日志已写入再压缩旧档 -
create 0644 www-data adm:轮转后自动重建日志文件,防止因权限问题导致 Nginx 写入失败 -
dateext+dateformat -%Y%m%d:用日期后缀替代数字序号,便于按时间归档和清理 - 慎用
copytruncate:它绕过 reload,适合无法 reopen 的程序,但在多站点 Nginx 场景中会丢失部分日志,不推荐替代 sharedscripts
验证是否生效:手动运行 logrotate -f -v /etc/logrotate.d/nginx-multi,观察输出中 “running postrotate script” 是否只出现一次,且末尾无 error。










