5.8.1 日志清理与归档脚本

日志清理与归档脚本#

目标与适用场景#

  • 控制日志磁盘占用,避免系统盘爆满
  • 统一归档规范,便于审计与追溯
  • 支持业务日志、系统日志、容器日志的定期清理

原理草图#

文章图片

依赖与安装#

# RHEL/CentOS
yum -y install gzip coreutils findutils

# Debian/Ubuntu
apt-get update && apt-get -y install gzip coreutils findutils

关键命令解释#

# 查找 30 天前的日志
find /var/log/app -type f -name "*.log" -mtime +30

# 压缩日志(保留原文件)
gzip -c /var/log/app/app.log > /var/log/archive/app.log.gz

# 压缩并替换源文件
gzip /var/log/app/app.log

# 按日期创建目录
mkdir -p /var/log/archive/$(date +%F)

样例脚本:按天数归档与清理#

#!/bin/bash
set -euo pipefail

LOG_DIR="/var/log/app"
ARCHIVE_DIR="/var/log/archive"
KEEP_DAYS=30
RUN_LOG="/var/log/ops/log_cleaner.log"

mkdir -p "$ARCHIVE_DIR" "$(dirname "$RUN_LOG")"

echo "[$(date '+%F %T')] Start log cleanup" >> "$RUN_LOG"

# 查找过期日志并归档
find "$LOG_DIR" -type f -name "*.log" -mtime +"$KEEP_DAYS" | while read -r f; do
  base=$(basename "$f")
  day=$(date -r "$f" +%F)
  target_dir="$ARCHIVE_DIR/$day"
  mkdir -p "$target_dir"

  # 归档压缩:保持源文件内容一致
  gzip -c "$f" > "$target_dir/$base.gz"
  if [[ $? -eq 0 ]]; then
    rm -f "$f"
    echo "[$(date '+%F %T')] archived: $f -> $target_dir/$base.gz" >> "$RUN_LOG"
  else
    echo "[$(date '+%F %T')] failed: $f" >> "$RUN_LOG"
  fi
done

echo "[$(date '+%F %T')] End log cleanup" >> "$RUN_LOG"

预期效果
- /var/log/app 中 30 天前的 *.log 被压缩并移入 /var/log/archive/日期/
- /var/log/ops/log_cleaner.log 记录执行过程

定时执行(crontab)#

# 每天凌晨 2:30 执行
crontab -e
30 2 * * * /bin/bash /usr/local/bin/log_cleaner.sh >> /var/log/ops/log_cleaner.cron.log 2>&1

验证与演练命令#

# 生成演示日志文件
mkdir -p /var/log/app
echo "demo log" > /var/log/app/test.log

# 修改时间到 31 天前
touch -d "31 days ago" /var/log/app/test.log

# 执行脚本
bash /usr/local/bin/log_cleaner.sh

# 检查归档
ls -l /var/log/archive/$(date -d "31 days ago" +%F)

# 查看运行日志
tail -n 20 /var/log/ops/log_cleaner.log

常见排错#

  • 无权限
    bash ls -ld /var/log/app /var/log/archive chmod -R 750 /var/log/app /var/log/archive
  • 脚本无输出
    检查 find 是否匹配到文件:
    bash find /var/log/app -type f -name "*.log" -mtime +30
  • 压缩失败
    检查磁盘空间与 gzip:
    bash df -h which gzip

练习#

  1. 将保留天数改为 7 天,并新增参数 KEEP_DAYS 从命令行传入。
  2. 增加按大小清理:超过 500MB 的日志优先归档。
  3. 在脚本中加入锁文件,避免并发执行。