CentOS 上 Nginx 日志清理与轮转最佳实践
一 核心原则与准备
二 推荐方案 Logrotate 标准配置
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 640 nginx adm
sharedscripts
postrotate
# 兼容 pid 文件或进程查找
if [ -f /run/nginx.pid ]; then
kill -USR1 $(cat /run/nginx.pid 2>/dev/null)
else
kill -USR1 $(ps axu | awk '/nginx: master process/ && !/grep/ {print $2; exit}')
fi
endscript
}
logrotate -d /etc/logrotate.d/nginxlogrotate -vf /etc/logrotate.d/nginx三 Docker 与无 Logrotate 环境的替代方案
#!/usr/bin/env bash
set -euo pipefail
LOG_DIR="/var/log/nginx"
DAYS_TO_KEEP=30
YESTERDAY=$(date -d "yesterday" +%Y-%m-%d)
cd "$LOG_DIR" || { echo "日志目录不存在: $LOG_DIR"; exit 1; }
# 1) 轮转
[ -f access.log ] && mv -f access.log "access_${YESTERDAY}.log"
[ -f error.log ] && mv -f error.log "error_${YESTERDAY}.log"
# 2) 重新打开日志(平滑,不中断服务)
if [ -f /run/nginx.pid ]; then
kill -USR1 "$(cat /run/nginx.pid)"
else
kill -USR1 "$(ps axu | awk '/nginx: master process/ && !/grep/ {print $2; exit}')"
fi
# 3) 压缩昨天的日志
gzip -f "access_${YESTERDAY}.log" 2>/dev/null || true
gzip -f "error_${YESTERDAY}.log" 2>/dev/null || true
# 4) 清理超期日志(按修改时间)
find "$LOG_DIR" -type f \( -name "access_*.log*" -o -name "error_*.log*" \) -mtime +${DAYS_TO_KEEP} -delete
echo "$(date '+%F %T') 轮转与清理完成(保留 ${DAYS_TO_KEEP} 天)" >> "$LOG_DIR/rotate_cleanup.log"
chmod +x /usr/local/bin/rotate_nginx_logs.sh0 0 * * * /usr/local/bin/rotate_nginx_logs.shdocker restart nginx 作为兜底(会带来短暂中断)。四 紧急处置与安全注意
> /var/log/nginx/access.log 或 truncate -s 0 /var/log/nginx/access.logrm 当前正在写入的 access.log/error.log 而不通知 Nginx 重新打开,可能导致写入失败或文件句柄异常。docker restart nginx 会影响可用性,优先尝试 kill -USR1 或 nginx -s reopen。五 监控与容量规划