菜单
开源

查询示例

这些 LogQL 查询示例附带查询目的的解释。

日志查询示例

基于 IP 地址过滤的示例

  • 返回不在 IPv4 地址范围内的日志行

    logql
    {job_name="myapp"} != ip("192.168.4.5-192.168.4.20")
  • 此示例匹配所有 IPv4 子网值 192.168.4.5/16 中的日志行,但不包括 IP 地址 192.168.4.2

    logql
    {job_name="myapp"}
    	| logfmt
    	| addr = ip("192.168.4.5/16")
    	| addr != ip("192.168.4.2")

有助于安全评估的示例

  • 从 Linux /var/log/secure 中提取登录失败的用户和 IP 地址

    logql
    {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 /var/log/secure 中获取成功登录

    logql
    {job="security"}
        != "grafana_com"
        |= "session opened"
        != "sudo: "
        | regexp "(^(?P<user>\\S+ {1,2}){11})"
        | line_format "USER = {{.user}}"

指标查询示例

  • 返回 MySQL 作业每台主机在过去几分钟内所有非超时错误的每秒速率,且仅包含持续时间超过十秒的错误。

    sum by (host) (rate({job="mysql"}
        |= "error" != "timeout"
        | json
        | duration > 10s [1m]))

多重过滤阶段示例

查询结果是通过从左到右依次评估查询的各个部分来收集的。为了提高查询效率,过滤阶段应按从左到右的顺序排列

  1. 流选择器
  2. 行过滤器
  3. 标签过滤器

考虑以下查询

logql
{cluster="ops-tools1", namespace="loki-dev", job="loki-dev/query-frontend"} |= "metrics.go" != "out of order" | logfmt | duration > 30s or status_code != "200"

在此查询中,流选择器为

{cluster="ops-tools1", namespace="loki-dev", job="loki-dev/query-frontend"}

这里有两个行过滤器:|= "metrics.go"!="out of order"。在通过流选择器标识的日志行中,查询结果仅包含那些包含字符串“metrics.go”且不包含字符串“out of order”的日志行。

logfmt 解析器生成 durationstatus_code 标签,以便标签过滤器可以使用它们。

标签过滤器 | duration > 30s or status_code!="200" 进一步过滤日志行。它包含那些 status_code 标签值非 200 的日志行,以及 duration 标签值大于 30 秒的日志行,

虽然每个查询都有一个流选择器,但并非所有查询都包含行过滤器和标签过滤器。

使用多个解析器的示例

考虑这条 logfmt 日志行。要提取这条 logfmt 日志行的方法和路径,

log
level=debug ts=2020-10-02T10:10:42.092268913Z caller=logging.go:66 traceID=a9d4d8a928d8db1 msg="POST /api/prom/api/v1/query_range (200) 1.5s"

要提取方法和路径,可以使用多个解析器(logfmt 和 regexp)

logql
{job="loki-ops/query-frontend"} | logfmt | line_format "{{.msg}}" | regexp "(?P<method>\\w+) (?P<path>[\\w|/]+) \\((?P<status>\\d+?)\\) (?P<duration>.*)"

这是因为 | line_format 将日志行重新格式化为 POST /api/prom/api/v1/query_range (200) 1.5s,然后可以使用 | regexp ... 解析器对其进行解析。

日志行格式化示例

以下查询展示了如何重新格式化日志行,使其更易于在屏幕上阅读。

logql
{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 }} "

标签格式化用于净化查询,而行格式化减少信息量并创建表格输出。

对于这些给定的日志行

log
level=info ts=2020-10-23T20:32:18.094668233Z caller=metrics.go:81 org_id=29 traceID=1980d41501b57b68 latency=fast query="{cluster=\"ops-tools1\", job=\"loki-ops/query-frontend\"} |= \"query_range\"" query_type=filter range_type=range length=15m0s step=7s duration=650.22401ms status=200 throughput_mb=1.529717 total_bytes_mb=0.994659
level=info ts=2020-10-23T20:32:18.068866235Z caller=metrics.go:81 org_id=29 traceID=1980d41501b57b68 latency=fast query="{cluster=\"ops-tools1\", job=\"loki-ops/query-frontend\"} |= \"query_range\"" query_type=filter range_type=range length=15m0s step=7s duration=624.008132ms status=200 throughput_mb=0.693449 total_bytes_mb=0.432718

结果将是

log
2020-10-23T20:32:18.094668233Z	650.22401ms	    traceID = 1980d41501b57b68	{cluster="ops-tools1", job="loki-ops/query-frontend"} |= "query_range"
2020-10-23T20:32:18.068866235Z	624.008132ms	traceID = 1980d41501b57b68	{cluster="ops-tools1", job="loki-ops/query-frontend"} |= "query_range"

可以从日志行中去除 ANSI 序列,使其更易于进一步解析

{job="example"} | decolorize

这样,这条日志行

[2022-11-04 22:17:57.811] \033[0;32http\033[0m: GET /_health (0 ms) 204

变成

[2022-11-04 22:17:57.811] http: GET /_health (0 ms) 204

展开(Unwrap)示例

  • 计算按路径划分的 nginx-ingress 延迟的 p99

    logql
    quantile_over_time(0.99,
      {cluster="ops-tools1",container="ingress-nginx"}
        | json
        | __error__ = ""
        | unwrap request_time [1m]) by (path)
  • 计算按组织 ID 划分的处理字节数

    logql
    sum by (org_id) (
      sum_over_time(
      {cluster="ops-tools1",container="loki-dev"}
          |= "metrics.go"
          | logfmt
          | unwrap bytes_processed [1m])
      )

向量聚合示例

按日志吞吐量最高获取前 10 个应用程序

logql
topk(10,sum(rate({region="us-east1"}[5m])) by (name))

获取指定作业在过去五分钟内的日志行计数,按级别分组

logql
sum(count_over_time({job="mysql"}[5m])) by (level)

按区域获取 NGINX 日志中对 /home 端点的 HTTP GET 请求速率

logql
avg(rate(({job="nginx"} |= "GET" | json | path="/home")[10s])) by (region)