日志轮转与自动清理脚本

代码脚本 · maintenance

自动轮转应用日志,压缩历史日志,清理过期日志,支持按大小/时间轮转,防止磁盘占满

详细内容

#!/bin/bash # ========================================== # 日志轮转与自动清理脚本 # 用途:自动轮转应用日志,压缩历史日志,清理过期日志 # 使用方法:bash log_rotate.sh # 定时任务:0 0 * * * /path/to/log_rotate.sh # ========================================== # 配置 LOG_DIRS="${LOG_DIRS:-/var/log/nginx /var/log/mysql /opt/app/logs}" LOG_PATTERNS="${LOG_PATTERNS:-*.log}" MAX_LOG_SIZE="${MAX_LOG_SIZE:-100M}" ROTATE_COUNT="${ROTATE_COUNT:-7}" COMPRESS="${COMPRESS:-true}" DELETE_OLD="${DELETE_OLD:-true}" DRY_RUN="${DRY_RUN:-false}" echo "========== 日志轮转开始 ==========" echo "执行时间: $(date '+%Y-%m-%d %H:%M:%S')" echo "日志目录: $LOG_DIRS" echo "最大日志大小: $MAX_LOG_SIZE" echo "保留份数: $ROTATE_COUNT" echo "压缩: $COMPRESS" echo "删除过期: $DELETE_OLD" echo "试运行: $DRY_RUN" echo "" # 统计 TOTAL_LOGS=0 ROTATED_LOGS=0 COMPRESSED_LOGS=0 DELETED_LOGS=0 FREED_SPACE=0 # 转换大小为字节 convert_to_bytes() { local size=$1 local num=${size%[KMG]} local unit=${size: -1} case $unit in K) echo $((num * 1024)) ;; M) echo $((num * 1024 * 1024)) ;; G) echo $((num * 1024 * 1024 * 1024)) ;; *) echo $num ;; esac } MAX_SIZE_BYTES=$(convert_to_bytes "$MAX_LOG_SIZE") # 轮转单个日志文件 rotate_log() { local log_file=$1 if [ ! -f "$log_file" ]; then return fi TOTAL_LOGS=$((TOTAL_LOGS + 1)) local file_size=$(stat -c%s "$log_file" 2>/dev/null || echo 0) # 检查是否需要轮转 if [ "$file_size" -lt "$MAX_SIZE_BYTES" ]; then return fi echo " 轮转: $log_file ($(du -h "$log_file" | cut -f1))" if [ "$DRY_RUN" = "true" ]; then echo " [试运行] 将轮转此文件" ROTATED_LOGS=$((ROTATED_LOGS + 1)) return fi # 删除最旧的日志 if [ "$DELETE_OLD" = "true" ]; then local oldest="${log_file}.${ROTATE_COUNT}.gz" if [ -f "$oldest" ]; then local oldest_size=$(stat -c%s "$oldest" 2>/dev/null || echo 0) rm -f "$oldest" DELETED_LOGS=$((DELETED_LOGS + 1)) FREED_SPACE=$((FREED_SPACE + oldest_size)) echo " 删除最旧: $oldest" fi fi # 轮转历史日志 for i in $(seq $((ROTATE_COUNT - 1)) -1 1); do local src="${log_file}.${i}.gz" local dst="${log_file}.$((i + 1)).gz" if [ -f "$src" ]; then mv "$src" "$dst" fi done # 轮转当前日志 local rotated="${log_file}.1" mv "$log_file" "$rotated" touch "$log_file" chmod 644 "$log_file" 2>/dev/null # 压缩 if [ "$COMPRESS" = "true" ]; then gzip -f "$rotated" COMPRESSED_LOGS=$((COMPRESSED_LOGS + 1)) echo " 压缩: ${rotated}.gz" fi ROTATED_LOGS=$((ROTATED_LOGS + 1)) } # 清理过期日志(按时间) cleanup_old_logs() { local dir=$1 local days=${2:-30} if [ ! -d "$dir" ]; then return fi echo " 清理 $dir 中超过 ${days} 天的日志..." local old_logs=$(find "$dir" -type f \( -name "*.log" -o -name "*.log.*" -o -name "*.gz" \) -mtime +$days 2>/dev/null) if [ -n "$old_logs" ]; then for log in $old_logs; do local log_size=$(stat -c%s "$log" 2>/dev/null || echo 0) if [ "$DRY_RUN" = "true" ]; then echo " [试运行] 将删除: $log" else rm -f "$log" echo " 删除: $log" fi DELETED_LOGS=$((DELETED_LOGS + 1)) FREED_SPACE=$((FREED_SPACE + log_size)) done else echo " 无过期日志" fi } # 主处理 for log_dir in $LOG_DIRS; do echo "【处理目录: $log_dir】" if [ ! -d "$log_dir" ]; then echo " ⚠️ 目录不存在,跳过" echo "" continue fi # 轮转日志 for pattern in $LOG_PATTERNS; do find "$log_dir" -maxdepth 2 -type f -name "$pattern" 2>/dev/null | while read log_file; do rotate_log "$log_file" done done # 清理过期日志 cleanup_old_logs "$log_dir" 30 echo "" done # 汇总 echo "========== 处理汇总 ==========" echo " 扫描日志数: $TOTAL_LOGS" echo " 轮转日志数: $ROTATED_LOGS" echo " 压缩日志数: $COMPRESSED_LOGS" echo " 删除日志数: $DELETED_LOGS" echo " 释放空间: $(echo "scale=2; $FREED_SPACE / 1024 / 1024" | bc) MB" echo "" # 磁盘使用情况 echo "【磁盘使用情况】" for log_dir in $LOG_DIRS; do if [ -d "$log_dir" ]; then echo " $log_dir: $(du -sh "$log_dir" | cut -f1)" fi done echo "" echo "========== 处理完成 ==========" echo "提示: 可将此脚本加入crontab定时执行,例如每天凌晨执行" echo " 0 0 * * * /path/to/log_rotate.sh"

适配环境

适配系统:CentOS 7+,Ubuntu 18.04+,Debian 10+

依赖环境:bash 4.0+

参数说明

[{"name": "LOG_DIRS", "label": "\u65e5\u5fd7\u76ee\u5f55(\u7a7a\u683c\u5206\u9694)", "default": "/var/log/nginx /var/log/mysql"}, {"name": "MAX_LOG_SIZE", "label": "\u6700\u5927\u65e5\u5fd7\u5927\u5c0f", "default": "100M"}, {"name": "ROTATE_COUNT", "label": "\u4fdd\u7559\u4efd\u6570", "default": "7"}, {"name": "DRY_RUN", "label": "\u8bd5\u8fd0\u884c(true/false)", "default": "false"}]
日志轮转日志清理磁盘空间定时任务

更多maintenance