Nginx 日志轮转维护:USR1、logrotate 定时任务与保留次数

日志改名之后,Nginx 可能仍写旧文件。检查 USR1、PID 路径、logrotate 定时调用和归档保留次数,避免把 daily 当成定时任务或磁盘限额。

·6 minNginxlogrotateVPSLinux
把应用部署到土耳其|BRNCHOST · 土耳其 VDS
云服务器,积分可续期|雨云 · 国内外节点 · 积分兑换权益
低价年付,大流量 VPS|RackNerd · SSD 存储 · 1Gbps 端口
香港轻量,搭个小站|晚安云 · 香港云服务器
香港 VPS,大带宽可选|野草云 · BGP 直连
大陆访问,精品线路|搬瓦工 · CN2 GIA / CTGNet 套餐
资料归档,交给 AI 整理|WorkBuddy · 本地文件处理
建站起步,先看应用镜像|腾讯云 · 轻量应用服务器
CN2 GIA,中国方向优化|DMIT · Premium 网络
双 ISP 原生住宅 IP|丽萨主机 · 美国 9929 精品线路
高频 CPU,多地部署|Evoxt · 云服务器 · 每周异地备份
京东云轻量云主机:129元/年,新人专享,限购1台

VPS 的磁盘忽然满了,先看看 Nginx 的 access.log 和 error.log。如果它们一直增长却没有归档,删除旧备份只能暂时腾出空间;还应检查日志轮转任务是否运行,以及 Nginx 是否在轮转后打开了新文件。

下面使用宿主机安装的 Nginx 和 logrotate,示例日志目录为 /var/log/nginx。容器把日志写到标准输出、面板管理独立日志目录,或机器上有多个 Nginx 实例时,要按各自的日志和进程管理方式处理,不能照抄目录与 PID 文件。

改名之后,Nginx 还可能写旧文件

Nginx 已经打开了日志文件。执行 mv 改名不会让这个文件描述符自动指向新的 access.log,进程仍可能往改名后的文件写。直接删除一个仍被进程打开的文件,也可能无法立即释放它占用的磁盘空间。

正常轮转先改名,再向 Nginx 主进程发送 USR1,让它重新打开日志。这个动作不需要为轮转而重启整个服务;HUP 用于重载配置,与 USR1 的用途不同。Nginx 控制文档说明了两种信号的区别。

先检查系统已经提供的规则

发行版安装包可能已放入 /etc/logrotate.d/nginx。先读它,并检查其他配置是否也匹配同一批日志;不要另外新建一个规则,让两个任务轮转相同文件。还要核对 Nginx 实际的日志路径、运行用户和 pid 设置。

以下是规则示例,适用于日志位于 /var/log/nginx、worker 使用 www-data、系统存在 adm 组、主进程 PID 文件为 /run/nginx.pid 的机器。保存前把不符合本机的值改掉;PID 文件应位于可信目录,由服务正确维护。

/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        if [ -s /run/nginx.pid ]; then
            pid=$(cat /run/nginx.pid) || exit 1
            case "$pid" in
                ''|*[!0-9]*|0|1) exit 1 ;;
            esac
            kill -USR1 "$pid"
        fi
    endscript
}

脚本先读取并检查 PID,再发送信号,读取失败或 PID 明显不合法时不继续执行。PID 文件缺失时会跳过信号,但跳过不等于轮转完成:如果 Nginx 实际仍在运行,就应查明路径为什么不对。不要用 || true 把所有发送信号的错误都隐藏掉。

create 的用户、组和权限要与本机设置匹配。delaycompress 延后一轮压缩最新归档,给仍可能写旧文件的进程留出时间,但它不能补救错误的 PID 文件或一直没有执行的重新打开操作。各选项可以查 logrotate 手册,并以机器安装版本的 man logrotate 为准。

daily 与 rotate 14 不是磁盘限额

daily 指定按日判断轮转条件,不会创建定时任务。机器仍需要 cron 或 systemd timer 定期调用 logrotate。rotate 14 保留的是轮转次数,不能无条件解释成十四天;空日志不轮转、任务漏跑或增加大小触发条件,都会改变归档覆盖的时间。

如果日志一天就能撑满磁盘,仅设 daily 不够。可以评估与时间条件配合的 maxsize,但它也要等 logrotate 被调用时才检查,不是实时硬限额。提高检查频率后,还要重新计算保留次数,防止同一天轮转多次使旧日志提前删除。

不要把 copytruncate 当成无需通知 Nginx 的通用替代。复制与截断之间存在日志丢失的窗口。能正常重新打开日志的 Nginx,优先沿用改名加 USR1 的流程。

如果正在选 VPS,除了 CPU 和内存,也要给日志、上传文件与备份分别留出容量。可以从 雨云查看云服务器配置,优惠码 KuZhuJi;具体优惠资格和价格以购买页面为准。轮转减少日志积累,但不会增加套餐本身的磁盘空间。

检查规则,也检查定时任务

修改后先用调试模式看规则。下面假定系统已使用 /etc/logrotate.conf 作为主配置;调试模式不会实际轮转或更新状态文件:

sudo logrotate -d /etc/logrotate.conf

观察是否读取了 Nginx 规则、是否提示重复匹配、目录权限错误,以及状态文件中记录的轮转时间。使用 systemd timer 的系统还可以检查:

systemctl list-timers --all logrotate.timer
systemctl status logrotate.timer
journalctl -u logrotate.service --since today

没有这个 timer 时,检查本机 cron 或面板的调度安排,不能据此直接断定没有定时任务。容器内安装了 logrotate,也不代表容器会启动 cron。

需要实际验证轮转时,先保留配置,并安排合适的维护时间。-f 会强制执行,别把它放进每小时巡检,也不要不加区分地强制轮转所有服务。若仅验证 Nginx 规则,应先确认该文件包含所需设置,并了解它脱离主配置后不会自动获得主配置里的全局选项。

sudo logrotate -v -f /etc/logrotate.d/nginx

轮转后发起一条正常访问,确认它进入新日志,再核对新文件的所有者与权限、旧文件是否继续增长,以及任务输出是否报告错误。归档存在,只能说明文件被处理过;新请求确实写入新文件,才说明重新打开这一步生效。

定期检查磁盘余量和归档覆盖时间。日志可能含 URL 参数、IP 地址或其他敏感信息,归档同样需要限制读取权限;需要保留审计记录时,另行安排符合保留要求的存储,不能靠本机十四次轮转承担长期归档。