Grafana Loki 日志查询实战:LogQL 查询示例详解
前言
Grafana Loki 是一个开源的日志聚合系统,它采用独特的索引方式实现了高效的日志存储和查询。LogQL 是 Loki 的查询语言,其语法类似于 PromQL,但专门针对日志数据设计。本文将深入解析 Loki 官方文档中的查询示例,帮助开发者掌握 LogQL 的核心用法。
基础日志查询示例
IP地址过滤查询
在日志分析中,IP地址过滤是常见需求。Loki 提供了专门的 IP 地址处理函数:
示例1:排除特定IP范围的日志
{job_name="myapp"} != ip("192.168.4.5-192.168.4.20")
这个查询会返回所有不属于 192.168.4.5 到 192.168.4.20 这个IP范围内的日志条目。
示例2:匹配子网但排除特定IP
{job_name="myapp"}
| logfmt
| addr = ip("192.168.4.5/16")
| addr != ip("192.168.4.2")
这里先使用 logfmt
解析器提取日志中的地址字段,然后匹配 192.168.4.5/16 子网,但排除具体的 192.168.4.2 地址。
安全日志分析
示例3:提取失败登录信息
{job="security"}
|~ "Invalid user.*"
| regexp "(^(?P<user>\\S+ {1,2}){8})"
| regexp "(^(?P<ip>\\S+ {1,2}){10})"
| line_format "IP = {{.ip}}\tUSER = {{.user}}"
这个查询从 Linux 安全日志中提取无效用户登录尝试,通过正则表达式捕获用户名和IP地址,最后格式化输出。
示例4:提取成功登录信息
{job="security"}
!= "grafana_com"
|= "session opened"
!= "sudo: "
| regexp "(^(?P<user>\\S+ {1,2}){11})"
| line_format "USER = {{.user}}"
这个查询过滤出成功开启的会话,排除特定关键词,最终输出用户名。
指标查询示例
LogQL 不仅可以查询日志内容,还能基于日志生成指标:
示例5:MySQL错误率统计
sum by (host) (rate({job="mysql"}
|= "error" != "timeout"
| json
| duration > 10s [1m]))
这个查询计算每分钟每个主机上持续时间超过10秒的非超时错误的每秒发生率。
查询优化技巧
多阶段过滤顺序
高效的 LogQL 查询应该按照以下顺序组织:
- 流选择器(Stream Selector)
- 行过滤器(Line Filter)
- 标签过滤器(Label Filter)
示例6:优化查询结构
{cluster="ops-tools1", namespace="loki-dev", job="loki-dev/query-frontend"}
|= "metrics.go"
!= "out of order"
| logfmt
| duration > 30s or status_code != "200"
这个查询首先通过流选择器缩小范围,然后进行行级过滤,最后使用解析后的标签进行过滤。
多解析器组合使用
有时需要组合多个解析器来提取复杂日志中的信息:
示例7:组合 logfmt 和 regexp 解析器
{job="loki-ops/query-frontend"}
| logfmt
| line_format "{{.msg}}"
| regexp "(?P<method>\\w+) (?P<path>[\\w|/]+) \\((?P<status>\\d+?)\\) (?P<duration>.*)"
这个查询先使用 logfmt 解析基础结构,然后通过 line_format 重组消息部分,最后用正则表达式提取详细信息。
日志格式化输出
示例8:表格化输出
{cluster="ops-tools1", name="querier", namespace="loki-dev"}
|= "metrics.go"
!= "loki-canary"
| logfmt
| query != ""
| label_format query="{{ Replace .query \"\\n\" \"\" -1 }}"
| line_format "{{ .ts}}\t{{.duration}}\ttraceID = {{.traceID}}\t{{ printf \"%-100.100s\" .query }} "
这个查询通过格式化输出,将复杂的日志信息转换为易读的表格形式。
示例9:去除ANSI颜色代码
{job="example"} | decolorize
这个简单的查询可以去除日志中的ANSI颜色代码,使日志更易于解析。
高级指标计算
Unwrap 操作示例
Unwrap 操作允许从日志中提取数值用于计算:
示例10:计算路径延迟的P99
quantile_over_time(0.99,
{cluster="ops-tools1",container="ingress-nginx"}
| json
| __error__ = ""
| unwrap request_time [1m]) by (path)
这个查询计算nginx-ingress按路径分组的请求时间P99百分位数。
示例11:统计各组织处理的数据量
sum by (org_id) (
sum_over_time(
{cluster="ops-tools1",container="loki-dev"}
|= "metrics.go"
| logfmt
| unwrap bytes_processed [1m])
)
这个查询统计每分钟各组织ID处理的总字节数。
向量聚合示例
示例12:获取日志吞吐量最高的10个应用
topk(10,sum(rate({region="us-east1"}[5m])) by (name))
示例13:按级别统计MySQL日志数量
sum(count_over_time({job="mysql"}[5m])) by (level)
示例14:计算/home端点请求率
avg(rate(({job="nginx"} |= "GET" | json | path="/home")[10s])) by (region)
总结
本文详细介绍了Grafana Loki中LogQL的各种查询示例,从基础的日志过滤到高级的指标计算。掌握这些查询技巧可以帮助开发者更高效地从海量日志中提取有价值的信息。实际使用时,建议根据具体需求组合这些查询模式,并注意查询优化原则以获得最佳性能。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考