Loki 日志检索

简介

Nightingale 集成了 Loki 的日志检索能力。在日志检索页面选择 Loki 类型的数据源和时间范围后,可以在查询输入框中输入 LogQL,查看日志原文或切换到统计图表模式做聚合分析。

LogQL 查询由两部分组成:

{日志流标签选择器} | 日志处理管道

其中:

  • {...} 是日志流标签选择器,必须填写,用来缩小 Loki 要扫描的日志流范围。
  • | 后面是可选的日志处理管道,可以继续做关键字过滤、正则过滤、JSON/logfmt 解析、字段过滤、格式化等。
  • 页面时间范围由 Nightingale 的时间选择器控制,不需要在 LogQL 中额外写绝对时间。
  • 日志原文模式使用 LogQL 日志查询,统计图表模式使用 LogQL 指标查询,例如 count_over_timeratesum bytopk 等。

本文后续样例使用以下常见 Loki 标签和 JSON 字段。实际查询时,请替换成你自己的 Loki 标签和日志字段。

类型 名称 示例值 常见用途
标签 app nginx 按应用过滤日志流
标签 namespace prod 按命名空间过滤日志流
标签 pod nginx-7d9f 按 Pod 过滤或分组
标签 container nginx 按容器过滤日志流
JSON 字段 method GET 按请求方法过滤或分组
JSON 字段 uri /api/v1/login 按请求路径过滤或分组
JSON 字段 status 200 按状态码过滤或分组
JSON 字段 remote_addr 10.0.0.8 按客户端 IP 过滤或分组
JSON 字段 request_time 0.123 统计请求耗时

基本查询语句

以下示例可直接放在查询输入框中,用于查看日志原文。

场景 示例
查询某个应用的全部日志 {app="nginx"}
同时按命名空间和容器过滤 {namespace="prod", container="nginx"}
标签正则匹配 `{app=~“nginx api”}`
排除某类标签值 {namespace="prod", pod!~".*-canary-.*"}
包含关键字 `{app=“nginx”} = “error”`
排除关键字 {app="nginx"} != "/health"
正则匹配日志原文 `{app=“nginx”} ~ “status=(4 5)\d\d”`
解析 JSON 后按字段过滤 `{app=“nginx”} json status=“500”`
解析 JSON 后匹配 5xx `{app=“nginx”} json status=~“5.."`
解析 JSON 后过滤慢请求 `{app=“nginx”} json request_time > 0.5`
解析 logfmt 后按级别过滤 `{app=“api”} logfmt level=“error”`
只展示关键信息 `{app=“nginx”} json line_format “{{.method}} {{.uri}} {{.status}}"`

常见写法:

{app="nginx"} |= "error"
{namespace="prod", container="nginx"} | json | status=~"5.."
{app="api"} | logfmt | level="error"

Loki 只索引标签,不会索引整条日志内容。查询时建议先用 {app="..."}{namespace="..."}{container="..."} 等标签缩小日志流,再追加关键字或字段过滤。

统计图表查询

统计图表模式需要输入 LogQL 指标查询。最常见的写法是先用 count_over_timerate 把日志转换成时间序列,再用 sum bytopk 等聚合。

统计日志总量

统计最近 5 分钟窗口内的日志条数:

sum(count_over_time({app="nginx"}[5m]))

统计包含 error 关键字的日志条数:

sum(count_over_time({app="nginx"} |= "error"[5m]))

查看日志产生速率

统计某个应用每秒日志产生速率:

sum(rate({app="nginx"}[5m]))

按 Pod 查看日志产生速率:

sum by (pod) (rate({namespace="prod", app="nginx"}[5m]))

按状态码统计数量

如果日志原文是 JSON,且包含 status 字段,可以写:

sum by (status) (
  count_over_time({app="nginx"} | json [5m])
)

只统计 5xx:

sum(
  count_over_time({app="nginx"} | json | status=~"5.."[5m])
)

查看 Top URI

topk(20,
  sum by (uri) (
    count_over_time({app="nginx"} | json [5m])
  )
)

适用于定位当前时间范围内访问量最高的接口。这里的 uri 需要替换为日志中的真实路径字段。

计算 5xx 错误率

sum(rate({app="nginx"} | json | status=~"5.."[5m]))
/
sum(rate({app="nginx"}[5m]))
* 100

返回值单位是百分比。例如结果为 3.5,表示 5xx 日志约占 3.5%。

统计接口 P99 耗时

如果 JSON 日志中有数值字段 request_time,可以用 unwrap 把字段转换为指标值:

quantile_over_time(0.99,
  {app="nginx"}
    | json
    | unwrap request_time
    | __error__=""[5m]
) by (uri)

__error__="" 用于丢弃解析失败或数值转换失败的日志,避免指标查询报错。

使用建议

  1. 优先使用 Loki 标签缩小查询范围,再追加日志内容过滤。
  2. 日志原文排查使用 {...} |= "keyword"| json| logfmt 等管道。
  3. 趋势、TopN、错误率等图表使用统计图表模式,并把 [5m] 调整为适合当前时间范围的窗口。
  4. 如果某个字段无法用于聚合,先确认日志是否真的被 jsonlogfmtregexp 解析成字段。
快猫星云 联系方式 快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云