本文目录导读:

- 核心原则
- Shell 脚本(Linux/Unix/macOS 最常用)
- Python 脚本(跨平台,更灵活)
- Windows PowerShell 脚本(Windows 环境)
- 使用
logrotate(Linux 推荐) - 总结建议
压缩归档旧日志是日志管理中的常见任务,可以通过多种脚本实现,以下是几种常见场景的解决方案,涵盖 Linux Shell、Python 和 Windows PowerShell。
核心原则
- 按时间切分:只处理超过指定天数(如 7天、30天)的日志。
- 高效压缩:通常使用
gzip、bzip2或xz(压缩比高)。 - 归档选项:可以选择压缩后删除原文件,或移动到归档目录。
- 健壮性:处理文件不存在、权限不足等异常。
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 命令 |
补充提示:
- 测试先运行:在正式环境使用前,先用
echo或dry-run模式(如 Shell 中先不加-exec,只-print查看匹配的文件)。 - 设置定时任务:
- Linux:使用
crontab -e,如0 3 * * * /path/to/archive.sh(每天凌晨3点)。 - Windows:使用“任务计划程序”运行 PowerShell 脚本。
- Linux:使用
- 注意磁盘空间:压缩后务必确认原文件被删除,避免空间爆炸。
如果你有特定的日志格式(如按日期切分、日志量大需异步处理)或操作系统版本限制,可以进一步说明,我会给出更精细的调整。