本文目录导读:

Shell脚本实现日志轮转可以通过多种方式,这里提供几种常见的实现方案:
基础日志轮转脚本
#!/bin/bash
# 日志轮转配置
LOG_DIR="/var/log/myapp"
LOG_FILE="app.log"
MAX_SIZE="10M" # 单个日志最大大小
KEEP_DAYS=7 # 保留天数
# 确保日志目录存在
mkdir -p "$LOG_DIR"
# 日志轮转函数
rotate_log() {
local log_path="$LOG_DIR/$LOG_FILE"
# 检查日志文件是否存在且大小超过限制
if [ -f "$log_path" ]; then
local file_size=$(stat -f%z "$log_path" 2>/dev/null || stat -c%s "$log_path" 2>/dev/null)
local max_bytes=$((10 * 1024 * 1024)) # 10M = 10*1024*1024
if [ "$file_size" -gt "$max_bytes" ]; then
# 备份当前日志
local timestamp=$(date +%Y%m%d_%H%M%S)
cp "$log_path" "$LOG_DIR/${LOG_FILE}.${timestamp}.bak"
# 清空原日志
> "$log_path"
# 删除过期备份
find "$LOG_DIR" -name "${LOG_FILE}.*.bak" -mtime +$KEEP_DAYS -delete
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 日志轮转完成" >> "$log_path"
fi
fi
}
# 运行日志轮转
rotate_log
带压缩功能的日志轮转
#!/bin/bash
# 配置
LOG_FILE="/var/log/myapp/application.log"
MAX_SIZE="10M"
MAX_FILES=5 # 保留的最大日志文件数
COMPRESS=true
# 转换大小
convert_size() {
local size=$1
local unit=${size: -1}
local num=${size%?}
case $unit in
M|m) echo $((num * 1024 * 1024)) ;;
G|g) echo $((num * 1024 * 1024 * 1024)) ;;
K|k) echo $((num * 1024)) ;;
*) echo "$size" ;;
esac
}
# 执行日志轮转
rotate_with_compression() {
local max_bytes=$(convert_size "$MAX_SIZE")
local log_dir=$(dirname "$LOG_FILE")
local log_name=$(basename "$LOG_FILE")
# 检查文件大小
if [ -f "$LOG_FILE" ]; then
local current_size=$(stat -f%z "$LOG_FILE" 2>/dev/null || stat -c%s "$LOG_FILE" 2>/dev/null)
if [ "$current_size" -gt "$max_bytes" ]; then
# 轮转现有日志
for ((i=MAX_FILES-1; i>=0; i--)); do
local old_file="$LOG_FILE.$i"
if [ "$i" -eq 0 ]; then
# 最新备份
cp "$LOG_FILE" "$old_file"
else
local prev_file="$LOG_FILE.$((i-1))"
if [ -f "$prev_file" ]; then
mv "$prev_file" "$old_file"
fi
fi
done
# 压缩旧日志
if [ "$COMPRESS" = true ]; then
for ((i=1; i<MAX_FILES; i++)); do
local file_to_compress="$LOG_FILE.$i"
if [ -f "$file_to_compress" ]; then
gzip -f "$file_to_compress"
fi
done
fi
# 清空原日志
> "$LOG_FILE"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 日志轮转完成 (压缩: $COMPRESS)" >> "$LOG_FILE"
fi
fi
}
# 执行
rotate_with_compression
基于大小的日志轮转(支持后缀编号)
#!/bin/bash
# 配置
LOG_DIR="/var/log/app"
BASE_NAME="app"
LOG_EXTENSION=".log"
MAX_SIZE="5M"
MAX_BACKUPS=3
# 日志轮转函数
rotate_by_size() {
local log_file="$LOG_DIR/${BASE_NAME}${LOG_EXTENSION}"
local max_bytes=$(echo "$MAX_SIZE" | sed 's/M$/*1024*1024/' | sed 's/K$/*1024/' | bc)
# 检查日志文件
if [ -f "$log_file" ]; then
local file_size=$(stat -c%s "$log_file" 2>/dev/null)
if [ "$file_size" -gt "$max_bytes" ]; then
# 轮转备份文件
for ((i=MAX_BACKUPS-1; i>=0; i--)); do
local old_backup="${LOG_DIR}/${BASE_NAME}.${i}${LOG_EXTENSION}"
if [ "$i" -eq 0 ]; then
mv "$log_file" "$old_backup" 2>/dev/null
else
local new_backup="${LOG_DIR}/${BASE_NAME}.${i}${LOG_EXTENSION}"
if [ -f "$old_backup" ]; then
mv "$old_backup" "$new_backup" 2>/dev/null
fi
fi
done
# 创建新的空日志文件
> "$log_file"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 日志已轮转" >> "$log_file"
fi
fi
}
# 执行
rotate_by_size
基于时间的日志轮转
#!/bin/bash
# 配置
LOG_FILE="/var/log/app/application.log"
ROTATE_HOURLY=true
ROTATE_DAILY=true
DAILY_ROTATE_TIME="00:00" # 每天轮转时间
# 时间轮转
rotate_by_time() {
local log_dir=$(dirname "$LOG_FILE")
local log_name=$(basename "$LOG_FILE")
local current_hour=$(date +%H)
local current_date=$(date +%Y%m%d)
# 每天轮转
if [ "$ROTATE_DAILY" = true ] && [ "$current_hour" = "00" ]; then
local backup_name="${log_dir}/${log_name%.*}_${current_date}.log"
if [ -f "$LOG_FILE" ] && [ -s "$LOG_FILE" ]; then
mv "$LOG_FILE" "$backup_name"
> "$LOG_FILE"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 每日日志轮转" >> "$LOG_FILE"
# 压缩旧的日志
gzip -f "$backup_name" 2>/dev/null
fi
fi
# 每小时轮转(可选)
if [ "$ROTATE_HOURLY" = true ]; then
# 可以在这里添加每小时轮转逻辑
:
fi
}
# 清理过期日志
cleanup_old_logs() {
local log_dir=$(dirname "$LOG_FILE")
# 保留30天的日志
find "$log_dir" -name "*.log.gz" -mtime +30 -delete
find "$log_dir" -name "*.log.*" -mtime +30 -delete
}
# 执行
rotate_by_time
cleanup_old_logs
完整的企业级日志轮转脚本
#!/bin/bash
# 完整的日志轮转系统
LOGGING_SYSTEM() {
# 配置
local LOG_FILE="/var/log/enterprise/app.log"
local MAX_SIZE="50M"
local MAX_FILES=10
local COMPRESS_OLD=true
local ROTATE_INTERVAL="daily"
# 日志配置
mkdir -p /var/log/enterprise/backups
# 日志轮转主函数
log_rotation_main() {
case "$1" in
"check")
check_log_size
;;
"rotate")
perform_rotation
;;
"cleanup")
cleanup_old_logs
;;
"status")
show_log_status
;;
*)
echo "使用方法: $0 {check|rotate|cleanup|status}"
exit 1
;;
esac
}
# 检查日志大小
check_log_size() {
if [ -f "$LOG_FILE" ]; then
local size=$(stat -c%s "$LOG_FILE")
local max=$(echo "$MAX_SIZE" | sed 's/M$/*1024*1024/' | bc)
echo "当前大小: $(echo "scale=2; $size/1024/1024" | bc)M"
echo "最大限制: $MAX_SIZE"
if [ "$size" -gt "$max" ]; then
echo "需要轮转"
return 0
else
echo "正常"
return 1
fi
fi
}
# 执行轮转
perform_rotation() {
if check_log_size >/dev/null 2>&1; then
local timestamp=$(date +%Y%m%d_%H%M%S)
local backup_file="/var/log/enterprise/backups/app_${timestamp}.log"
echo "$(date) - 开始日志轮转" >> /var/log/enterprise/rotation.log
# 复制当前日志
cp "$LOG_FILE" "$backup_file"
# 压缩
if [ "$COMPRESS_OLD" = true ]; then
gzip -f "$backup_file"
fi
# 清空当前日志
> "$LOG_FILE"
echo "$(date) - 日志轮转完成: $backup_file" >> /var/log/enterprise/rotation.log
fi
}
# 清理旧日志
cleanup_old_logs() {
echo "清理30天前的日志..."
find /var/log/enterprise/backups -name "*.log*" -mtime +30 -delete
echo "清理完成"
}
# 显示日志状态
show_log_status() {
echo "=== 日志状态 ==="
echo "主日志: $LOG_FILE"
echo "大小: $(ls -lh "$LOG_FILE" | awk '{print $5}')"
echo "备份数量: $(ls /var/log/enterprise/backups/*.log* 2>/dev/null | wc -l)"
echo "配置:"
echo " MAX_SIZE=$MAX_SIZE"
echo " MAX_FILES=$MAX_FILES"
echo " COMPRESS=$COMPRESS_OLD"
}
# 执行
log_rotation_main "$@"
}
# 运行
LOGGING_SYSTEM "$@"
使用crontab自动执行
# 添加定时任务,每6小时检查一次 # crontab -e 添加以下内容 0 */6 * * * /path/to/rotate.sh # 或者使用systemd timer # 创建服务文件 /etc/systemd/system/log-rotate.service [Unit] Description=Custom Log Rotation Service [Service] Type=oneshot ExecStart=/path/to/rotate.sh User=root # 创建定时器 /etc/systemd/system/log-rotate.timer [Unit] Description=Run log rotation every 6 hours [Timer] OnCalendar=*-*-* 00,06,12,18:00:00 Persistent=true [Install] WantedBy=timers.target
使用建议
- 选择合适的轮转策略:根据日志增长速度和重要性选择按大小或时间轮转
- 测试脚本:在生产环境使用前充分测试
- 监控日志轮转:添加日志记录轮转操作的执行情况
- 资源考虑:大型日志文件轮转会消耗CPU和I/O资源
- 权限管理:确保脚本有适当权限访问和修改日志文件
这些脚本可以根据具体需求调整配置,如修改大小限制、保留天数、压缩选项等。