Day-2 脚本——「轻量级日志轮转器 rotate_log.sh」
这个shell脚本与上个脚本的目录备份脚本互补:前者管整体备份,今天这个专注于单个日志文件的自动轮转、压缩和过期清理。
功能一览
- 按时间戳轮转:将活动日志 app.log 重命名为 app_YYYYMMDD_HHMMSS.log
- 自动压缩:轮转后的旧日志立即 gzip,节省磁盘
- 保留最新 N 份(默认 5 份),其余删除
- 返回码可观测:0 成功,非 0 失败,方便 cron / CI 检测
脚本源码
rotate_log.sh
#!/usr/bin/env bash
#
# rotate_log.sh — 轻量级日志轮转与保留
#
# 用法:
# ./rotate_log.sh -f /var/log/app.log [-k 5]
# 参数:
# -f 需要轮转的日志文件(必填)
# -k 最多保留轮转后的压缩包数量,默认 5
#
# 计划任务示例(每日 00:10 轮转 nginx 访问日志,保留 30 份):
# 10 0 * * * /opt/scripts/rotate_log.sh -f /var/log/nginx/access.log -k 30
set -euo pipefail
usage() {
echo "Usage: $0 -f <log_file> [-k <keep_num>]" >&2
exit 1
}
KEEP_NUM=5 # 默认保留 5 份
while getopts ":f:k:" opt; do
case "${opt}" in
f) LOG_FILE="${OPTARG}" ;;
k) KEEP_NUM="${OPTARG}" ;;
*) usage ;;
esac
done
[[ -z "${LOG_FILE:-}" ]] && usage
[[ ! -f "${LOG_FILE}" ]] && { echo "ERROR: Log file not found: ${LOG_FILE}" >&2; exit 2; }
DIR=$(dirname "${LOG_FILE}")
BASE=$(basename "${LOG_FILE}" .log) # 去掉 .log 后缀
TS=$(date '+%Y%m%d_%H%M%S')
ROTATED="${DIR}/${BASE}_${TS}.log"
echo "$(date '+%F %T') Rotate ${LOG_FILE} → ${ROTATED}"
mv "${LOG_FILE}" "${ROTATED}"
echo "$(date '+%F %T') Compress ${ROTATED}"
gzip "${ROTATED}"
# 重新创建空日志,避免应用写失败
: > "${LOG_FILE}"
chmod 644 "${LOG_FILE}"
echo "$(date '+%F %T') Cleanup: keep last ${KEEP_NUM} archives"
# 取同名 *.log.gz,按修改时间排序,超出保留数的删除
ls -1t "${DIR}/${BASE}"_*.log.gz | tail -n +"$((KEEP_NUM + 1))" | xargs -r rm -v
echo "$(date '+%F %T') Done"
落地步骤
# 1. 保存脚本
sudo mkdir -p /opt/scripts
sudo nano
/opt/scripts/rotate_log.sh # 或 vim,将上方代码粘贴
# 2. 赋权
sudo chmod +x /opt/scripts/rotate_log.sh
# 3. 立即试跑
sudo /opt/scripts/rotate_log.sh -f /var/log/syslog -k 7
# 4. 加入 crontab(示例:每天 00:05 轮转 /var/log/app.log)
crontab -e
5 0 * * * /opt/scripts/rotate_log.sh -f /var/log/app.log -k 14 >> /var/log/rotate_app.log 2>&1
关键知识点
技巧 | 说明 |
basename "$LOG_FILE" .log | 去掉固定后缀,方便生成新文件名 |
mv && gzip | 分离“轮转”和“压缩”两步,避免应用与 gzip 同时抢写 |
: > file | Bash 空命令,快速清空 / 新建日志文件 |
`ls -1t … | tail -n +N` |
xargs -r rm -v | 仅当有超额文件才执行删除,并逐个打印 |
进阶练习
- 信号通知:脚本结束后用 logger 写入系统日志,或调用钉钉机器人;
- 并行压缩:安装 pigz,替换 gzip 提升多核压缩效率;
- 多日志批处理:支持读取目录并对其中所有 *.log 循环调用;
- 完整封装为 systemd timer:替代 cron,统一管理;
- 单元测试:利用 Bats-core 创建旋转、保留、失败场景的自动验证。