当前位置: 首页 > article >正文

日志轮转方案和脚本

**日志轮转方案 **

1. 日志轮转概述

按月份分割和打包日志文件,并保留当前月份的日志。脚本会根据日志文件的内容格式(访问日志或错误日志)进行处理,创建相应的目录,将分割后的日志文件保存到按月份命名的目录中,最后将每个月的目录打包为 .tar.gz 文件,并清空原始日志文件,只保留当前月份的日志。

日志全量只留存一年,现服务器堆积一年前所有的日志已清空,本脚本没有添加按年删除的功能,需手动删除,也就是说在使用脚本之前需要处理一下今年之前的日志,或者在补充一下脚本灵活性,说实话我感觉这个脚本有点der,还不如直接上工具,有想法可以一起沟通,自己琢磨太费劲了,欢迎各位运维大佬

2. 配置和准备工作

· 日志目录: LOG_DIR 变量指定了日志文件所在的目录。

· 月份数组: MONTHS 变量包含了所有的月份数字,用于过滤日志内容。

· 月份名称: MONTH_NAMES 变量包含了月份的英文缩写,用于格式化日志内容。

· 日志文件路径: LOGFILE 变量指定了记录脚本运行日志的文件路径。

3. 脚本执行步骤

创建日志文件: 脚本首先创建一个日志文件,用于记录处理过程中的所有输出信息。

处理日志文件:

访问日志: 根据文件名中的 access 关键字,脚本将日志文件按照月份分割,并将每个月的日志保存到对应的目录中。

错误日志: 根据文件名中的 error 关键字,脚本将日志文件按照月份分割,并将每个月的日志保存到对应的目录中。

打包目录: 脚本将每个月的目录打包为 .tar.gz 文件,并删除原始目录。

清空****日志文件: 脚本清空原始日志文件切割内容,但保留当前月份的日志。

4. 定时任务设置

在每个月的第一天凌晨 2 点执行该脚本,按照以下步骤设置定时任务:

(1) 编辑 cron 配置文件:

crontab -e

(2) 添加定时任务**:******

0 2 1 * * /scripts/split_logs_by_month.sh

(3) 检查 cron 服务状态**😗*****

sudo systemctl status cron

crontab -l

5、**脚本测试 **

#在个人主机测试的,准备了两个日志文件

(1) 执行

/scripts/split_logs_by_month.sh

(2) 结果

#将日志按照月份切割后,按月份保存到目录,再生成压缩包,删除目录,原日志文件只剩余当月的日志

6、注意事项

· 确保日志目录存在: 在脚本执行前,确保 LOG_DIR 指定的目录存在。

· **权限: **确保脚本具有足够的权限来读取日志文件、创建目录、写入日志和执行其他操作。

#!/bin/bash
#auth:Dragon_qu
#version:v1.0



# 配置变量
LOG_DIR="/var/log/nginx"  # 日志目录
MONTHS=("01" "02" "03" "04" "05" "06" "07" "08" "09" "10" "11" "12")  # 月份数组
MONTH_NAMES=("Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec")  # 月份英文缩写
YEAR=$(date +%Y)  # 当前年份
CURRENT_MONTH=$(date +%m)  # 当前月份数字
LOGFILE="/scripts/split_logs_by_month_$(date +%Y%m%d).log"  # 日志文件路径

# 定义输出日志的函数
log() {
    echo "$(date +'%Y-%m-%d %H:%M:%S') $1" >> "$LOGFILE"
}

# 检查日志目录是否存在
if [ ! -d "$LOG_DIR" ]; then
    log "日志目录不存在:$LOG_DIR"
    exit 1
fi

# 定义函数来处理访问日志文件
process_access_log_file() {
    local log_file="$1"
    local log_filename=$(basename "$log_file")
    log "处理访问日志文件: $log_filename"

    for i in ${!MONTHS[@]}; do
        month_num=${MONTHS[$i]}
        month_name=${MONTH_NAMES[$i]}
        
        # 跳过当前月份的日志
        if [ "$month_num" == "$CURRENT_MONTH" ]; then
            continue
        fi

        # 检查日志文件是否包含对应月份的内容
        if grep -qE "\/$month_name" "$log_file"; then
            # 创建目标目录
            year_month="${YEAR}-${month_num}"
            month_dir="${LOG_DIR}/${year_month}"
            mkdir -p "$month_dir"

            # 使用 grep 过滤出对应月份的日志行,并重定向到新文件
            grep -E "\/$month_name" "$log_file" >> "${month_dir}/${log_filename}"
            log "日志已重定向到: ${month_dir}/${log_filename}"
        fi
    done

    log "[$log_filename] 日志已处理完毕"
}

# 定义函数来处理错误日志文件
process_error_log_file() {
    local log_file="$1"
    local log_filename=$(basename "$log_file")
    log "处理错误日志文件: $log_filename"

    for month_num in "${MONTHS[@]}"; do
        # 跳过当前月份的日志
        if [ "$month_num" == "$CURRENT_MONTH" ]; then
            continue
        fi

        log "检查月份: ${YEAR}/${month_num}/"
        # 检查错误日志格式是否存在
        if grep -qE "${YEAR}/${month_num}/" "$log_file"; then
            log "找到匹配: ${YEAR}/${month_num}/ 在文件: $log_file"
            # 创建目标目录
            year_month="${YEAR}-${month_num}"
            month_dir="${LOG_DIR}/${year_month}"
            mkdir -p "$month_dir"

            # 使用 grep 过滤出对应月份的日志行,并重定向到新文件
            grep -E "${YEAR}/${month_num}/" "$log_file" >> "${month_dir}/${log_filename}"
            log "日志已重定向到: ${month_dir}/${log_filename}"
        else
            log "未找到匹配: ${YEAR}/${month_num}/ 在文件: $log_file"
        fi
    done

    log "[$log_filename] 日志已处理完毕"
}

# 遍历日志目录中的每个 .log 文件,处理包含 "access" 或 "error" 的文件
for log_file in "$LOG_DIR"/*.log; do
    if [[ -f "$log_file" ]]; then
        if [[ "$log_file" == *access* ]]; then
            process_access_log_file "$log_file"
        elif [[ "$log_file" == *error* ]]; then
            process_error_log_file "$log_file"
        else
            log "未处理的日志文件: $log_file"
        fi
    else
        log "未找到日志文件: $log_file"
    fi
done

# 将每个月的目录打包成 .tar.gz 文件
for i in ${!MONTHS[@]}; do
    month_num=${MONTHS[$i]}
    year_month="${YEAR}-${month_num}"
    month_dir="${LOG_DIR}/${year_month}"

    if [ -d "$month_dir" ]; then
        tar -czf "${LOG_DIR}/${year_month}.tar.gz" -C "$LOG_DIR" "$year_month"
        log "目录 ${month_dir} 已打包为 ${LOG_DIR}/${year_month}.tar.gz"

        # 删除原始目录
        rm -rf "$month_dir"
        log "已删除原始目录: ${month_dir}"
    fi
done

# 清空原始日志文件,保留当前月份的日志
for log_file in "$LOG_DIR"/*.log; do
    if [[ -f "$log_file" ]]; then
        # 备份当前月份的日志到临时文件
        grep -E "\/$(date +%b)" "$log_file" > "${log_file}.tmp"

        # 用临时文件替换原始日志文件
        mv "${log_file}.tmp" "$log_file"
        log "已清空日志文件,但保留当前月份的日志: $log_file"
    fi
done

log "所有日志文件已按月份分割并输出到相应目录,并已打包且清空,保留当前月份的日志。"


http://www.kler.cn/news/293539.html

相关文章:

  • EvoSuite使用总结
  • Java+Swing+sqlserver学生成绩管理系统
  • springboot中上传图片到阿里云的oss云存储
  • CSS学习9[重点]--盒子模型大小、布局稳定性、CSS3盒模型以及盒子阴影
  • 端侧 ChatGPT 时刻到来!面壁小钢炮 3.0 重磅发布
  • Docker 在 Windows 上的使用指南
  • JVM性能调优之5种垃圾收集器
  • 【AI大模型应用开发】1.3 Prompt攻防(安全) 和 Prompt逆向工程
  • 滚珠花键助力生产加工精准化!
  • Python知识点:如何使用Python实现图像分类
  • 【Python】Requests:请求发送
  • log4j2 与 log4j使用时的几点小区别 - log4j2上手说明
  • WebStorm用Debug模式调试Vue等前端项目
  • 如何编写Linux PCI设备驱动器 之一
  • K8s中如何使用etcd进行集群信息的备份与恢复
  • el-table setCurrentRow会触发current-change函数 解决方案
  • php实用命令
  • 12,sql 中分组查询
  • GenBook RK3588一款模块化开源ARM笔记本电脑,具有高达32GB内存和模块化扩展功能
  • Vue3+vite中使用import.meta.glob
  • 【神经网络系列(高级)】神经网络Grokking现象的电路效率公式——揭秘学习飞跃的秘密【通俗理解】
  • STM32+ESP8266+MQTT协议连接阿里云实现温湿度上传
  • vue多环境配置和打包
  • 【基础】Three.js 自定义几何体和复制几何体
  • 研1日记5
  • IP学习——twoday
  • 43. 1 ~ n 整数中 1 出现的次数【难】
  • 路由器的固定ip地址是啥意思?固定ip地址有什么好处
  • 算法练习小技巧之有序集合--套路详细解析带例题(leetcode)
  • 使用 Nginx 部署前端 Vue.js 项目