light-sentry-sdk/docs/04-alert-engine.md

10 KiB
Raw Permalink Blame History

告警引擎设计文档

一、设计原则

1.1 核心原则

  • :错误发生后 1 分钟内触发告警
  • :减少误报,告警要有价值
  • :支持多种告警规则和通知渠道
  • :不依赖复杂组件,轻量实现

1.2 告警目标

  • 错误突增:及时发现线上故障
  • 新错误出现:第一时间感知新问题
  • 错误率超标:质量红线监控
  • 性能劣化:用户体验下降预警

二、告警规则类型

2.1 规则分类

类型 说明 实时性 复杂度
阈值告警 指标超过固定阈值
突增告警 同比/环比增长超过阈值
新错误告警 出现新的错误指纹
错误率告警 错误率超过阈值
质量分告警 性能/质量综合评分下降

2.2 内置规则模板

1. 错误数量突增

name: 错误数量突增
type: spike
metric: error_count
window: 5m           # 检测窗口
compare: 1h_ago      # 对比1小时前
threshold: 200%      # 增长 200% 触发
min_count: 10        # 最少 10 条才检测(避免噪音)
level: warning

2. 新错误出现

name: 新错误出现
type: new_error
metric: error_fingerprint
window: 24h          # 过去 24 小时没出现过
level: info

3. JS 错误率过高

name: JS 错误率过高
type: threshold
metric: error_rate   # 错误数 / PV
window: 5m
threshold: 5%        # 错误率超过 5%
level: critical

4. 页面性能劣化

name: LCP 性能劣化
type: threshold
metric: lcp_p95
window: 15m
threshold: 4000      # P95 LCP > 4s
level: warning

5. 接口错误率过高

name: 接口错误率过高
type: threshold
metric: api_error_rate
window: 5m
threshold: 10%
level: critical

三、告警引擎架构

3.1 整体架构

┌──────────────────────────────────────────────────────┐
│                     事件流                            │
│  错误事件 ──→ 实时检测 ──→ 触发规则 ──→ 告警通知      │
│                (快路径)                               │
└──────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────┐
│                     定时任务                          │
│  Loki/MySQL ──→ 指标计算 ──→ 规则匹配 ──→ 告警通知   │
│                (慢路径)                               │
└──────────────────────────────────────────────────────┘

3.2 双路径设计

快路径:实时检测(秒级)

用于:新错误出现、错误数突增(粗粒度)

事件入队
    ↓
实时规则引擎
    ├─ 检查是否是新指纹(内存 BloomFilter
    ├─ 检查 1 分钟错误数是否突增
    └─ 触发 → 入告警队列
    ↓
告警收敛 + 去重
    ↓
通知

慢路径:定时检测(分钟级)

用于:复杂计算、分位数、错误率

定时任务(每 5 分钟)
    ↓
从 Loki/MySQL 拉取指标
    ↓
计算同比、环比、分位数
    ↓
匹配告警规则
    ↓
触发 → 入告警队列
    ↓
告警收敛 + 去重
    ↓
通知

四、告警规则引擎

4.1 规则数据结构

CREATE TABLE alert_rules (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  project_id VARCHAR(64) NOT NULL,
  name VARCHAR(128) NOT NULL,
  description TEXT,
  
  -- 规则类型
  type VARCHAR(32) NOT NULL,  -- threshold / spike / new_error / error_rate
  
  -- 规则配置JSON
  config JSON NOT NULL,
  /*
  {
    "metric": "error_count",
    "window": "5m",
    "threshold": 100,
    "compare": "1h_ago",
    "operator": ">"
  }
  */
  
  -- 告警级别
  level VARCHAR(32) NOT NULL,  -- info / warning / critical
  
  -- 通知渠道
  channels JSON NOT NULL,
  /*
  [
    { "type": "webhook", "url": "https://..." },
    { "type": "email", "to": ["a@b.com"] }
  ]
  */
  
  -- 收敛配置
  group_by VARCHAR(64),        -- 按指纹/项目/页面分组
  interval INT DEFAULT 300,    -- 同组告警间隔(秒)
  max_count INT DEFAULT 10,    -- 每小时最多告警次数
  
  -- 状态
  enabled TINYINT DEFAULT 1,
  created_at DATETIME,
  updated_at DATETIME,
  
  INDEX idx_project (project_id)
);

4.2 规则匹配流程

新指标数据到达
    ↓
加载项目的所有启用规则
    ↓
逐条匹配
    ├─ 类型匹配?
    ├─ 条件满足?
    └─ 未被静默?
    ↓
触发告警
    ↓
告警去重 + 收敛
    ↓
发送通知

4.3 内置规则表达式

支持简单的表达式语法:

# 阈值比较
error_count > 100
error_rate > 0.05
lcp_p95 >= 4000

# 同比环比
error_count / error_count_1h_ago > 2
error_count > error_count_1d_ago * 1.5

五、告警收敛与降噪

5.1 降噪策略

策略 说明 效果
同指纹去重 同一错误 5 分钟内只告警 1 次 减少 80% 重复告警
分组收敛 按项目/级别聚合,合并发送 减少通知数量
频率限制 每项目每小时最多 N 条 防止告警风暴
静默期 已知问题可设置静默 忽略已知问题
最小阈值 数量太少不告警 避免噪音

5.2 告警去重键

去重键 = project_id + rule_id + fingerprint + 时间窗口

同一去重键在 interval 时间内只发 1 次告警。

5.3 告警升级

  • 持续时间超过 30 分钟 → 级别升级warning → critical
  • 影响用户数超过阈值 → 级别升级
  • 持续超过 2 小时 → 通知更多人

六、通知渠道

6.1 支持的渠道

渠道 说明 适用场景
Webhook 通用 HTTP 回调 飞书、钉钉、企业微信、Slack
邮件 SMTP 发送 正式通知、归档
Server酱 微信推送 个人项目
飞书机器人 专用适配 飞书团队
钉钉机器人 专用适配 钉钉团队

6.2 Webhook 格式

{
  "alert_id": "alert_abc123",
  "rule_id": 123,
  "rule_name": "错误数量突增",
  "level": "critical",
  "project_id": "1001",
  "project_name": "前端项目",
  
  "metric": "error_count",
  "value": 250,
  "threshold": 100,
  "window": "5m",
  
  "description": "5 分钟内错误数达到 250超过阈值 100增长 150%",
  
  "details": {
    "error_type": "TypeError",
    "top_errors": [
      { "fingerprint": "a1b2c3", "message": "...", "count": 100 },
      { "fingerprint": "d4e5f6", "message": "...", "count": 50 }
    ]
  },
  
  "link": "https://log.example.com/manage/#/errors?project=1001",
  "timestamp": "2024-01-01T00:00:00Z"
}

6.3 飞书 / 钉钉适配

提供现成的模板,直接粘贴 Webhook URL 即可使用:

  • 飞书:使用富文本卡片,支持点击跳转
  • 钉钉:使用 Markdown 格式,支持 @人

七、告警事件存储

7.1 告警历史表

CREATE TABLE alert_events (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  project_id VARCHAR(64) NOT NULL,
  rule_id BIGINT NOT NULL,
  rule_name VARCHAR(128),
  level VARCHAR(32),
  
  -- 告警数据
  metric VARCHAR(64),
  value DOUBLE,
  threshold DOUBLE,
  description TEXT,
  details JSON,
  
  -- 状态
  status VARCHAR(32) DEFAULT 'firing',  -- firing / resolved / acknowledged
  
  -- 时间
  started_at DATETIME,
  resolved_at DATETIME NULL,
  duration INT,  -- 持续时间(秒)
  
  created_at DATETIME,
  updated_at DATETIME,
  
  INDEX idx_project_time (project_id, started_at),
  INDEX idx_status (status)
);

7.2 状态流转

firing ──→ acknowledged ──→ resolved
  │                           ↑
  └───────────────────────────┘
        自动恢复(指标降下来)

八、实现方案

8.1 轻量实现v1

技术栈Node.js + 内存定时器 + MySQL

API Server 进程内
    ├─ 事件消费时同步检测(快路径)
    │   ├─ 新错误检测BloomFilter
    │   └─ 简单计数1min 滑动窗口)
    │
    └─ 定时任务(慢路径)
        └─ 每 5 分钟跑一次复杂规则

优点:无额外组件,部署简单 缺点:单进程,无法水平扩展

8.2 独立服务v2

技术栈:独立的 Alert Worker 进程 + Redis

API Server → Redis Stream → Alert Worker
                          → 规则匹配
                          → 告警收敛
                          → 通知发送

优点:可独立扩展,不影响接入性能 缺点:多一个组件


九、静默与抑制

9.1 静默规则

用户可以设置静默期,暂时忽略某些告警:

- project_id: 1001
  fingerprint: a1b2c3d4
  reason: "已知问题,下个版本修复"
  start_time: 2024-01-01 00:00:00
  end_time: 2024-01-03 00:00:00
  created_by: user1

9.2 抑制规则

高优先级告警抑制低优先级:

  • critical 级别的错误告警触发后,同指纹的 warning 级告警被抑制
  • 项目级别的大故障告警触发后,该项目的其他告警被抑制

十、与现有系统集成

10.1 当前状态

  • 有 Loki 存原始数据 → 可用于慢路径查询
  • 有 MySQL待加聚合层→ 可存规则和告警历史
  • 有管理后台 → 可加告警管理页面

10.2 落地步骤

v1最小可用

  1. 新增 alert_rules 和 alert_events 表
  2. 实现新错误检测(快路径,内存 BloomFilter
  3. 实现 Webhook 通知
  4. 管理后台加告警规则配置页面

v2增强

  1. 实现定时规则引擎(慢路径)
  2. 增加突增检测、错误率检测
  3. 支持飞书/钉钉专用模板
  4. 告警收敛和静默功能

v3完善

  1. 独立 Alert Worker 服务
  2. Redis 队列 + 分布式锁
  3. 更复杂的规则表达式
  4. 告警抑制和升级