systemd 默认不轮转 Nginx 日志,需选择 logrotate(推荐,文件写入+定时切割)或 journald(stdout/stderr+原生轮转)之一;二者不可混用。

systemd 管理 Nginx 服务时,默认不会自动轮转其日志(/var/log/nginx/access.log 和 error.log),因为日志由 Nginx 进程自身写入,而 systemd-journald 只接管标准输出/错误(若配置为 StandardOutput=journal)。要实现可靠、可控的日志轮转,需明确区分两种路径:一是让 Nginx 继续直接写文件,配合 logrotate;二是改用 systemd-journald 接管并利用 journalctl 的原生轮转机制。实际生产中,前者更常见、更灵活。
方案一:Nginx 写文件 + logrotate(推荐)
这是最主流、最易调试的方式。Nginx 保持原有日志配置不变,交由 logrotate 定期切割、压缩、清理。
操作步骤如下:
- 确认 Nginx 日志路径,通常为
/var/log/nginx/*.log - 创建或编辑
/etc/logrotate.d/nginx,内容示例:
/var/log/nginx/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 0644 nginx nginx
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}关键说明:
-
daily:每天轮转一次;也可用weekly或size 100M -
rotate 30:保留最近 30 个归档日志(含当前) -
create 0644 nginx nginx:轮转后重建日志文件,权限属主正确 -
postrotate ... kill -USR1:通知 Nginx 重新打开日志文件,避免丢失新日志
测试配置是否有效:sudo logrotate -d /etc/logrotate.d/nginx(调试模式)或 sudo logrotate -f /etc/logrotate.d/nginx(强制执行一次)。
方案二:Nginx 输出到 stdout/stderr + systemd-journald
适用于容器化部署或希望统一用 journalctl 查日志的场景。需修改 Nginx 服务单元配置,使其不写磁盘日志,全部交由 journald 处理。
步骤如下:
- 编辑 Nginx 的 systemd 单元文件:
sudo systemctl edit nginx(推荐使用 drop-in) - 添加以下内容:
[Service] StandardOutput=journal StandardError=journal SyslogIdentifier=nginx # 关闭 Nginx 自己的日志(可选,但建议) ExecStartPre=/bin/sh -c 'sed -i "s|access_log .*;|access_log /dev/stdout;|g" /etc/nginx/nginx.conf' ExecStartPre=/bin/sh -c 'sed -i "s|error_log .*;|error_log /dev/stderr;|g" /etc/nginx/nginx.conf'
然后重载并重启:sudo systemctl daemon-reload && sudo systemctl restart nginx。
journald 会自动轮转,配置在 /etc/systemd/journald.conf 中,常用参数:
-
SystemMaxUse=512M:限制日志总占用空间 -
MaxRetentionSec=2week:日志最长保留时间 -
Compress=yes:启用压缩
查看日志:journalctl -u nginx -n 100;实时跟踪:journalctl -u nginx -f。
验证与排错要点
无论采用哪种方式,都应验证日志是否按预期工作:
- 检查日志文件或 journal 是否持续有新条目:
tail -f /var/log/nginx/access.log或journalctl -u nginx -f - 确认 logrotate 是否真正触发(查看
/var/lib/logrotate/status中的时间戳) - Nginx 收到
USR1信号后,旧日志应停止写入,新日志文件被创建(注意权限和 SELinux 上下文) - 若用 journal,确保
Storage=persistent已设置(默认可能为auto,导致重启后日志丢失)
常见问题:logrotate 后 Nginx 仍往旧文件写 —— 多因未发送 USR1 或进程未识别该信号,可用 ps aux | grep nginx 确认主进程 PID 是否与 /var/run/nginx.pid 一致。
小结:按需选择,不强求统一
logrotate 方案成熟稳定,支持精细控制(按大小、时间、压缩策略),适合传统服务器;journald 方案轻量简洁,便于集中采集(如搭配 fluentd 或 systemd-cat),适合云原生环境。两者不可混用——Nginx 不应同时写文件又输出到 stdout,否则日志重复且难以追踪。










