脚本如何压缩归档旧日志

wen 实用脚本 28

本文目录导读:

脚本如何压缩归档旧日志

  1. 核心原则
  2. Shell 脚本(Linux/Unix/macOS 最常用)
  3. Python 脚本(跨平台,更灵活)
  4. Windows PowerShell 脚本(Windows 环境)
  5. 使用 logrotate(Linux 推荐)
  6. 总结建议

压缩归档旧日志是日志管理中的常见任务,可以通过多种脚本实现,以下是几种常见场景的解决方案,涵盖 Linux ShellPythonWindows PowerShell

核心原则

  1. 按时间切分:只处理超过指定天数(如 7天、30天)的日志。
  2. 高效压缩:通常使用 gzipbzip2xz(压缩比高)。
  3. 归档选项:可以选择压缩后删除原文件,或移动到归档目录。
  4. 健壮性:处理文件不存在、权限不足等异常。

Shell 脚本(Linux/Unix/macOS 最常用)

适用于 .log.txt 等文本日志,按日期过滤并压缩。

脚本:archive_old_logs.sh

#!/bin/bash
# 配置
LOG_DIR="/var/log/myapp"          # 日志目录
ARCHIVE_DIR="/var/log/archive"    # 归档目录(可选)
DAYS_OLD=7                        # 超过7天的日志
FILE_PATTERN="*.log"              # 匹配的日志模式
# 创建归档目录(如果不存在)
mkdir -p "$ARCHIVE_DIR"
# 查找并压缩
find "$LOG_DIR" -type f -name "$FILE_PATTERN" -mtime +$DAYS_OLD -exec sh -c '
    file="$1"
    # 压缩到当前目录(生成 .gz 文件)
    gzip -9 "$file"  # -9 表示最高压缩比
    # 如果需要移动压缩包到归档目录,取消注释下一行
    # mv "${file}.gz" "$ARCHIVE_DIR/"
' _ {} \;
echo "Archive completed."

使用方式:

chmod +x archive_old_logs.sh
./archive_old_logs.sh

说明:

  • -mtime +7:查找最后修改时间超过7天的文件。
  • gzip -9:压缩比最高,速度稍慢,如需要更快速度,用 -1
  • 如果希望压缩后直接删除原文件,使用 gzip -9 -f "$file"gzip -9 "$file" && rm "$file"

Python 脚本(跨平台,更灵活)

适用于需要更复杂逻辑(如正则匹配、异常处理、大型文件流)的场景。

脚本:archive_old_logs.py

import os
import gzip
import shutil
from datetime import datetime, timedelta
import glob
# 配置
LOG_DIR = "/var/log/myapp"
ARCHIVE_DIR = "/var/log/archive"
DAYS_OLD = 7
FILE_PATTERN = "*.log"
def is_old_file(filepath, days_old):
    """检查文件是否超过指定天数"""
    if not os.path.isfile(filepath):
        return False
    mtime = os.path.getmtime(filepath)
    cutoff = (datetime.now() - timedelta(days=days_old)).timestamp()
    return mtime < cutoff
def compress_file(src_path, dst_dir):
    """压缩文件到目标目录"""
    base_name = os.path.basename(src_path)
    dst_path = os.path.join(dst_dir, base_name + ".gz")
    with open(src_path, 'rb') as f_in:
        with gzip.open(dst_path, 'wb', compresslevel=9) as f_out:
            shutil.copyfileobj(f_in, f_out)
    # 删除原文件(可选)
    os.remove(src_path)
    print(f"Compressed and removed: {src_path} -> {dst_path}")
def main():
    # 创建归档目录
    os.makedirs(ARCHIVE_DIR, exist_ok=True)
    # 遍历匹配文件
    for filepath in glob.glob(os.path.join(LOG_DIR, FILE_PATTERN)):
        if is_old_file(filepath, DAYS_OLD):
            try:
                compress_file(filepath, ARCHIVE_DIR)
            except Exception as e:
                print(f"Error processing {filepath}: {e}")
if __name__ == "__main__":
    main()

使用方式:

python3 archive_old_logs.py

优点:

  • 跨平台(Windows / Linux / macOS)。
  • 可以轻松添加日志、发邮件、记录统计等高级功能。

Windows PowerShell 脚本(Windows 环境)

适用于 Windows Server 或本地的 IIS、应用日志。

脚本:Archive-OldLogs.ps1

# 配置
$LogDir = "C:\Logs\MyApp"
$ArchiveDir = "C:\Logs\Archive"
$DaysOld = 7
$Pattern = "*.log"
# 创建归档目录
New-Item -ItemType Directory -Force -Path $ArchiveDir | Out-Null
# 获取旧文件
$OldFiles = Get-ChildItem -Path $LogDir -Filter $Pattern | Where-Object {
    $_.LastWriteTime -lt (Get-Date).AddDays(-$DaysOld)
}
foreach ($File in $OldFiles) {
    $SourcePath = $File.FullName
    $DestPath = Join-Path -Path $ArchiveDir -ChildPath ($File.Name + ".gz")
    # 读取内容并压缩(PowerShell 内置 GZipStream)
    $SourceStream = [System.IO.File]::OpenRead($SourcePath)
    $DestStream = [System.IO.File]::OpenWrite($DestPath)
    $GZipStream = New-Object System.IO.Compression.GZipStream($DestStream, [System.IO.Compression.CompressionMode]::Compress)
    $SourceStream.CopyTo($GZipStream)
    # 清理流
    $GZipStream.Close()
    $DestStream.Close()
    $SourceStream.Close()
    # 删除原文件
    Remove-Item -Path $SourcePath -Force
    Write-Host "Compressed and removed: $SourcePath -> $DestPath"
}
Write-Host "Archive completed."

使用方式:

.\Archive-OldLogs.ps1

注意:

  • 如果系统没有 System.IO.Compression 命名空间(旧版本),可能需要安装 .NET 框架。

使用 logrotate(Linux 推荐)

对于 Linux 系统,logrotate 是管理日志归档的标准工具,它不需要手写脚本,用配置文件即可实现压缩、轮换、删除。

配置示例:/etc/logrotate.d/myapp

/var/log/myapp/*.log {
    daily                      # 每天轮换
    rotate 7                   # 保留最近 7 个归档
    compress                   # 使用 gzip 压缩
    delaycompress              # 延迟一天压缩(避免同时写入)
    missingok                  # 如果日志缺失,不报错
    notifempty                 # 如果为空,不轮换
    copytruncate               # 复制并清空原文件(应用无感知)
}

用法: 只需将文件放入 /etc/logrotate.d/logrotate 会由 cron 每天自动调用。

优点: 简单、标准、可靠。


总结建议

场景 推荐方式
Linux 服务器 logrotate(最标准)或 Shell 脚本
需要跨平台 / 复杂逻辑 Python 脚本
Windows 环境 PowerShell 脚本
临时手动操作 直接使用 gzip / zip 命令

补充提示:

  • 测试先运行:在正式环境使用前,先用 echodry-run 模式(如 Shell 中先不加 -exec,只 -print 查看匹配的文件)。
  • 设置定时任务
    • Linux:使用 crontab -e,如 0 3 * * * /path/to/archive.sh(每天凌晨3点)。
    • Windows:使用“任务计划程序”运行 PowerShell 脚本。
  • 注意磁盘空间:压缩后务必确认原文件被删除,避免空间爆炸。

如果你有特定的日志格式(如按日期切分、日志量大需异步处理)或操作系统版本限制,可以进一步说明,我会给出更精细的调整。

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