本文目录导读:

是的,实用脚本可以自动压缩日志文件,以下是几种常见的方案,适用于不同场景:
简单Shell脚本(Linux/Unix)
#!/bin/bash
# 日志压缩脚本 - auto_compress_logs.sh
LOG_DIR="/var/log/myapp"
DAYS_OLD=7
COMPRESS_CMD="gzip"
# 压缩7天前的日志文件
find $LOG_DIR -name "*.log" -mtime +$DAYS_OLD -exec $COMPRESS_CMD {} \;
# 删除已压缩的原始日志(可选)
# find $LOG_DIR -name "*.log" -mtime +$DAYS_OLD -delete
echo "日志压缩完成:$(date)"
使用logrotate(推荐)
# 配置示例 /etc/logrotate.d/myapp
/var/log/myapp/*.log {
daily # 每日轮转
rotate 30 # 保留30个备份
compress # 启用压缩
delaycompress # 延迟压缩(保留最新一个未压缩)
missingok # 日志文件不存在也不报错
notifempty # 空文件不轮转
create 0640 root adm # 创建新日志文件权限
postrotate
systemctl reload myapp > /dev/null 2>&1 || true
endscript
}
Python脚本(跨平台)
#!/usr/bin/env python3
import gzip
import shutil
import os
from datetime import datetime, timedelta
def compress_logs(log_dir, days_old=7):
"""压缩指定天数前的日志文件"""
cutoff = datetime.now() - timedelta(days=days_old)
for root, dirs, files in os.walk(log_dir):
for file in files:
if not file.endswith('.log'):
continue
file_path = os.path.join(root, file)
file_time = datetime.fromtimestamp(os.path.getmtime(file_path))
if file_time < cutoff and not file.endswith('.gz'):
compressed_path = file_path + '.gz'
with open(file_path, 'rb') as f_in:
with gzip.open(compressed_path, 'wb') as f_out:
shutil.copyfileobj(f_in, f_out)
os.remove(file_path)
print(f"压缩: {file} -> {file}.gz")
if __name__ == "__main__":
compress_logs("/var/log/myapp", 7)
Windows PowerShell脚本
# 日志压缩脚本 - compress_logs.ps1
$logPath = "C:\Logs\MyApp"
$daysOld = 7
$cutoffDate = (Get-Date).AddDays(-$daysOld)
Get-ChildItem $logPath -Filter *.log | Where-Object {
$_.LastWriteTime -lt $cutoffDate -and $_.Extension -ne ".gz"
} | ForEach-Object {
$source = $_.FullName
$destination = $_.FullName + ".gz"
# 使用System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.FileSystem
$compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
$compress = [System.IO.Compression.GZipStream]::new(
[System.IO.File]::Open($destination, [System.IO.FileMode]::Create),
$compressionLevel)
$stream = [System.IO.File]::OpenRead($source)
$stream.CopyTo($compress)
$compress.Close()
$stream.Close()
Remove-Item $source
Write-Host "压缩: $($_.Name) -> $($_.Name).gz"
}
高级功能脚本
#!/bin/bash
# 高级日志压缩脚本 - 支持配置和通知
CONFIG_FILE="/etc/log-compressor.conf"
# 默认配置
LOG_DIRS=("/var/log/app1" "/var/log/app2")
DAYS_OLD=7
COMPRESS_TYPE="gzip" # gzip, bzip2, xz
DELETE_AFTER=90 # 删除压缩后超过90天的文件
NOTIFY_EMAIL="admin@example.com"
# 加载配置
[ -f "$CONFIG_FILE" ] && source "$CONFIG_FILE"
# 确定压缩命令
case $COMPRESS_TYPE in
gzip) EXT=".gz"; CMD="gzip -9" ;;
bzip2) EXT=".bz2"; CMD="bzip2 -9" ;;
xz) EXT=".xz"; CMD="xz -9" ;;
*) echo "未知压缩类型"; exit 1 ;;
esac
compress_logs() {
local dir=$1
find "$dir" -name "*.log" -mtime +$DAYS_OLD | while read logfile; do
if [ ! -f "${logfile}${EXT}" ]; then
echo "压缩: $logfile -> ${logfile}${EXT}"
$CMD "$logfile"
fi
done
}
cleanup_old() {
local dir=$1
find "$dir" -name "*.${EXT#.}" -mtime +$DELETE_AFTER -delete
}
# 执行压缩
for dir in "${LOG_DIRS[@]}"; do
if [ -d "$dir" ]; then
compress_logs "$dir"
cleanup_old "$dir"
fi
done
# 可选:发送通知
# echo "日志压缩完成于 $(date)" | mail -s "日志压缩报告" $NOTIFY_EMAIL
定时执行方法
Linux(Crontab)
# 每天凌晨2点执行 0 2 * * * /path/to/compress_logs.sh # 或使用logrotate(推荐) # logrotate已集成在系统定时任务中
Windows(任务计划程序)
# 创建定时任务 $action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:\scripts\compress_logs.ps1" $trigger = New-ScheduledTaskTrigger -Daily -At 3am Register-ScheduledTask -TaskName "CompressLogs" -Action $action -Trigger $trigger
最佳实践建议
- 测试先行:先在测试环境运行
- 保持备份:保留原始文件直到压缩成功
- 监控空间:设置磁盘空间告警
- 权限控制:确保脚本有足够权限
- 日志记录:记录压缩操作日志
选择哪种方案取决于你的操作系统、日志量大小和具体需求,对于大多数Linux系统,logrotate是最推荐的标准方案。