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 全文(用于审计) {...}
设计要点:UAI 规范不要求保留所有原始字段,但必须保留 alert_id、source、severity、status、timestamp 五个核心字段,确保自愈引擎能够基于这些字段完成去重、过滤、路由和恢复判定。

4.2 适配器模式架构设计

适配器模式在此场景中充当“翻译层”:每个告警源对应一个适配器实例,负责监听/接收原始告警,将其转换为 UAI 标准格式,然后推送到统一的消息队列或 API 网关。自愈引擎只消费 UAI 格式的告警,无需关心底层告警源的具体实现。

告警源适配器模式架构图 告警源适配器模式架构 Prometheus Webhook / Alertmanager Zabbix Action / Media Type 云监控(阿里云/AWS) Webhook / SNS / SQS Prometheus Adapter 转换 → UAI 格式 Zabbix Adapter 转换 → UAI 格式 Cloud Monitor Adapter 转换 → UAI 格式 统一告警消息队列(Kafka / RabbitMQ) UAI 标准格式 Runbook 自愈引擎(消费 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)推送告警。适配器需处理不同云厂商的认证签名和重试机制。

云监控适配器通用处理流程:
  1. 鉴权验证:校验请求签名(阿里云 HMAC-SHA1、AWS SigV4),防止伪造告警。
  2. 格式转换:将云厂商的告警 JSON 结构映射到 UAI 字段,注意字段名差异(如阿里云 alertName → UAI alert_name)。
  3. 去重标识:使用云厂商提供的 alertId 或 eventId 作为 UAI alert_id 的一部分,确保全局唯一。
  4. 重试与幂等:云监控可能重复推送,适配器需在转换层做幂等处理(基于 alert_id 去重)。

4.4 适配器注册与动态加载

为支持告警源的动态扩展,适配器采用插件化注册机制。系统启动时扫描适配器目录,根据配置文件加载对应的适配器实例。

适配器动态注册与加载流程 适配器动态注册与加载流程 1. 读取配置文件 adapter_config.yaml 2. 适配器注册中心 维护适配器映射表 3. 动态加载适配器 反射 / SPI 机制 4. 启动监听服务 HTTP / MQ Consumer 4. 启动监听服务 HTTP / MQ Consumer 4. 启动监听服务 HTTP / MQ Consumer 5. 适配器就绪,等待告警流入
避坑指南:适配器注册中心必须支持热加载与健康检查。当某个适配器连续转换失败超过阈值(如 5 次/分钟),应自动摘除该适配器并告警,避免因单个告警源异常阻塞整个自愈链路。

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 仪表盘实时监控每个适配器的运行状态,确保告警源接入链路稳定可靠。