跳到主要内容

日志规则

对 ElasticSearch、OpenSearch、Loki、VictoriaLogs 的日志条数或匹配做告警——四种都能告警,但只有三种能在日志检索里预览。

这页办完你会得到:一条按周期数日志行数、多了就报警的规则, 四种日志存储里你用的是哪种都行。

日志告警最后都归结为同一件事——把一个时间窗的日志变成一个数,然后拿它比较。 四种数据源的差别在于「比较写在哪儿」。

四种数据源,两种规则形态​

数据源阈值写在哪表达式写法
Elasticsearch单独的判定条件区块$A > 100
OpenSearch同 Elasticsearch$A > 100
VictoriaLogs同一个区块$A.<stats 别名> > 100
Loki写在 LogQL 里,和 Prometheus 规则一样没有——它就是查询的一部分

Loki 是那个例外,单独放在下面讲。其余三种共用 判定周期与恢复里描述的那套判定条件模型。

Elasticsearch 与 OpenSearch​

两者用同一套表单,OpenSearch 只是把「索引模式」那个选项藏了。

把日志变成一个数​

查询统计下面是一张查询卡片:

字段怎么填
索引要查的索引。logs-2026.01.01、逗号分隔的多个,或者 logs-* 这样的通配符
过滤条件一条 Lucene 查询——level:ERROR AND service:checkout。规则表单里不提供 KQL
日期字段时间戳字段,默认 @timestamp
时间间隔时间窗,单位秒,默认 60。它既是聚合桶大小,也是这次查询往回看多久
数值提取这个窗怎么变成一个数:count,或者对某个数值字段做 avg / sum / max / min / p90 / p95 / p99
Group By可选。按某个 term 字段拆开,每个取值各出一条事件,用 匹配个数 和 文档最小值 控制规模
辅助配置 → Offset把窗口整体往前挪 N 秒,适合写入有延迟的数据源

count 是最常见的:「命中了多少行」。那几个分位数是给「对日志里的某个数值告警」用的, 比如每行里记的请求耗时。

Group By 是把「一条告警」变成「每个服务一条告警」的关键。 不用它, 一条统计所有服务错误数的规则只会响一次,而且不告诉你是哪个服务。 配上 Group By: service,匹配个数 10,每个超阈值的服务各出一条事件, 带着 service=<名字> 这个标签,路由就能拿它用了。

判定条件​

查询下面是判定条件 → 阈值判断。每条判定条件带自己的级别; 和指标规则一样,多条判定条件加上级别抑制,就能做出分档阈值而不重复发消息。

判定条件有两种写法:

  • 简单模式——选查询、选比较符、填一个数;
  • 表达式模式——自己写表达式,用到多条查询时就得用它:
$A > 100 && $B < 10

Elasticsearch 里引用一条查询用裸的 $A。多加几张查询卡片就有了 $B、$C,可以组合。

有两件事会静默失效,所以要用模拟触发验一下:

  • 引用了一个已经不存在的查询别名;
  • 拿标签和数字比。标签是字符串——$A.service == 'checkout' 没问题, $A.service > 10 是类型错误,而引擎对算不出来的表达式一律当「不满足」处理,一声不吭。

VictoriaLogs​

查询是一条 LogsQL,而且必须以 stats 管道结尾——规则是以即时 stats 查询的方式跑它的, 纯搜索返回的东西用不了:

_msg:error | stats count() as value

你给这个统计起的别名,就是判定条件里引用它的方式:

$A.value > 20

查询里没有 _time 过滤时表单会给一条警告,这条警告值得听:不加的话, 每个评估周期都会把库里所有数据扫一遍。

_time:5m AND _msg:error | stats count() as value

Loki​

Loki 规则的形态像 Prometheus 规则,不像其他日志规则。每条查询是一个 LogQL 输入框, 阈值写在里面,每条查询各带自己的级别:

count_over_time({job="myapp"} |= "error" [5m]) > 10

由此带来的后果,全都和指标规则一样:

  • 查询必须返回瞬时向量,所以要有 count_over_time、rate 或别的区间聚合—— 光写一个日志选择器不行;
  • 返回一条序列产生一条事件,所以粒度由 sum by (job) (...) 决定;
  • 没有单独的判定条件区块,因此 Loki 规则上没有恢复条件、也没有数据缺失开关;
  • 恢复的含义就是查询不再返回那条序列。

加第二条查询会出现级别抑制开关,和指标规则一样。

恢复的默认值在这里不一样​

Elasticsearch、OpenSearch 和 VictoriaLogs 规则的每条判定条件上都有一个恢复条件下拉, 而这个选择对日志比对别处更要紧:

  • 查不到数据就恢复——查不到错误日志,通常就真的说明问题过去了。日志类数据源表单默认选的就是它。
  • 必须查到数据且不满足告警条件才恢复——查询什么都没返回时告警会保持。 当「一条日志都没有」意味着采集链路断了、而不是服务变健康时,这个才对。

如果「日志管道静默」本身就是你想知道的事,那就用告警条件那一步单独的数据缺失开关, 而不是靠恢复方式。它有自己的级别,于是「错误变多了」和「日志不来了」就成了两种能区分的事件。

保存之前先验证​

每张查询卡片上都有数据预览,会真的跑一次查询,把结果值列成表。保存前用一下—— 这是唯一能看出你的过滤条件到底有没有命中东西的地方。

Elasticsearch、Loki 和 VictoriaLogs 还可以先在数据查询 → 日志里交互式地试, 调过滤条件更方便。OpenSearch 在日志检索里没有, 所以 OpenSearch 的查询只能在规则表单的数据预览里验。

然后用模拟触发拿真实数据核一下判定表达式,保存之后再看 判定执行记录,看每个周期到底返回了什么。

下一步​