实用脚本能自动压缩日志文件吗?

wen 实用脚本 1

本文目录导读:

实用脚本能自动压缩日志文件吗?

  1. 简单Shell脚本(Linux/Unix)
  2. 使用logrotate(推荐)
  3. Python脚本(跨平台)
  4. Windows PowerShell脚本
  5. 高级功能脚本
  6. 定时执行方法
  7. 最佳实践建议

是的,实用脚本可以自动压缩日志文件,以下是几种常见的方案,适用于不同场景:

简单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

最佳实践建议

  1. 测试先行:先在测试环境运行
  2. 保持备份:保留原始文件直到压缩成功
  3. 监控空间:设置磁盘空间告警
  4. 权限控制:确保脚本有足够权限
  5. 日志记录:记录压缩操作日志

选择哪种方案取决于你的操作系统、日志量大小和具体需求,对于大多数Linux系统,logrotate是最推荐的标准方案。

抱歉,评论功能暂时关闭!