Doris 查询
从实际使用场景出发,介绍夜莺 Doris 数据源告警:用 SQL 统计日志做告警判定,时间宏 $__timeFilter 的用法,以及值字段与标签字段的配置。
概述
Doris 常用来存海量日志和明细数据。接成告警数据源后,用 SQL 在上面做统计并判定告警。
和其它 SQL 类数据源相比,Doris 多了两个要点:需要先选数据库,以及查询里建议使用时间宏来限定查询区间。
| 字段 | 必填 | 说明 |
|---|---|---|
| 数据源类型 / 数据源 | 是 | 选 Doris 类型并选中已接入的实例 |
| 数据库 | 是 | 选择要查询的数据库 |
| 查询条件 | 是 | SQL 语句,如 SELECT count(*) as count FROM db_name.table_name WHERE ts >= now() - 5m |
| 时间间隔 | 是 | 查询回看的时间区间,单位可选秒 / 分钟 / 小时 |
| 值字段(辅助配置) | 是 | SQL 结果的哪一列作为数值,用 $A.<列名> 在告警条件里引用 |
| 标签字段(辅助配置) | 否 | SQL 结果的哪些列作为告警事件的标签,通常是 GROUP BY 的分组列 |
| 告警条件 | 是 | 基于值字段写告警表达式,如 $A.cnt > 1000 |
| 执行频率 | 是 | 多久跑一次 SQL |
下面按实际使用场景介绍。
场景一:统计日志条数判阈值
「最近 5 分钟错误日志超过 1000 条」,直接在 SQL 里限定时间范围:
SELECT count(*) AS cnt
FROM db_name.app_log
WHERE level = 'ERROR'
AND ts >= DATE_SUB(NOW(), INTERVAL 5 MINUTE);
- 值字段选
cnt; - 告警条件写
$A.cnt > 1000。
写完点「数据预览」,确认返回的列名和值符合预期,再配阈值。
场景二:用时间宏让「时间间隔」生效
除了在 SQL 里写死时间条件,更推荐用时间宏 $__timeFilter(时间列),让查询区间跟着表单上的「时间间隔」走:
SELECT count(*) AS cnt
FROM db_name.app_log
WHERE level = 'ERROR'
AND $__timeFilter(`ts`);
这样调整「时间间隔」就能改变查询窗口,不用改 SQL。
注意:查询条件里没有时间宏时,表单上选择的时间区间不会生效,SQL 会按你写死的条件执行——如果 SQL 里也没有时间限制,就可能触发全表扫描。Doris 上的数据量通常很大,务必确保查询有时间范围限定。
场景三:GROUP BY 分组告警
想让每个服务、每个接口单独告警,用 GROUP BY 分组,并把分组列设为标签字段:
SELECT service AS service, count(*) AS cnt
FROM db_name.app_log
WHERE level = 'ERROR'
AND $__timeFilter(`ts`)
GROUP BY service;
- 值字段选
cnt,标签字段选service; - 告警条件
$A.cnt > 100。
SQL 返回几行就有几条"伪时序",告警引擎逐行独立判定,每个 service 各自触发独立的告警事件。
常见问题
Q1:为什么表单上调了「时间间隔」,查询结果却没变?
A:查询条件里没有用时间宏。加上 $__timeFilter(时间列) 后,时间间隔才会作用到 SQL 上。
Q2:SQL 返回多行会怎样?
A:每行作为一条独立"伪时序",逐行判定告警。用 GROUP BY + 标签字段控制分组粒度。
Q3:值字段和标签字段怎么选?
A:要做数值比较的列(计数、耗时)选值字段;要作为告警分组维度或事件标签的列(服务名、状态码)选标签字段。
Q4:怎么避免告警查询拖垮 Doris?
A:查询务必带时间范围(用时间宏或 SQL 里写死);避免 SELECT *,只查聚合结果;执行频率与查询代价匹配,别用秒级频率跑重查询。
参考资料
- 告警表达式语法
- MySQL 告警举例(SQL 类表达式写法通用)
- ClickHouse 查询
- 告警规则基础配置