本文目录导读:

基础Shell日志归档脚本
#!/bin/bash
# 日志归档脚本
# 功能:按日期归档并压缩日志文件
# 配置变量
LOG_DIR="/var/log/myapp" # 日志目录
ARCHIVE_DIR="/var/log/archives" # 归档目录
RETENTION_DAYS=30 # 保留天数
LOG_FILE="/var/log/archive.log" # 脚本日志
# 获取当前日期
CURRENT_DATE=$(date +%Y%m%d)
CURRENT_TIME=$(date '+%Y-%m-%d %H:%M:%S')
# 创建归档目录(如果不存在)
mkdir -p "$ARCHIVE_DIR"
# 日志函数
log_message() {
echo "[$CURRENT_TIME] $1" >> "$LOG_FILE"
}
# 开始归档
log_message "开始日志归档..."
# 归档昨天的日志(或其他需要归档的日志)
YESTERDAY=$(date -d "yesterday" +%Y%m%d)
ARCHIVE_NAME="logs_${YESTERDAY}.tar.gz"
# 查找并归档旧日志文件
find "$LOG_DIR" -name "*.log" -mtime +1 | while read file; do
BASENAME=$(basename "$file")
# 将文件移动到临时目录或直接打包
tar -rvf "/tmp/${ARCHIVE_NAME}" "$file" 2>/dev/null
if [ $? -eq 0 ]; then
# 压缩打包后的文件
gzip -f "/tmp/${ARCHIVE_NAME}"
mv "/tmp/${ARCHIVE_NAME}.gz" "$ARCHIVE_DIR/"
# 删除原始日志文件
rm -f "$file"
log_message "归档并删除: $file"
fi
done
# 清理旧归档(超过保留天数的)
find "$ARCHIVE_DIR" -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete
log_message "清理超过${RETENTION_DAYS}天的归档文件"
# 完成
log_message "日志归档完成"
增强版:支持多目录和压缩格式选择
#!/bin/bash
# 增强日志归档脚本
# 配置文件
CONFIG=(
["app1"]="/var/log/app1:/backup/app1:gzip"
["app2"]="/var/log/app2:/backup/app2:bzip2"
["nginx"]="/var/log/nginx:/backup/nginx:gzip"
)
# 日志分割函数
rotate_logs() {
local log_file=$1
local max_size=$2 # 单位:MB
# 检查文件大小
if [ -f "$log_file" ]; then
file_size=$(du -m "$log_file" | cut -f1)
if [ "$file_size" -gt "$max_size" ]; then
# 分割日志文件
timestamp=$(date +%Y%m%d_%H%M%S)
mv "$log_file" "${log_file}.${timestamp}"
touch "$log_file"
echo "日志文件 ${log_file} 已分割"
fi
fi
}
# 压缩函数
compress_logs() {
local src_dir=$1
local dest_dir=$2
local compress_type=$3
local date_str=$(date +%Y%m%d_%H%M%S)
mkdir -p "$dest_dir"
# 根据压缩类型选择压缩命令
case "$compress_type" in
"gzip")
find "$src_dir" -name "*.log*" -mtime +1 -exec tar -czf "${dest_dir}/archive_${date_str}.tar.gz" {} \;
;;
"bzip2")
find "$src_dir" -name "*.log*" -mtime +1 -exec tar -cjf "${dest_dir}/archive_${date_str}.tar.bz2" {} \;
;;
"xz")
find "$src_dir" -name "*.log*" -mtime +1 -exec tar -cJf "${dest_dir}/archive_${date_str}.tar.xz" {} \;
;;
esac
# 清理已归档的原始文件
if [ $? -eq 0 ]; then
find "$src_dir" -name "*.log*" -mtime +1 -delete
fi
}
# 主处理逻辑
for app_config in "${CONFIG[@]}"; do
IFS=':' read -r src dest compress <<< "$app_config"
echo "处理 ${src}..."
# 分割大文件(设置10MB阈值)
find "$src" -name "*.log" -type f | while read log_file; do
rotate_logs "$log_file" 10
done
# 压缩归档
compress_logs "$src" "$dest" "$compress"
done
echo "所有日志归档完成"
Python版本(更灵活的日志归档)
#!/usr/bin/env python3
import os
import shutil
import gzip
import tarfile
import datetime
import logging
from pathlib import Path
import glob
class LogArchiver:
def __init__(self, config):
self.config = config
self.setup_logging()
def setup_logging(self):
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler(self.config.get('log_file', 'archive.log')),
logging.StreamHandler()
]
)
self.logger = logging.getLogger(__name__)
def archive_logs(self, source_dir, archive_dir, days_old=1):
"""归档指定天数前的日志文件"""
source_path = Path(source_dir)
archive_path = Path(archive_dir)
# 创建归档目录
archive_path.mkdir(parents=True, exist_ok=True)
# 获取需要归档的文件
cutoff_date = datetime.datetime.now() - datetime.timedelta(days=days_old)
for log_file in source_path.glob('*.log*'):
# 检查文件修改时间
file_mtime = datetime.datetime.fromtimestamp(log_file.stat().st_mtime)
if file_mtime < cutoff_date:
self._compress_file(log_file, archive_path)
def _compress_file(self, file_path, archive_path):
"""压缩单个文件并移动到归档目录"""
try:
# 创建tar.gz归档
archive_name = f"{file_path.stem}_{datetime.datetime.now().strftime('%Y%m%d')}.tar.gz"
archive_file = archive_path / archive_name
with tarfile.open(archive_file, 'w:gz') as tar:
tar.add(file_path, arcname=file_path.name)
# 删除原始文件
file_path.unlink()
self.logger.info(f"已归档: {file_path} -> {archive_file}")
except Exception as e:
self.logger.error(f"归档失败 {file_path}: {str(e)}")
def cleanup_old_archives(self, archive_dir, retention_days=30):
"""清理超过保留天数的归档文件"""
archive_path = Path(archive_dir)
cutoff_date = datetime.datetime.now() - datetime.timedelta(days=retention_days)
for archive_file in archive_path.glob('*.tar.gz'):
file_mtime = datetime.datetime.fromtimestamp(archive_file.stat().st_mtime)
if file_mtime < cutoff_date:
archive_file.unlink()
self.logger.info(f"已删除旧归档: {archive_file}")
# 使用示例
if __name__ == "__main__":
config = {
'log_file': '/var/log/log_archiver.log'
}
archiver = LogArchiver(config)
# 归档日志
archiver.archive_logs('/var/log/myapp', '/var/log/archives', days_old=1)
# 清理30天前的归档
archiver.cleanup_old_archives('/var/log/archives', retention_days=30)
定时任务配置(crontab)
# 每天凌晨2点执行归档 0 2 * * * /path/to/archive_script.sh # 每周日凌晨3点执行周归档 0 3 * * 0 /path/to/weekly_archive.sh # 每月1号凌晨4点执行月归档 0 4 1 * * /path/to/monthly_archive.sh
使用建议
-
权限设置:确保脚本有执行权限
chmod +x archive_script.sh
-
测试运行:先用测试目录验证脚本
-
日志监控:保持归档操作的日志记录
-
错误处理:添加完善的错误处理机制
-
空间监控:检查磁盘空间是否充足
选择适合您需求的版本,并根据实际情况调整路径和参数。