本文目录导读:

在Shell脚本中设置告警依赖关系,通常有几种常见方式:
基于返回值的依赖检查
#!/bin/bash
# 检查前置告警是否已触发
check_prerequisite_alarm() {
local prereq_alarm="$1"
# 检查告警文件或日志是否存在
if [ -f "/tmp/alarms/${prereq_alarm}.triggered" ]; then
return 0 # 前置告警已触发
else
return 1 # 前置告警未触发
fi
}
# 主告警逻辑
main_alarm() {
# 检查依赖
if check_prerequisite_alarm "cpu_high"; then
echo "CPU高告警已触发,可以发送关联告警"
# 发送告警逻辑
send_alarm "内存使用率过高"
else
echo "前置条件未满足,跳过告警"
fi
}
时间窗口依赖
#!/bin/bash
# 检查在指定时间窗口内是否发生过告警
check_time_window_dependency() {
local alarm_type="$1"
local window_minutes="$2"
local alarm_log="/var/log/alarms.log"
# 获取当前时间
current_time=$(date +%s)
# 检查最近window_minutes分钟内是否有相关告警
recent_alarm=$(awk -v alarm="$alarm_type" -v current="$current_time" -v window="$window_minutes" '
$1 ~ alarm {
alarm_time = $2
if ((current - alarm_time) < (window * 60)) {
print $0
exit
}
}
' "$alarm_log")
if [ -n "$recent_alarm" ]; then
return 0 # 找到匹配的告警
else
return 1 # 未找到
fi
}
# 使用示例
if check_time_window_dependency "CPU_ALARM" 30; then
# 30分钟内有CPU告警,执行内存告警
trigger_alarm "MEMORY_ALARM"
fi
状态文件依赖
#!/bin/bash
STATE_DIR="/var/run/alarm_states"
DEPENDENCY_FILE="${STATE_DIR}/dependency_chain.conf"
# 检查依赖链
check_dependency_chain() {
local current_alarm="$1"
# 从配置文件读取依赖关系
while IFS=':' read -r alarm depends_on; do
if [ "$alarm" = "$current_alarm" ]; then
# 检查依赖的告警状态
for dep in $(echo "$depends_on" | tr ',' ' '); do
dep_state_file="${STATE_DIR}/${dep}.state"
if [ ! -f "$dep_state_file" ]; then
return 1 # 依赖不满足
fi
# 检查状态是否为已触发
state=$(cat "$dep_state_file")
if [ "$state" != "TRIGGERED" ]; then
return 1
fi
done
return 0 # 所有依赖满足
fi
done < "$DEPENDENCY_FILE"
return 1 # 未找到依赖配置
}
# 设置告警状态
set_alarm_state() {
local alarm="$1"
local state="$2"
mkdir -p "$STATE_DIR"
echo "$state" > "${STATE_DIR}/${alarm}.state"
}
# 使用示例
if check_dependency_chain "HIGH_MEMORY_ALARM"; then
echo "依赖满足,触发告警"
set_alarm_state "HIGH_MEMORY_ALARM" "TRIGGERED"
fi
带优先级的依赖管理
#!/bin/bash
# 告警优先级和依赖配置
declare -A ALARM_PRIORITY
declare -A ALARM_DEPENDENCIES
# 初始化配置
init_alarm_config() {
ALARM_PRIORITY["CRITICAL"]=1
ALARM_PRIORITY["HIGH"]=2
ALARM_PRIORITY["MEDIUM"]=3
ALARM_PRIORITY["LOW"]=4
ALARM_DEPENDENCIES["HIGH_MEMORY"]="HIGH_CPU,SWAP_USAGE"
ALARM_DEPENDENCIES["CRITICAL_DISK"]="HIGH_DISK,WARNING_DISK"
}
# 检查告警优先级
check_alarm_priority() {
local alarm_type="$1"
local required_priority="$2"
if [ "${ALARM_PRIORITY[$alarm_type]}" -le "$required_priority" ]; then
return 0 # 优先级满足
else
return 1 # 优先级不够
fi
}
# 执行依赖检查
execute_alarm_with_dependencies() {
local alarm_type="$1"
local alarm_message="$2"
init_alarm_config
# 检查是否存在依赖
if [ -n "${ALARM_DEPENDENCIES[$alarm_type]}" ]; then
echo "告警 $alarm_type 存在依赖: ${ALARM_DEPENDENCIES[$alarm_type]}"
# 将依赖字符串转为数组
IFS=',' read -ra dependencies <<< "${ALARM_DEPENDENCIES[$alarm_type]}"
for dep in "${dependencies[@]}"; do
dep=$(echo "$dep" | tr -d ' ')
echo "检查依赖: $dep"
if ! check_alarm_priority "$dep" 2; then
echo "依赖 $dep 优先级未满足"
return 1
fi
# 检查依赖告警状态
if [ ! -f "/tmp/alarms/${dep}.triggered" ]; then
echo "依赖告警 $dep 未触发"
return 1
fi
done
fi
# 所有依赖满足,执行告警
echo "所有依赖检查通过,触发告警: $alarm_type - $alarm_message"
touch "/tmp/alarms/${alarm_type}.triggered"
return 0
}
# 使用示例
execute_alarm_with_dependencies "HIGH_MEMORY" "内存使用率超过90%"
完整的依赖告警系统示例
#!/bin/bash
# 告警依赖管理系统
ALARM_CONFIG="/etc/alarm_dependencies.conf"
ALARM_STATE_DIR="/var/run/alarms"
LOG_FILE="/var/log/alarm_dependency.log"
# 初始化
init_alarm_system() {
mkdir -p "$ALARM_STATE_DIR"
touch "$LOG_FILE"
# 创建默认依赖配置
if [ ! -f "$ALARM_CONFIG" ]; then
cat > "$ALARM_CONFIG" << EOF
# 告警依赖配置
# 格式:告警名称:依赖告警:超时时间(秒)
HIGH_CPU:CRITICAL_CPU:300
HIGH_MEMORY:HIGH_CPU,SWAP_USAGE:600
CRITICAL_DISK:HIGH_DISK:120
EOF
fi
}
# 记录日志
log_message() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
# 读取依赖配置
get_dependencies() {
local alarm_name="$1"
grep -w "^${alarm_name}:" "$ALARM_CONFIG" | cut -d: -f2
}
# 获取超时时间
get_timeout() {
local alarm_name="$1"
grep -w "^${alarm_name}:" "$ALARM_CONFIG" | cut -d: -f3
}
# 检查单个依赖
check_single_dependency() {
local dependency="$1"
local timeout="$2"
local dep_state_file="${ALARM_STATE_DIR}/${dependency}.state"
if [ ! -f "$dep_state_file" ]; then
log_message "依赖告警 $dependency 状态文件不存在"
return 1
fi
# 获取依赖告警的状态和时间
read -r state timestamp < "$dep_state_file"
current_time=$(date +%s)
# 检查是否在超时时间内
if [ "$state" = "TRIGGERED" ] && [ $((current_time - timestamp)) -le "$timeout" ]; then
return 0 # 依赖满足
else
log_message "依赖告警 $dependency 不满足(状态: $state, 时间: $timestamp)"
return 1
fi
}
# 更新告警状态
update_alarm_state() {
local alarm_name="$1"
local state="$2"
local state_file="${ALARM_STATE_DIR}/${alarm_name}.state"
echo "$state $(date +%s)" > "$state_file"
log_message "更新告警 $alarm_name 状态为 $state"
}
# 主告警处理函数
process_alarm() {
local alarm_name="$1"
local alarm_message="$2"
local alarm_severity="$3"
log_message "处理告警: $alarm_name ($alarm_severity)"
# 获取依赖
dependencies=$(get_dependencies "$alarm_name")
if [ -n "$dependencies" ]; then
timeout=$(get_timeout "$alarm_name")
timeout=${timeout:-300} # 默认300秒
log_message "检查依赖: $dependencies"
IFS=',' read -ra dep_list <<< "$dependencies"
for dep in "${dep_list[@]}"; do
dep=$(echo "$dep" | tr -d ' ')
if ! check_single_dependency "$dep" "$timeout"; then
log_message "依赖检查失败,跳过告警 $alarm_name"
return 1
fi
done
fi
# 执行告警
log_message "触发告警: $alarm_name - $alarm_message"
update_alarm_state "$alarm_name" "TRIGGERED"
# 执行告警动作
case "$alarm_severity" in
CRITICAL)
# 发送紧急通知
echo "紧急告警: $alarm_message" | mail -s "CRITICAL: $alarm_name" admin@example.com
;;
HIGH)
# 发送邮件
echo "高级告警: $alarm_message" | mail -s "HIGH: $alarm_name" team@example.com
;;
MEDIUM)
# 记录日志
logger -t alarm "MEDIUM: $alarm_name - $alarm_message"
;;
esac
return 0
}
# 主程序
init_alarm_system
# 处理命令行参数
case "${1:-}" in
trigger)
process_alarm "$2" "$3" "${4:-MEDIUM}"
;;
status)
if [ -n "$2" ]; then
cat "${ALARM_STATE_DIR}/${2}.state" 2>/dev/null || echo "未找到告警状态"
else
ls -la "$ALARM_STATE_DIR"
fi
;;
*)
echo "用法: $0 {trigger|status} [alarm_name] [message] [severity]"
exit 1
;;
esac
关键要点:
- 使用状态文件:维持告警状态的持久化
- 超时机制:避免依赖长期不满足
- 日志记录:便于问题排查
- 配置分离:依赖关系独立管理
- 优先级控制:允许设置告警级别
这种设计可以有效管理复杂的告警依赖关系,确保告警触发的准确性和合理性。