Loki 查询
从实际使用场景出发,介绍夜莺 Loki 日志告警:用 LogQL 指标查询统计日志并判阈值,以及按标签分组告警的写法。
概述
Loki 日志告警用 LogQL 查询日志并做统计。和其它日志类数据源"填表单选统计函数"的方式不同,Loki 的统计直接写在 LogQL 里——用 count_over_time、rate、sum by 这类指标查询把日志压成时序,再判阈值。
因此 Loki 的配置方式更接近 Prometheus:写一段查询、返回时序、逐条判定。
| 字段 | 必填 | 说明 |
|---|---|---|
| 数据源类型 / 数据源 | 是 | 选 Loki 类型并选中已接入的 Loki 数据源 |
| LogQL | 是 | LogQL 查询语句,需要是指标查询(返回数值而非日志原文) |
| 告警分级 | 是 | 每条查询可单独设置一级 Critical / 二级 Warning / 三级 Info |
| 告警条件 | 是 | 阈值可写进 LogQL,或添加多条查询后用告警表达式混合判定 |
| 执行频率 | 是 | 多久跑一次查询 |
| 持续时长 | 是 | 满足条件持续多久才触发 |
| 查询延迟(PLUS) | 否 | 日志有写入延迟时把查询窗口前移,企业版提供 |
下面按实际使用场景介绍。
场景一:错误日志数量告警
统计一段时间内的错误日志条数。「payment 服务 5 分钟内错误日志超过 10 条」:
count_over_time({service="payment"} |= "ERROR" [5m]) > 10
{service="payment"}是流选择器,先圈定日志流;|= "ERROR"过滤含 ERROR 的行;count_over_time(...[5m])统计 5 分钟内的行数;> 10即阈值,也可以去掉阈值只保留统计、把判定放到告警条件里。
场景二:按标签分组告警
想让每个服务、每个实例单独告警,用 sum by (标签) 聚合:
sum by (service) (count_over_time({env="prod"} |= "ERROR" [5m])) > 100
每个 service 独立判定,各自触发告警事件,事件标签里带对应的 service。
分组维度决定了告警事件的数量和粒度——聚合到你真正关心的维度,避免产生大量重复事件。
场景三:错误率告警(多查询混合)
要算比率,添加多条查询后用告警表达式混合运算。比如错误日志占比:
$A:sum(count_over_time({app="api"} |= "ERROR" [5m]))
$B:sum(count_over_time({app="api"} [5m]))
告警条件:
$A / $B > 0.05
注意混合运算要求两侧标签能对齐,必要时用 sum by (...) 统一维度。
常见问题
Q1:LogQL 写了却查不出数据 / 报错?
A:最常见的原因是写成了日志查询而不是指标查询。告警需要数值,必须用 count_over_time、rate、bytes_over_time 等函数把日志聚合成时序。先在日志查询页面把语句跑通,再拿来配告警。
Q2:阈值写在 LogQL 里还是告警条件里?
A:都可以。单条查询直接写进 LogQL 最简单(如 ... > 10);需要多条查询做比率、联合判定时,把阈值放到告警条件的表达式里。
Q3:一条规则会产生多少告警事件?
A:查询返回几条时序就逐条判定,每条满足阈值的时序各触发一条事件。用 sum by (维度) 控制分组粒度。
Q4:日志有写入延迟,查不到最近的数据怎么办?
A:企业版(PLUS)在高级配置里提供「查询延迟」,把查询窗口整体前移若干秒,避开尚未落盘的时间窗口。开源版可以把 LogQL 的统计区间适当放宽(如从 [1m] 调到 [5m])来降低影响。