nginx 缓存日志可被 logrotate 切割,前提是使用固定绝对路径的文本日志(如 /var/log/nginx/cache_access.log),并配置对应 logrotate 规则及 postrotate 中 kill -usr1 通知 nginx 重开日志文件。

Nginx 本身不生成“缓存日志”(如 proxy_cache、fastcgi_cache 的命中/未命中记录),它默认不会自动记录缓存行为。所以所谓“Nginx 缓存日志”,通常指两类情况:
-
你手动配置了
log_format+access_log,在日志中嵌入了$upstream_cache_status等变量,把缓存状态写进常规 access.log; -
你使用了第三方模块(如 nginx-module-vts)或自定义 Lua 脚本,将缓存相关事件单独输出到一个独立日志文件(例如
/var/log/nginx/cache_access.log)。
只要这个缓存日志是以普通文本文件形式持续追加写入的(路径固定、权限可控),logrotate 就能切割它——和切割 access.log 完全一样,无需特殊处理。
✅ 确保缓存日志路径明确且稳定
在 nginx.conf 中,确认你已显式定义缓存日志路径,例如:
http {
log_format cache_fmt '$time_iso8601 $remote_addr "$request" $status '
'$upstream_cache_status $body_bytes_sent';
access_log /var/log/nginx/cache_access.log cache_fmt;
}
⚠️ 关键要求:
- 路径必须是绝对路径(如
/var/log/nginx/cache_access.log); -
不能含变量或动态路径(如
$hostname/cache.log),否则 logrotate 无法匹配; - 确保 Nginx 进程对目录有写权限,且 logrotate 运行时能读写该文件。
✅ 配置 logrotate 切割缓存日志(按天)
新建 /etc/logrotate.d/nginx-cache(文件名任意,但建议语义清晰):
/var/log/nginx/cache_access.log {
daily
missingok
notifempty
rotate 30
compress
delaycompress
dateext
dateyesterday
dateformat -%Y-%m-%d
create 0644 nginx nginx
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 $(cat /var/run/nginx.pid)
fi
endscript
}
? 说明:
-
sharedscripts:避免多个日志(如同时切access.log和cache_access.log)重复发多次 USR1; -
dateyesterday+dateformat:让归档文件名显示“昨天日期”,例如cache_access.log-2026-10-07,更符合运维直觉; -
create 0644 nginx nginx:确保新日志文件权限正确(根据你实际运行 Nginx 的用户调整,常见为www-data或nginx); -
postrotate … kill -USR1:通知 Nginx 重新打开日志文件句柄,否则仍往旧文件写。
✅ 验证与生效
-
语法检查(调试模式)
sudo logrotate -d /etc/logrotate.d/nginx-cache
查看输出是否报错,尤其关注“file not found”或“permission denied”。
-
强制执行一次(立即测试)
sudo logrotate -vf /etc/logrotate.d/nginx-cache
执行后检查:
- 是否生成
cache_access.log-2026-10-07(或类似带昨日日期的文件); - 原
cache_access.log是否变为空文件; -
tail -f /var/log/nginx/cache_access.log是否继续有新日志写入。
- 是否生成
-
确认 cron 已接管
logrotate 默认由/etc/cron.daily/logrotate每日凌晨触发,无需额外加 crontab。可查状态:ls -l /etc/cron.daily/logrotate
❗ 注意:不是所有“缓存日志”都适合 logrotate
- 如果你用的是
proxy_cache_path ... use_temp_path=off;配合open_file_cache,这些是磁盘缓存文件,不是文本日志,logrotate 不适用; - 如果你用 Prometheus + nginx-vts-exporter 抓取指标,那是 HTTP 接口数据,也不走文件日志;
- 若日志由 systemd-journald 收集(如
journalctl -u nginx),则应配置 journald 的SystemMaxUse,而非 logrotate。
不复杂但容易忽略:核心就三点——路径写死、logrotate 配对、USR1 通知到位。











