二进制安装的 nginx 需手动实现日志切割:先 mv 重命名日志文件,再执行 nginx -s reopen 通知进程重新打开日志,配合 cron 每日自动执行,并验证归档与写入是否正常。

直接用二进制安装的 Nginx 默认不带 logrotate 集成,日志切割得靠自己写脚本实现。核心是:让 Nginx 重新打开日志文件(通过信号或 reload),同时安全地重命名旧日志。
日志切割脚本的关键逻辑
二进制安装的 Nginx 没有包管理器协助,不能依赖系统 logrotate 的 postrotate 脚本自动发信号。必须在脚本里显式执行:kill -USR1 或 nginx -s reopen,通知 worker 进程关闭并重新打开日志文件。
- 先移动(mv)当前 access.log 和 error.log 到带时间戳的归档名(如 access.log-20240520)
- 再执行
nginx -s reopen(确保 nginx 二进制路径正确,比如/usr/local/nginx/sbin/nginx) - 可选:用 gzip 压缩归档日志,节省空间
- 加判断:检查 nginx 进程是否存在、日志目录是否可写,避免静默失败
一个可用的 daily-cut.sh 示例
假设 Nginx 安装在 /usr/local/nginx,日志在 /usr/local/nginx/logs/:
#!/bin/bash NGINX_BIN="/usr/local/nginx/sbin/nginx" LOG_DIR="/usr/local/nginx/logs" DATE=$(date +\%Y\%m\%d) <h1>切割 access.log 和 error.log</h1><p>for log in access.error; do if [ -f "$LOG_DIR/$log.log" ]; then mv "$LOG_DIR/$log.log" "$LOG_DIR/$log.log-$DATE" fi done</p><h1>通知 nginx 重新打开日志</h1><p>if pgrep -x "nginx" > /dev/null; then $NGINX_BIN -s reopen 2>/dev/null fi</p><h1>压缩昨日日志(可选)</h1><p>gzip "$LOG_DIR/access.log-$DATE" "$LOG_DIR/error.log-$DATE" 2>/dev/null </p>
注意:access.error 是笔误?应为 access 和 error 分开处理;实际使用时请按真实日志名调整。
配合 cron 自动执行
把脚本加入 crontab,每天凌晨 0 点运行:
0 0 * * * /path/to/daily-cut.sh >/dev/null 2>&1
- 确保脚本有可执行权限:
chmod +x daily-cut.sh - 建议用绝对路径调用 nginx 二进制,避免 PATH 环境问题
- 首次运行前手动测试脚本,确认日志能正常归档且 Nginx 不报错
常见坑和验证方法
切完日志后,务必验证是否生效:
- 检查
ls -l logs/是否出现带日期的新文件 - 执行
ps aux | grep nginx确认 master 进程仍在,worker 未异常退出 - 访问一次站点,看新
access.log是否有新增记录(不是旧文件) - 如果日志没写入新文件,大概率是
-s reopen失败——检查 nginx 用户是否有权限写 logs 目录,以及 nginx 是否以该用户运行
不复杂但容易忽略细节,重点盯住信号是否真正送达、文件权限是否匹配、路径是否写错。











