博客/工程

如何使用Loki的LogQL创建快速查询,以在几秒钟内过滤tb级的日志

2020年12月8日5分钟

LogQL,洛基查询语言,很大程度上受到Prometheus PromQL的启发。然而,当涉及到过滤日志和大海捞针时,查询语言是专门针对Loki的。在本文中,我们将为您提供创建快速过滤器查询的所有技巧,这些查询可以在几秒钟内过滤tb级的数据。

在洛基有三种类型的过滤器,你可以使用:

标签匹配器

标签匹配器是您的第一道防线,是大幅减少您正在搜索的日志量(例如,从100TB减少到1TB)的最佳方法。当然,这意味着你需要有好的标签代理的卫生:基本上,标签应该定义您的工作负载(集群、名称空间和容器是最好的),这样您就可以在多个不同的维度上分割数据。例如:

  • 我的应用程序跨所有集群
  • 我的应用程序在所有集群的dev名称空间中
  • 我的prod命名空间
  • 等。

经验法则是:你至少需要一个相等匹配器(例如,{集群= " us-central1 "}).否则,您将不得不提取整个索引数据。但有一个例外:如果正则表达式匹配器包含一个或多个字面量,则可以使用一个正则表达式匹配器,例如{容器= ~”promtail |代理”},因为洛基可以优化它。以下是一些好的和坏的例子:

好:

{集群= " us-central1 "}

{容器= " istio "}

{集群= " us-central1 ",容器= ~”代理| promtail "}

缺点:

{工作= ~”。* /队列”}

{名称空间! ~”dev -。*”}

线过滤器

线条滤镜是你的第二个好朋友,因为它们非常快。它们允许您过滤包含(| =)或不包含(! =)字符串,您还可以使用RE2正则表达式来匹配(| ~)或不匹配(! ~一种模式。这不是强制性的,但你应该在结束后立即进行检查标签匹配器

您可以将其中几个过滤器串联起来,但请注意,这里的顺序非常重要。你想要先过滤最多的那些,然后你可以使用正则表达式,它比等式和不等式慢,但是应用在更少的行上。在数百万行上运行相等和不相等是完全没问题的,但使用正则表达式可能会很慢。

这里有个例外:| ~“错误|致命”可以被洛基优化掉,事实上是这样吗错误致命的,因此不会执行任何正则表达式。

一个好的方法是先添加一个匹配你想要的东西的过滤器,例如,| = "错".执行它,然后添加越来越多的不等式来移除你不想要的东西,直到你得到像这样的东西|= "err" != "timeout" != "cancelled" |~ "failed. "*" != "memcached".现在,如果你意识到你的大多数错误都来自memcached,那么把它移到第一个位置:! = " memcached " | = "错" ! =“超时”! = |“取消”~“失败了。*”.这样,后续过滤器将执行更少的次数。

行筛选器还适用于查找IP、跟踪ID和一般标识符。所以{namespace="prod"} |= "traceID=2e2er8923100"是一个很好的问题。当然,如果您希望此跟踪的所有日志都与某个正则表达式匹配,请添加| ~“/ api / v + /查询”在ID筛选器之后,这样它就不会对prod名称空间中的每一行执行。

标签过滤器

标签过滤器提供更复杂的比较(持续时间、数值等),但它们通常需要先提取标签,然后将标签值转换为另一种类型。这意味着它们通常是最慢的,所以你应该最后使用它们。

好的,这里有一个小秘密,你实际上可以使用标签过滤器而不提取标签(使用解析器,如| json| logfmt).标签过滤器也适用于索引标签。举个例子,{job="ingress/nginx"} | status_code >= 400 and cluster="us-central2"很好,但是您真正应该问自己的是是否需要status_code作为索引标签。通常不应该这样做,但是可以考虑提取status_code作为标签,将大容量流(每秒超过1000行)拆分为单独的流。

| json而且| logfmt解析器是快速的|正则表达式一个是相当慢的。这就是为什么在使用解析器时,我总是在它前面加上一个行筛选器。例如,在我的Go应用程序(包括Loki)中,我的所有日志都附加了文件和行号(这里)调用者= metrics.go: 83):

level=info ts=2020-12-07T21:03:22.885781801Z caller=metrics。go:83 org_id=29 traceID=4078dafcbc079822 latency=slow query="{cluster=\"ops-tools1\",job=\"loki-ops/querier\"} != \"log . log。Go \" != \"参数。go\" |= \"recover\"" query_type=filter range_type=range length=168h0m1s step=5m0s duration=54.82511258s status=200 throughput=8.3GB total_bytes=454GB

因此,当我想过滤慢速请求时,我使用记录延迟的文件和行作为行过滤器,然后解析它并与标签过滤器进行比较。

{namespace="loki-ops",container="query-frontend"} |= "caller=metrics. "go:83" | logfmt | throughput > 1GB and duration > 10s and org_id=29

结论

这三个筛选器(标签匹配器、行筛选器和标签筛选器)就像一个逐步处理日志的管道。您应该尝试在每一步都尽可能地减少,因为后续的每一步对每一行的执行速度都更有可能变慢。

我希望你喜欢我在Loki中编写快速过滤查询的技巧。一定要读完全文LogQL文档在我们的网站上,让我知道你接下来想让我介绍的其他方法!

试试洛基自己安装或者在几分钟内开始Grafana云.我们刚刚宣布了新的免费和付费Grafana云计划,以适应每一个用例-现在免费注册