本文目录导读:

我来提供一个完整的Python脚本方案来压缩归档旧日志文件:
基础版本
#!/usr/bin/env python3
import os
import gzip
import shutil
from datetime import datetime, timedelta
import glob
def compress_old_logs(log_dir, days_old=7, delete_original=True):
"""
压缩指定目录下的旧日志文件
Args:
log_dir: 日志文件目录路径
days_old: 多少天前的文件算旧文件
delete_original: 压缩后是否删除原文件
"""
# 计算截止日期
cutoff_date = datetime.now() - timedelta(days=days_old)
# 查找所有.log文件
log_files = glob.glob(os.path.join(log_dir, '*.log'))
# 也可以添加其他扩展名
# log_files.extend(glob.glob(os.path.join(log_dir, '*.txt')))
compressed_count = 0
for log_file in log_files:
# 获取文件修改时间
file_mtime = datetime.fromtimestamp(os.path.getmtime(log_file))
# 判断文件是否超过指定天数
if file_mtime < cutoff_date:
# 创建压缩文件名
gz_filename = log_file + '.gz'
try:
# 压缩文件
with open(log_file, 'rb') as f_in:
with gzip.open(gz_filename, 'wb') as f_out:
shutil.copyfileobj(f_in, f_out)
# 删除原文件(可选)
if delete_original:
os.remove(log_file)
print(f"已压缩: {log_file} -> {gz_filename}")
compressed_count += 1
except Exception as e:
print(f"压缩失败 {log_file}: {e}")
print(f"共压缩 {compressed_count} 个文件")
# 使用示例
if __name__ == "__main__":
compress_old_logs("/var/log/myapp", days_old=7)
高级版本(带更多功能)
#!/usr/bin/env python3
import os
import gzip
import shutil
import argparse
import logging
from datetime import datetime, timedelta
from pathlib import Path
import zipfile
class LogArchiver:
"""日志归档器"""
def __init__(self, config=None):
self.config = config or {}
self.setup_logging()
def setup_logging(self):
"""设置日志记录"""
log_format = '%(asctime)s - %(levelname)s - %(message)s'
logging.basicConfig(
level=logging.INFO,
format=log_format,
handlers=[
logging.FileHandler('archiver.log'),
logging.StreamHandler()
]
)
self.logger = logging.getLogger(__name__)
def compress_gzip(self, source_path, output_path=None):
"""使用gzip压缩单个文件"""
if output_path is None:
output_path = str(source_path) + '.gz'
try:
with open(source_path, 'rb') as f_in:
with gzip.open(output_path, 'wb', compresslevel=9) as f_out:
shutil.copyfileobj(f_in, f_out)
self.logger.info(f"Gzip压缩完成: {source_path} -> {output_path}")
return True
except Exception as e:
self.logger.error(f"Gzip压缩失败: {e}")
return False
def compress_zip(self, source_dir, output_path, file_pattern='*.log', days_old=7):
"""将旧日志打包为zip文件"""
cutoff_date = datetime.now() - timedelta(days=days_old)
files_to_archive = []
# 查找符合条件的文件
for log_file in Path(source_dir).glob(file_pattern):
file_mtime = datetime.fromtimestamp(log_file.stat().st_mtime)
if file_mtime < cutoff_date:
files_to_archive.append(log_file)
if not files_to_archive:
self.logger.info("没有找到需要归档的文件")
return False
try:
# 创建zip文件
with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
for file_path in files_to_archive:
zipf.write(file_path, file_path.name)
self.logger.info(f"添加到zip: {file_path}")
# 删除原文件
for file_path in files_to_archive:
file_path.unlink()
self.logger.info(f"已删除原文件: {file_path}")
self.logger.info(f"Zip归档完成: {output_path}")
return True
except Exception as e:
self.logger.error(f"Zip归档失败: {e}")
return False
def archive_by_pattern(self, source_dir, patterns=['*.log', '*.txt'],
days_old=7, archive_format='gz', output_dir=None):
"""根据文件模式归档"""
if output_dir is None:
output_dir = source_dir
cutoff_date = datetime.now() - timedelta(days=days_old)
archived_count = 0
for pattern in patterns:
for log_file in Path(source_dir).glob(pattern):
file_mtime = datetime.fromtimestamp(log_file.stat().st_mtime)
if file_mtime < cutoff_date:
if archive_format == 'gz':
# 单个文件压缩
self.compress_gzip(log_file)
elif archive_format == 'zip':
# 批量zip归档(这里简化处理,实际可以根据时间分批)
pass
archived_count += 1
self.logger.info(f"共归档 {archived_count} 个文件")
return archived_count
def clean_old_archives(self, archive_dir, days_to_keep=30):
"""清理旧的归档文件"""
cutoff_date = datetime.now() - timedelta(days=days_to_keep)
cleaned_count = 0
for archive_file in Path(archive_dir).glob('*.gz'):
file_mtime = datetime.fromtimestamp(archive_file.stat().st_mtime)
if file_mtime < cutoff_date:
archive_file.unlink()
self.logger.info(f"已删除旧归档: {archive_file}")
cleaned_count += 1
self.logger.info(f"共清理 {cleaned_count} 个旧归档文件")
# 命令行接口
def main():
parser = argparse.ArgumentParser(description='日志文件归档工具')
parser.add_argument('source_dir', help='日志文件目录')
parser.add_argument('--days', '-d', type=int, default=7, help='归档多少天前的文件')
parser.add_argument('--format', '-f', choices=['gz', 'zip'], default='gz',
help='归档格式')
parser.add_argument('--output', '-o', help='输出目录')
parser.add_argument('--pattern', '-p', nargs='+', default=['*.log'],
help='文件匹配模式')
parser.add_argument('--dry-run', action='store_true', help='模拟运行,不实际执行')
args = parser.parse_args()
archiver = LogArchiver()
if args.dry_run:
print("模拟运行模式 - 不实际执行归档")
# 这里可以添加模拟运行的逻辑
return
archiver.archive_by_pattern(
source_dir=args.source_dir,
patterns=args.pattern,
days_old=args.days,
archive_format=args.format,
output_dir=args.output
)
if __name__ == "__main__":
main()
简化实用版本
#!/usr/bin/env python3
import os
import gzip
import shutil
from pathlib import Path
from datetime import datetime, timedelta
def simple_log_rotation(log_dir, days=7):
"""简单的日志轮转函数"""
cutoff = datetime.now() - timedelta(days=days)
for log_file in Path(log_dir).glob("*.log*"):
if log_file.suffix == '.gz': # 跳过已压缩的文件
continue
mtime = datetime.fromtimestamp(log_file.stat().st_mtime)
if mtime < cutoff:
# 压缩文件
with open(log_file, 'rb') as f_in:
with gzip.open(f"{log_file}.gz", 'wb') as f_out:
shutil.copyfileobj(f_in, f_out)
# 删除原文件
log_file.unlink()
print(f"Archived: {log_file.name}")
# 使用示例
if __name__ == "__main__":
simple_log_rotation("/var/log/myapp")
使用crontab定时执行
创建脚本后,可以添加到crontab实现定时执行:
# 每天凌晨2点执行 0 2 * * * /usr/bin/python3 /path/to/log_archiver.py /var/log/myapp --days 7
这个脚本的主要特点:
- 多种压缩格式:支持gzip和zip格式
- 灵活的文件匹配:支持通配符模式
- 时间控制:可配置归档天数
- 日志记录:记录归档过程
- 错误处理:有基本的异常处理
- 可选功能:可以选择是否删除原文件
根据你的具体需求选择合适的版本使用,如果只是简单使用,基础版本就足够了;如果需要更多功能,可以使用高级版本。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播