Skip to content
On this page

用 SQL 写告警规则:GreptimeDB Trigger 快速入门

了解如何使用 GreptimeDB Trigger 通过 SQL 定义告警规则、自动管理告警状态,并与 Prometheus Alertmanager 集成。

概述

Trigger 为 GreptimeDB 提供了内置的告警检测、多阶段状态管理以及 Webhook 通知能力,将完整的监控告警逻辑内置于数据库。用户可通过 SQL 定义触发规则,GreptimeDB 会周期性执行这些规则,并在条件满足时自动发出通知。

关键特性

  • SQL 原生:通过 SQL 定义触发规则,无缝复用 GreptimeDB 已有的功能(如内置函数),降低学习成本
  • 多阶段状态管理:内置 pending / firing / inactive 状态机,有效抑制状态抖动与重复通知
  • 丰富的上下文信息:支持自定义 labels 和 annotations,并自动将查询结果字段注入其中,便于精准定位问题根因
  • 生态友好的通知集成:告警负载与 Prometheus Alertmanager 完全兼容,可直接复用其分组、抑制、静默和路由功能,无需胶水代码

Quick Start

本快速入门将带你完成一个端到端的监控告警场景:使用 Trigger 监控系统负载(load1),并在负载持续超过阈值时自动触发告警。

具体步骤包括:

  • 创建指标表:建立 load1 表存储主机负载指标
  • 定义 Trigger:通过 SQL 设定触发条件,配置 labels、annotations 及通知方式
  • 模拟数据写入:依次注入正常与异常的负载数据,激活告警逻辑
  • 观察状态变化:实时查看告警实例从 PENDING → FIRING → INACTIVE 的完整生命周期

Demo

1. 准备数据表

使用 MySQL 客户端连接 GreptimeDB,创建 load1 表:

sql
CREATE TABLE `load1` (
    host            STRING,
    load1           FLOAT32,
    ts              TIMESTAMP TIME INDEX
) WITH ('append_mode'='true');

2. 创建 Trigger

执行以下 SQL 创建 Trigger:

sql
CREATE TRIGGER IF NOT EXISTS `load1_monitor`
    ON (
        SELECT
            host          AS label_host,
            avg(load1)    AS avg_load1,
            max(ts)       AS ts
        FROM public.load1
        WHERE ts >= NOW() - '1 minutes'::INTERVAL
        GROUP BY host
        HAVING avg(load1) > 10
    ) EVERY '1 minutes'::INTERVAL
    FOR '3 minutes'::INTERVAL
    KEEP FIRING FOR '3 minutes'::INTERVAL
    LABELS (severity=warning)
    ANNOTATIONS (comment='Your computer is smoking, should take a break.')
    NOTIFY(
        WEBHOOK alert_manager URL 'http://localhost:9093' WITH (timeout='1m')
    );

这个 Trigger 每分钟执行一次查询,统计各主机最近 60 秒的平均负载,筛选出 avg(load1) > 10 的主机生成告警。

关键参数:

  • FOR:条件持续满足 3 分钟后,告警才进入 firing 状态
  • KEEP FIRING FOR:进入 firing 后,即使条件不再满足,仍保持 3 分钟

更多语法细节参阅官方文档

3. 查看 Trigger 状态

列出所有 Trigger:

sql
SHOW TRIGGERS;

查看创建语句:

sql
SHOW CREATE TRIGGER `load1_monitor`\G

查询详细信息:

sql
SELECT * FROM information_schema.triggers\G

输出示例:

   trigger_name: load1_monitor
     trigger_id: 1024
        raw_sql: (SELECT host AS label_host, avg(load1) AS avg_load1, ...)
       interval: 60
         labels: {"severity":"warning"}
    annotations: {"comment":"Your computer is smoking, should take a break."}
            for: 180
keep_firing_for: 180
       channels: [{"channel_type":{"Webhook":{...}},"name":"alert_manager"}]

查看告警实例:

sql
SELECT * FROM information_schema.alerts;

此时尚无数据写入,结果为空。

4. 写入数据观察告警状态

运行以下脚本模拟数据写入:前 1 分钟写入正常值,接下来 6 分钟写入超阈值数据触发告警,之后恢复正常。

bash
#!/usr/bin/env bash

MYSQL="mysql -h 127.0.0.1 -P 4002"

insert_normal() {
  $MYSQL -e "INSERT INTO load1 (host, load1, ts) VALUES
    ('shanghai1', 1.2, now()),
    ('shanghai2', 1.1, now()),
    ('shanghai3', 1.3, now());"
}

insert_high() {
  $MYSQL -e "INSERT INTO load1 (host, load1, ts) VALUES
    ('shanghai1', 1.2, now()),
    ('shanghai2', 12.1, now()),
    ('shanghai3', 11.5, now());"
}

# 第 1 分钟:正常数据
for i in {1..4}; do insert_normal; sleep 15; done

# 接下来 6 分钟:超阈值数据
for i in {1..24}; do insert_high; sleep 15; done

# 之后:恢复正常
while true; do insert_normal; sleep 15; done

在另一个终端持续查询告警状态:

sql
SELECT * FROM information_schema.alerts\G

状态变化过程

阶段 1:无告警

Empty set

阶段 2:PENDING(条件首次满足,未达 FOR 时长)

*************************** 1. row ***************************
  trigger_id: 1024
trigger_name: load1_monitor
      labels: {"alert_name":"load1_monitor","host":"shanghai2","severity":"warning"}
 annotations: {"avg_load1":"12.100000381469727","comment":"Your computer is smoking, should take a break.","ts":"1765718356823"}
      status: FIRING
   active_at: 2025-12-14 13:15:29.064475
    fired_at: 2025-12-14 13:19:29.064195
 resolved_at: NULL
last_sent_at: 2025-12-14 13:19:29.064195
*************************** 2. row ***************************
  trigger_id: 1024
trigger_name: load1_monitor
      labels: {"alert_name":"load1_monitor","host":"shanghai3","severity":"warning"}
 annotations: {"avg_load1":"11.5","comment":"Your computer is smoking, should take a break.","ts":"1765718356823"}
      status: FIRING
   active_at: 2025-12-14 13:15:29.064475
    fired_at: 2025-12-14 13:19:29.064195
 resolved_at: NULL
last_sent_at: 2025-12-14 13:19:29.064195
2 rows in set (0.008 sec)

阶段 3:FIRING(满足 FOR 条件,开始发送通知)

      status: FIRING
    fired_at: 2025-12-14 13:19:29
last_sent_at: 2025-12-14 13:19:29

阶段 4:INACTIVE(条件不满足 + KEEP FIRING FOR 期满,发送恢复通知)

      status: INACTIVE
 resolved_at: 2025-12-14 13:22:29

5. 集成 Alertmanager(可选)

如果已部署 Prometheus Alertmanager,GreptimeDB 会自动将 firing 和 inactive 状态的告警推送过去。

Trigger 每次评估后,会将查询结果字段注入到 labels 和 annotations 中。例如上例中的 avg_load1 会出现在 annotations 里,可在 Alertmanager 的通知模板中引用,生成包含主机名、负载值等上下文的告警消息。

得益于与 Alertmanager 的 payload 兼容性,可直接使用其分组、抑制、静默、路由等功能,无需额外适配。

小结

本文演示了 Trigger 的基本工作流程:用 SQL 定义触发条件,自动管理告警状态,与 Prometheus 生态无缝集成。无论是轻量原型还是生产级告警,Trigger 都能简化实现路径。

加入我们的社区

获取 Greptime 最新更新,并与其他用户讨论。