如何编写日志归档脚本

wen 实用脚本 24

本文目录导读:

如何编写日志归档脚本

  1. 基础Shell日志归档脚本
  2. 增强版:支持多目录和压缩格式选择
  3. Python版本(更灵活的日志归档)
  4. 定时任务配置(crontab)
  5. 使用建议

基础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

使用建议

  1. 权限设置:确保脚本有执行权限

    chmod +x archive_script.sh
  2. 测试运行:先用测试目录验证脚本

  3. 日志监控:保持归档操作的日志记录

  4. 错误处理:添加完善的错误处理机制

  5. 空间监控:检查磁盘空间是否充足

选择适合您需求的版本,并根据实际情况调整路径和参数。

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