LogQL 入门:语法基础、标签过滤与行过滤

LogQL 是 Loki 的查询语言,受 PromQL 和 SQL 启发,专为日志数据设计。理解 LogQL 的核心在于区分两个阶段:日志流选择器(选择日志来源)和行过滤器(在已选流中筛选内容)。本章从最基础的语法结构开始,逐步掌握标签过滤与行过滤的精确写法。

1. LogQL 查询结构

一个完整的 LogQL 查询由两部分组成:

{标签表达式} 行过滤器
组成部分 作用 示例
日志流选择器 通过标签匹配选择日志流(类似 PromQL 的指标选择器) {job="nginx", env="prod"}
行过滤器 在选中的日志流内按内容过滤行 |= "error"
关键理解:标签过滤发生在索引层,速度快;行过滤发生在数据扫描层,消耗更多资源。先通过标签缩小范围,再用行过滤精确匹配,是性能最佳实践。

2. 标签过滤:日志流选择器

标签过滤使用花括号 {} 包裹,语法与 PromQL 完全一致。支持以下操作符:

操作符 含义 示例 说明
= 精确匹配 {job="nginx"} 标签值必须完全等于 nginx
!= 不等于 {job!="nginx"} 排除 nginx 的所有其他 job
=~ 正则匹配 {job=~"nginx|apache"} 匹配 nginx 或 apache
!~ 正则排除 {job!~".*test.*"} 排除 job 中包含 test 的流
实战案例:查询所有生产环境 Nginx 服务的日志流:
{job="nginx", env="prod"}
查询所有非测试环境的 Web 服务(支持正则):
{job=~"nginx|apache", env!~".*staging.*"}

3. 行过滤:在日志内容中搜索

行过滤器紧跟在日志流选择器之后,对选中的日志行进行内容级过滤。支持四种操作符:

操作符 类型 示例 匹配行为
|= 包含 {job="nginx"} |= "500" 返回包含 500 的行
!= 排除 {job="nginx"} != "health" 排除包含 health 的行
|~ 正则包含 {job="nginx"} |~ "5[0-9][0-9]" 匹配 5xx 状态码
!~ 正则排除 {job="nginx"} !~ "GET|POST" 排除 GET 和 POST 请求
性能注意:行过滤器是全量扫描,|= 和 != 使用子字符串匹配,速度较快;|~ 和 !~ 使用正则引擎,CPU 开销更高。优先使用 |= 和 !=,仅在需要复杂模式时使用正则。

4. 组合查询:标签 + 行过滤

实际场景中,标签过滤和行过滤通常组合使用,形成精确的查询链:

{job="nginx", env="prod"} |= "error" != "timeout"

这条查询的含义:

  1. 选择 job="nginx" 且 env="prod" 的日志流
  2. 保留包含 error 的行
  3. 从结果中排除包含 timeout 的行
变更窗口场景:在变更窗口期间,查询特定服务的新增错误:
{service="user-api", deploy_id="v2.3.1"} |= "exception" != "known_bug_123"
通过标签锁定变更范围,通过行过滤聚焦新异常,排除已知问题。

5. LogQL 查询流程可视化

下图展示了 LogQL 从标签选择到行过滤的完整执行流程:

LogQL 查询执行流程 原始日志流 步骤 1:标签过滤(索引层) {job="nginx", env="prod"} 步骤 2:行过滤(扫描层) |= "error" != "timeout" 精确匹配的日志行 性能关键点 • 标签过滤:索引扫描,快 • 行过滤:全量扫描,慢 • 先缩小标签范围再过滤

6. 常见错误与调试技巧

错误场景 错误写法 正确写法 原因
标签值未加引号 {job=nginx} {job="nginx"} 标签值必须用双引号包裹
正则未转义 {job=~"nginx|apache"} {job=~"nginx|apache"} 正则中 | 无需额外转义
行过滤顺序颠倒 |= "error" {job="nginx"} {job="nginx"} |= "error" 标签选择器必须在行过滤器之前
多个行过滤未链式连接 {job="nginx"} |= "error" |~ "5.." {job="nginx"} |= "error" |~ "5.." 多个行过滤器用 | 链式连接

7. 标签过滤与行过滤对比总结

下表从多个维度对比两种过滤方式,帮助你在实际查询中做出正确选择:

对比维度 标签过滤 行过滤
作用对象 日志流的元数据(标签) 日志行的文本内容
语法位置 花括号 {} 内 花括号之后,使用 |=、!=、|~、!~
性能 高(索引查询) 低(全量扫描)
灵活性 仅支持标签键值对 支持子字符串和正则表达式
推荐使用场景 按服务、环境、集群等维度筛选 按错误码、关键字、模式匹配
最佳实践:在变更窗口服务目录中,先通过标签过滤锁定变更范围(如 {deploy_id="v2.3.1"}),再使用行过滤聚焦异常模式(如 |= "5xx"),既能保证查询精度,又能控制资源消耗。