
shell 脚本-实现 NGINX 日志的每日自动化轮换与归档
#!/bin/bash
# =============================================================================
# auth:24/07/2025 by Oldhan
#
# log_rotate.sh
#
# 功能:
# 1. 将指定目录下 .log 文件按“日志名.YYYYMMDD.log”重命名
# 2. gzip 压缩并移动到 /data/nginx-logs/bak/ 备份目录
# 3. 给 nginx 主进程发送 USR1 信号,触发 reopen 日志
# 4. 将操作记录追加到执行日志 /data/sh/nginx/log_rotate.log
#
# 用法:
# chmod +x /data/sh/nginx/log_rotate.sh
# 每天午夜由 crontab 调用:0 0 * * * bash /data/sh/nginx/log_rotate.sh
# =============================================================================
set -euo pipefail
LOG_DIR="/data/nginx-logs"
BAK_DIR="$LOG_DIR/bak"
NGINX_PID="/usr/local/nginx/logs/nginx.pid"
EXEC_LOG="/data/sh/nginx/log_rotate.log"
DATE_SUFFIX="$(date -d 'yesterday' +%Y%m%d)"
LOG_FILES=(access_api.log access_mil.log access_food.log)
dirlog="$(dirname "$EXEC_LOG")"
if [ ! -d "$dirlog" ]; then
echo "[`date '+%Y-%m-%d %H:%M:%S'`] 脚本执行日志目录 $dirlog 不存在,正在创建…"
mkdir -p "$dirlog"
fi
if [ ! -d "$BAK_DIR" ]; then
echo "[`date '+%Y-%m-%d %H:%M:%S'`] 备份日志目录 $BAK_DIR 不存在,正在创建…"
mkdir -p "$BAK_DIR"
fi
exec >>"$EXEC_LOG" 2>&1
echo "===== 日志轮转开始: $(date '+%Y-%m-%d %H:%M:%S') ====="
for name in "${LOG_FILES[@]}"; do
f="$LOG_DIR/$name"
[ -e "$f" ] || {
echo "[`date '+%Y-%m-%d %H:%M:%S'`] 跳过:$f 不存在"
continue
}
rotated_name="${name%.*}.$DATE_SUFFIX.log"
if [ -e "$LOG_DIR/$rotated_name" ]; then
echo "跳过已存在备份:$LOG_DIR/$rotated_name"
continue
fi
mv "$f" "$LOG_DIR/$rotated_name"
echo "重命名:$f → $LOG_DIR/$rotated_name"
done
if [ -f "$NGINX_PID" ]; then
kill -USR1 "$(cat "$NGINX_PID")"
echo "向 nginx 发送 USR1,切换到新日志"
fi
for rotated in "$LOG_DIR"/*.${DATE_SUFFIX}.log; do
[ -e "$rotated" ] || continue
gzip -c "$rotated" > "$BAK_DIR/$(basename "$rotated").gz" \
&& rm -f "$rotated"
echo "压缩并备份:$rotated → $BAK_DIR/$(basename "$rotated").gz"
done
echo "===== 日志轮转结束: $(date '+%Y-%m-%d %H:%M:%S') ====="
exit 0
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 Oldhan's World
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果