4. 告警源接入设计:Prometheus、Zabbix、云监控等告警源的统一接入规范与适配器模式
在 Runbook 告警自愈体系中,告警源接入是触发链路的第一道关卡。生产环境中通常同时存在 Prometheus、Zabbix、各类云监控(阿里云、AWS、腾讯云)等多种监控系统,它们产生的告警格式、传输协议、字段语义各不相同。若为每种告警源单独开发自愈逻辑,会导致系统耦合度高、扩展性差、维护成本激增。
本章核心设计目标:通过适配器模式(Adapter Pattern)建立统一告警接入规范,将异构告警源转化为标准内部事件,实现告警源与自愈引擎的解耦。
4.1 统一告警接入规范(UAI)
统一告警接入规范(Unified Alert Ingestion, UAI)定义了自愈引擎能够理解的标准告警数据结构。所有告警源适配器必须将原始告警转换为 UAI 格式后,才能提交至自愈触发链路。
| UAI 字段 | 类型 | 说明 | 示例 |
|---|---|---|---|
| alert_id | string | 全局唯一告警标识,由适配器生成 | prom-20250321-001 |
| source | string | 告警源类型标识 | prometheus / zabbix / aliyun |
| alert_name | string | 告警规则名称 | HighCpuUsage |
| severity | enum | 标准化严重级别:critical / warning / info |
critical |
| status | enum | 告警状态:firing / resolved |
firing |
| timestamp | int64 | 告警触发 Unix 时间戳(秒) | 1742524800 |
| labels | map[string]string | 标签键值对,包含实例、集群等维度 | {"instance":"10.0.1.5:9090","env":"prod"} |
| annotations | map[string]string | 注解信息,包含描述、建议操作等 | {"summary":"CPU > 90%","runbook":"/runbooks/cpu.md"} |
| raw_payload | string | 原始告警 JSON/XML 全文(用于审计) | {...} |
alert_id、source、severity、status、timestamp 五个核心字段,确保自愈引擎能够基于这些字段完成去重、过滤、路由和恢复判定。
4.2 适配器模式架构设计
适配器模式在此场景中充当“翻译层”:每个告警源对应一个适配器实例,负责监听/接收原始告警,将其转换为 UAI 标准格式,然后推送到统一的消息队列或 API 网关。自愈引擎只消费 UAI 格式的告警,无需关心底层告警源的具体实现。
4.3 主流告警源适配器实现要点
4.3.1 Prometheus 适配器
Prometheus 通过 Alertmanager 的 Webhook 接收器推送告警。适配器监听 HTTP POST 请求,解析 Alertmanager 的 JSON 负载,映射到 UAI 字段。
// Prometheus Webhook 负载示例
{
"version": "4",
"groupKey": "{}:{alertname=\"HighCpuUsage\"}",
"status": "firing",
"alerts": [
{
"status": "firing",
"labels": {
"alertname": "HighCpuUsage",
"instance": "10.0.1.5:9090",
"severity": "critical"
},
"annotations": {
"summary": "CPU usage > 90%",
"runbook_url": "http://runbook.example.com/cpu"
},
"startsAt": "2025-03-21T10:00:00Z"
}
]
}
// Prometheus 适配器核心转换逻辑(伪代码)
func convertPromAlert(promAlert Alert) UAIAlert {
return UAIAlert{
AlertID: "prom-" + promAlert.Labels["alertname"] + "-" + strconv.FormatInt(promAlert.StartsAt.Unix(), 10),
Source: "prometheus",
AlertName: promAlert.Labels["alertname"],
Severity: normalizeSeverity(promAlert.Labels["severity"]),
Status: promAlert.Status,
Timestamp: promAlert.StartsAt.Unix(),
Labels: promAlert.Labels,
Annotations: promAlert.Annotations,
RawPayload: json.Marshal(promAlert),
}
}
4.3.2 Zabbix 适配器
Zabbix 通过 Action 配置 Webhook 媒体类型,发送 JSON 或 XML 格式的告警。适配器需要处理 Zabbix 特有的字段命名风格(如 TRIGGER.SEVERITY、ITEM.VALUE)。
| Zabbix 宏变量 | UAI 映射字段 | 说明 |
|---|---|---|
{TRIGGER.NAME} |
alert_name |
触发器名称 |
{TRIGGER.SEVERITY} |
severity |
映射为 critical/warning/info |
{TRIGGER.STATUS} |
status |
PROBLEM → firing, OK → resolved |
{EVENT.DATE} + {EVENT.TIME} |
timestamp |
拼接后转为 Unix 时间戳 |
{HOST.NAME} |
labels["host"] |
主机名作为标签 |
{ITEM.VALUE} |
annotations["value"] |
当前监控项值 |
4.3.3 云监控适配器
云监控(阿里云 CMS、AWS CloudWatch、腾讯云 CM)通常通过 HTTP Webhook 或消息队列(SNS/SQS)推送告警。适配器需处理不同云厂商的认证签名和重试机制。
- 鉴权验证:校验请求签名(阿里云 HMAC-SHA1、AWS SigV4),防止伪造告警。
- 格式转换:将云厂商的告警 JSON 结构映射到 UAI 字段,注意字段名差异(如阿里云
alertName→ UAIalert_name)。 - 去重标识:使用云厂商提供的
alertId或eventId作为 UAIalert_id的一部分,确保全局唯一。 - 重试与幂等:云监控可能重复推送,适配器需在转换层做幂等处理(基于
alert_id去重)。
4.4 适配器注册与动态加载
为支持告警源的动态扩展,适配器采用插件化注册机制。系统启动时扫描适配器目录,根据配置文件加载对应的适配器实例。
4.5 适配器接口定义
以下为适配器核心接口的 Go 语言定义,所有告警源适配器必须实现该接口:
// AlertAdapter 定义告警源适配器接口
type AlertAdapter interface {
// Name 返回适配器名称,用于注册和日志标识
Name() string
// Start 启动适配器监听,接收原始告警
Start(ctx context.Context) error
// Stop 优雅停止适配器
Stop() error
// Convert 将原始告警负载转换为 UAI 标准格式
Convert(rawPayload []byte) (*UAIAlert, error)
// Health 返回适配器健康状态
Health() HealthStatus
}
// UAIAlert 统一告警结构
type UAIAlert struct {
AlertID string `json:"alert_id"`
Source string `json:"source"`
AlertName string `json:"alert_name"`
Severity string `json:"severity"`
Status string `json:"status"`
Timestamp int64 `json:"timestamp"`
Labels map[string]string `json:"labels"`
Annotations map[string]string `json:"annotations"`
RawPayload string `json:"raw_payload"`
}
// HealthStatus 健康状态
type HealthStatus struct {
Status string `json:"status"` // "up" / "down"
LastError string `json:"last_error"`
Uptime int64 `json:"uptime"`
}
4.6 适配器配置规范
每个适配器通过独立的 YAML 配置段定义连接参数、转换规则和过滤条件。以下为统一配置模板:
# adapter_config.yaml
adapters:
- name: "prometheus_adapter"
type: "prometheus"
enabled: true
config:
listen_addr: ":8080"
webhook_path: "/webhook/prometheus"
# 严重级别映射
severity_mapping:
critical: "critical"
warning: "warning"
info: "info"
# 标签白名单,只保留需要的标签
label_whitelist:
- "alertname"
- "instance"
- "job"
- name: "zabbix_adapter"
type: "zabbix"
enabled: true
config:
listen_addr: ":8081"
webhook_path: "/webhook/zabbix"
# Zabbix 严重级别数字到 UAI 的映射
severity_mapping:
"5": "critical"
"4": "critical"
"3": "warning"
"2": "warning"
"1": "info"
"0": "info"
- name: "aliyun_adapter"
type: "aliyun_cms"
enabled: true
config:
listen_addr: ":8082"
webhook_path: "/webhook/aliyun"
auth:
access_key_id: "${ALIYUN_AK_ID}"
access_key_secret: "${ALIYUN_AK_SECRET}"
# 云监控地域过滤
region_filter:
- "cn-hangzhou"
- "cn-shanghai"
4.7 告警源接入质量指标
为保障告警接入的可靠性,需要建立以下可观测指标:
| 指标名称 | 类型 | 说明 | 告警阈值 |
|---|---|---|---|
adapter_alert_received_total |
Counter | 适配器接收原始告警总数 | - |
adapter_alert_converted_total |
Counter | 成功转换为 UAI 的告警数 | - |
adapter_convert_errors_total |
Counter | 转换失败次数 | > 5/min |
adapter_convert_latency_seconds |
Histogram | 单次转换耗时分布 | p99 > 1s |
adapter_health_status |
Gauge | 适配器健康状态(1=up, 0=down) | 0 持续 30s |
通过 Prometheus 采集这些指标,结合 Grafana 仪表盘实时监控每个适配器的运行状态,确保告警源接入链路稳定可靠。