本文目录导读:

我来详细介绍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
这个脚本提供了完整的容器日志告警解决方案,包括实时监控、多维度分析、多种告警方式和灵活的配置选项。