Shell脚本如何配置容器日志告警

wen 实用脚本 1

本文目录导读:

Shell脚本如何配置容器日志告警

  1. 基础日志监控脚本
  2. 增强版日志告警脚本
  3. 多维度日志告警脚本
  4. 配置文件示例
  5. 部署脚本
  6. 使用说明

我来详细介绍Shell脚本配置容器日志告警的多种方案。

基础日志监控脚本

实时日志监控告警

#!/bin/bash
# 配置参数
CONTAINER_NAME="my-app"
LOG_PATTERN="ERROR|FATAL|CRITICAL"
ALERT_EMAIL="admin@example.com"
LOG_FILE="/var/log/container/${CONTAINER_NAME}.log"
# 监控函数
monitor_container_logs() {
    tail -f ${LOG_FILE} | while read line; do
        if echo "$line" | grep -qE "${LOG_PATTERN}"; then
            echo "告警: ${CONTAINER_NAME} 检测到异常日志"
            echo "$line" | mail -s "容器日志告警 - ${CONTAINER_NAME}" ${ALERT_EMAIL}
        fi
    done
}
# 执行监控
monitor_container_logs

增强版日志告警脚本

#!/bin/bash
# ============ 配置变量 ============
LOG_DIR="/var/log/containers"
CONTAINERS=("app1" "app2" "app3")
ALERT_THRESHOLD=5  # 5分钟内出现5次告警
ALERT_INTERVAL=300 # 告警间隔(秒)
WEBHOOK_URL="https://hooks.slack.com/services/xxx/xxx/xxx"
LOG_PATTERNS=(
    "ERROR"
    "FATAL"
    "CRITICAL"
    "Exception"
    "Connection refused"
    "OutOfMemory"
)
# ============ 工具函数 ============
timestamp() {
    date "+%Y-%m-%d %H:%M:%S"
}
send_slack_alert() {
    local message="$1"
    curl -X POST -H 'Content-type: application/json' \
        --data "{
            \"text\": \"🚨 容器日志告警: ${message}\",
            \"channel\": \"#alerts\",
            \"username\": \"LoggerBot\"
        }" ${WEBHOOK_URL}
}
send_email_alert() {
    local subject="$1"
    local body="$2"
    echo "${body}" | mail -s "${subject}" admin@example.com
}
# ============ 日志分析函数 ============
check_container_logs() {
    local container=$1
    local container_log="${LOG_DIR}/${container}.log"
    local temp_file="/tmp/container_alert_${container}.tmp"
    # 检查日志文件是否存在
    if [ ! -f "${container_log}" ]; then
        echo "$(timestamp) [WARN] 日志文件不存在: ${container_log}"
        return 1
    fi
    # 获取最近5分钟的日志
    local recent_logs=$(find "${container_log}" -newer "${temp_file}" 2>/dev/null)
    for pattern in "${LOG_PATTERNS[@]}"; do
        local match_count=$(echo "${recent_logs}" | grep -c "${pattern}")
        if [ ${match_count} -gt 0 ]; then
            local alert_message="${container}: 发现 ${match_count} 条 '${pattern}' 模式日志"
            echo "$(timestamp) [ALERT] ${alert_message}"
            # 获取匹配的日志详情
            local log_details=$(echo "${recent_logs}" | grep "${pattern}" | tail -5)
            # 发送告警
            send_slack_alert "${alert_message}\n\`\`\`${log_details}\`\`\`"
        fi
    done
    # 更新时间戳
    touch "${temp_file}"
}
# ============ 主循环 ============
main() {
    echo "$(timestamp) [INFO] 启动容器日志监控..."
    while true; do
        for container in "${CONTAINERS[@]}"; do
            check_container_logs "${container}"
        done
        # 等待30秒后再次检查
        sleep 30
    done
}
# 处理优雅退出
trap 'echo "$(timestamp) [INFO] 停止监控..."; exit 0' SIGINT SIGTERM
# 启动主循环
main

多维度日志告警脚本

#!/bin/bash
# ============ 配置 ============
CONFIG_FILE="/etc/log-alert/config.ini"
STATE_DIR="/var/run/log-alert"
LOG_DIR="/var/log/containers"
BACKUP_DIR="/var/log/alerts"
# 默认配置
LOG_LEVELS="ERROR,WARN,CRITICAL"
ALERT_METHODS="email,slack,webhook"
ERROR_THRESHOLD=3
TIME_WINDOW=300
COOLDOWN_PERIOD=600
# ============ 初始化 ============
init() {
    mkdir -p ${STATE_DIR}
    mkdir -p ${BACKUP_DIR}
    # 加载配置
    if [ -f "${CONFIG_FILE}" ]; then
        source "${CONFIG_FILE}"
    fi
}
# ============ 高级日志分析 ============
analyze_log_pattern() {
    local log_content="$1"
    local pattern="$2"
    # 统计频率
    local frequency=$(echo "${log_content}" | grep -c "pattern")
    # 提取时间戳
    local timestamps=$(echo "${log_content}" | grep -oP '\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}')
    # 计算趋势
    local trend="stable"
    if [ ${frequency} -gt ${ERROR_THRESHOLD} ]; then
        trend="increasing"
    fi
    echo "${frequency}|${trend}|${timestamps}"
}
# ============ 实时监控引擎 ============
monitor_container() {
    local container=$1
    local container_log="${LOG_DIR}/${container}.log"
    local state_file="${STATE_DIR}/${container}.state"
    # 获取监控状态
    local last_check=0
    local alert_count=0
    if [ -f "${state_file}" ]; then
        source "${state_file}"
    fi
    # 检查新日志
    local new_logs=""
    if [ ${last_check} -gt 0 ]; then
        new_logs=$(tail -n +${last_check} "${container_log}")
    else
        new_logs=$(tail -c +1 "${container_log}")
    fi
    if [ -z "${new_logs}" ]; then
        return 0
    fi
    # 分析新日志
    for level in $(echo ${LOG_LEVELS} | tr ',' ' '); do
        local result=$(analyze_log_pattern "${new_logs}" "${level}")
        local frequency=$(echo "${result}" | cut -d'|' -f1)
        if [ ${frequency} -gt 0 ]; then
            # 检查是否需要告警
            local current_time=$(date +%s)
            local time_diff=$((current_time - last_alert_time))
            if [ ${time_diff} -gt ${COOLDOWN_PERIOD} ] && [ ${frequency} -gt ${ERROR_THRESHOLD} ]; then
                # 生成告警
                generate_alert "${container}" "${level}" "${frequency}" "${result}"
                # 更新状态
                echo "last_alert_time=${current_time}" > ${state_file}
                echo "alert_count=$((alert_count + 1))" >> ${state_file}
            fi
        fi
    done
    # 记录检查点
    local line_count=$(wc -l < "${container_log}")
    echo "last_check=${line_count}" >> ${state_file}
}
# ============ 告警生成器 ============
generate_alert() {
    local container=$1
    local level=$2
    local frequency=$3
    local details=$4
    local alert_time=$(date "+%Y-%m-%d %H:%M:%S")
    local alert_id="alert_${container}_${alert_time}"
    # 构建告警消息
    local alert_subject="[${level}] 容器日志告警 - ${container}"
    local alert_body="
时间: ${alert_time}
容器: ${container}
级别: ${level}
频率: ${frequency}次/${TIME_WINDOW}秒
详情: 
${details}
    "
    # 记录告警
    echo "${alert_body}" >> "${BACKUP_DIR}/${alert_id}.log"
    # 发送告警
    for method in $(echo ${ALERT_METHODS} | tr ',' ' '); do
        case ${method} in
            email)
                echo "${alert_body}" | mail -s "${alert_subject}" admin@example.com
                ;;
            slack)
                curl -X POST -H 'Content-type: application/json' \
                    --data "{\"text\":\"${alert_body}\"}" \
                    "${SLACK_WEBHOOK_URL}"
                ;;
            webhook)
                curl -X POST -H 'Content-Type: application/json' \
                    --data "$(jq -n --arg subj "${alert_subject}" --arg body "${alert_body}" '{subject: $subj, body: $body}')" \
                    "${WEBHOOK_URL}"
                ;;
        esac
    done
}
# ============ 主流程 ============
main_loop() {
    init
    echo "========================================"
    echo "容器日志告警监控系统启动"
    echo "时间: $(date)"
    echo "监控日志目录: ${LOG_DIR}"
    echo "告警级别: ${LOG_LEVELS}"
    echo "========================================"
    while true; do
        # 获取所有运行中的容器
        local containers=$(docker ps --format "{{.Names}}" 2>/dev/null)
        if [ $? -ne 0 ]; then
            echo "[ERROR] Docker命令执行失败"
            sleep 60
            continue
        fi
        # 监控每个容器
        for container in ${containers}; do
            monitor_container "${container}"
        done
        # 等待
        sleep 30
    done
}
# ============ 启动 ============
main_loop

配置文件示例

/etc/log-alert/config.ini

# 日志级别
LOG_LEVELS=ERROR,CRITICAL,FATAL,WARN
# 告警阈值
ERROR_THRESHOLD=3
WARN_THRESHOLD=10
# 时间窗口(秒)
TIME_WINDOW=300
# 冷却时间(秒)
COOLDOWN_PERIOD=600
# 告警方式
ALERT_METHODS=email,slack,webhook
# Slack配置
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/xxx/xxx/xxx
# Email配置
SMTP_SERVER=smtp.example.com
SMTP_PORT=587
SMTP_USER=alert@example.com
SMTP_PASS=your_password
ALERT_EMAIL=admin@example.com
# Webhook配置
WEBHOOK_URL=http://your-webhook-server/alert
# 需要忽略的日志模式
IGNORE_PATTERNS=heartbeat,healthcheck
# Docker配置
CONTAINER_FILTER="name:app-*"

部署脚本

#!/bin/bash
# 部署日志告警系统
deploy_alert_system() {
    local install_dir="/opt/log-alert"
    local config_dir="/etc/log-alert"
    echo "开始部署容器日志告警系统..."
    # 创建目录
    mkdir -p ${install_dir}
    mkdir -p ${config_dir}
    mkdir -p /var/run/log-alert
    mkdir -p /var/log/alerts
    # 复制脚本
    cp alert-script.sh ${install_dir}/
    chmod +x ${install_dir}/alert-script.sh
    # 复制配置
    cp config.ini ${config_dir}/
    chmod 600 ${config_dir}/config.ini
    # 创建systemd服务
    cat > /etc/systemd/system/log-alert.service <<EOF
[Unit]
Description=Container Log Alert Service
After=docker.service
Requires=docker.service
[Service]
Type=simple
ExecStart=${install_dir}/alert-script.sh
Restart=always
RestartSec=10
User=root
Group=root
[Install]
WantedBy=multi-user.target
EOF
    # 启动服务
    systemctl daemon-reload
    systemctl enable log-alert
    systemctl start log-alert
    echo "部署完成!"
    echo "检查状态: systemctl status log-alert"
}

使用说明

安装和配置

# 1. 创建脚本文件
chmod +x log-alert.sh
# 2. 配置crontab定期检查
*/5 * * * * /opt/log-alert/log-alert.sh
# 3. 或者作为服务运行
nohup ./log-alert.sh > /var/log/log-alert.log 2>&1 &
# 4. 测试告警
./log-alert.sh --test

命令行选项

# 查看帮助
./log-alert.sh --help
# 指定配置文件
./log-alert.sh --config /etc/log-alert/custom.ini
# 仅监控特定容器
./log-alert.sh --containers my-app,my-web
# 调试模式
./log-alert.sh --debug

这个脚本提供了完整的容器日志告警解决方案,包括实时监控、多维度分析、多种告警方式和灵活的配置选项。

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