200字
nginx日志分割脚本
2025-10-12
2025-10-12
[root@aliyun nginx]# cat /etc/nginx/scripts/nginx_log_rotate.sh 
#!/bin/bash
# 乐哥的nginx日志分割脚本
# ======================== 定义变量 ========================
# Nginx PID文件路径、日志文件路径
NGINX_PID="/var/run/nginx.pid"
ACCESS_LOG="/var/log/nginx/access.log"
ERROR_LOG="/var/log/nginx/error.log"

# 日志备份目录
BACKUP_DIR="/var/log/nginx/backup"

# 保留备份日志的天数
RETENTION_DAYS=15

# 获取当前日期,用于后缀名
TIMESTAMP=$(date +%Y%m%d%H%M%S)_${RANDOM}
# =========================================================



# 检查并创建备份目录
function check_and_create_backup_dir() {
    echo "[INFO] 检查备份目录: ${BACKUP_DIR}"
    
    if [ ! -d "${BACKUP_DIR}" ]; then
        echo "[INFO] 创建备份目录并设置权限: ${BACKUP_DIR}"
        mkdir -p "${BACKUP_DIR}" && chown nginx:root "${BACKUP_DIR}" && chmod 755 "${BACKUP_DIR}"
        if [ $? -ne 0 ]; then
            echo "[ERROR] 备份目录创建失败"
            return 1
        fi
    else
        # 检查所有者
        local current_owner=$(stat -c "%U:%G" "${BACKUP_DIR}")
        if [ "${current_owner}" != "nginx:root" ]; then
            echo "[INFO] 修正备份目录所有者为 nginx:root"
            chown nginx:root "${BACKUP_DIR}" || echo "[ERROR] 修正备份目录所有者失败"
        fi
        # 检查权限
        local current_perm=$(stat -c "%a" "${BACKUP_DIR}")
        if [ "${current_perm}" != "755" ]; then
            echo "[INFO] 修正备份目录权限为 755"
            chmod 755 "${BACKUP_DIR}" || echo "[ERROR] 修正备份目录权限失败"
        fi
    fi
    return 0
}



# 切割日志文件
function rotate_log_file() {
    local log_file="$1"
    local log_name=$(basename "${log_file}")
    local backup_file="${BACKUP_DIR}/${log_name}-${TIMESTAMP}"

    # 1. 检查文件有效性(无效则返回)
    if [ -z "${log_file}" ]; then
        echo "[ERROR] 日志文件路径未指定"
        return 1
    fi
    if [ ! -f "${log_file}" ]; then
        echo "[ERROR] 日志文件不存在: ${log_file}"
        return 1
    fi

    # 2. 执行日志切割
    echo "[INFO] 开始切割日志: ${log_file}"
    mv "${log_file}" "${backup_file}"
    if [ $? -eq 0 ]; then
        echo "[INFO] 日志切割完成: ${backup_file}"

        # 3. 压缩备份
        gzip "${backup_file}"
        if [ $? -eq 0 ]; then
            echo "[INFO] 日志压缩完成: ${backup_file}.gz"
        else
            echo "[ERROR] 日志压缩失败"
            return 1
        fi
    else
        echo "[ERROR] 日志移动失败"
        return 1
    fi
    return 0
}




# 通知Nginx重启日志
function reload_nginx_log() {
    local pid_file="$1"  # 明确参数是PID文件路径
    echo "[INFO] 通知Nginx重新生成日志(PID文件: ${pid_file})"

    # 1. 检查PID文件是否存在
    if [ ! -f "${pid_file}" ]; then
        echo "[ERROR] 未找到Nginx PID文件: ${pid_file}"
        return 1
    fi

    # 2. 读取PID文件内容,获取实际PID号
    local nginx_pid=$(cat "${pid_file}")
    if [ -z "${nginx_pid}" ]; then
        echo "[ERROR] PID文件为空: ${pid_file}"
        return 1
    fi

    # 3. 检查PID对应的进程是否存在
    ps -p "${nginx_pid}" > /dev/null
    if [ $? -eq 0 ]; then
        kill -USR1 "${nginx_pid}"
        if [ $? -eq 0 ]; then
            echo "[INFO] Nginx日志已重启 (PID: ${nginx_pid})"
        else
            return 1
        fi
    else
        echo "[ERROR] Nginx进程不存在 (PID: ${nginx_pid})"
        return 1
    fi
    return 0
}



# 清理过期日志
function clean_expired_logs() {
    echo "[INFO] 清理${RETENTION_DAYS}天前的过期日志"
    if [ -d "${BACKUP_DIR}" ]; then
        find "${BACKUP_DIR}" -name "*.log-*.gz" -type f -mtime +"${RETENTION_DAYS}" -exec rm -f {} \;
        echo "[INFO] 过期日志清理完成"
    else
        echo "[WARNING] 备份目录不存在,跳过清理"
    fi
}




# ======================== 主执行流程 ========================
# 主流程:目录检查 → 切割访问日志 → 切割错误日志 → 重启日志 → 清理过期日志

echo "======================================================"
echo "[INFO] 日志切割脚本启动: $(date +%Y-%m-%d\ %H:%M:%S)"
echo "======================================================"

check_and_create_backup_dir || exit 1
rotate_log_file "${ACCESS_LOG}"
rotate_log_file "${ERROR_LOG}"
reload_nginx_log "${NGINX_PID}"
clean_expired_logs

echo "======================================================"
echo "[INFO] 日志切割脚本完成: $(date +%Y-%m-%d\ %H:%M:%S)"
echo "======================================================"

评论