轻量级日志平台 Loki 2.3 发布: 15 倍最近数据查询速度提升
一、前言
Loki v2.3.0 中添加了出色的新功能,进行了 bug 修复。除此之外,性能也得到了提升。虽然我们一直很低调,但我们是真的很忙!
二、自定义保留规则
Loki 中的保留对于集群来说一直是全局的,并推迟到底层对象存储。
Loki 现在可以通过 Compactor 组件处理保留。你可以配置每个租户和每个流的保留时间。这些不同的保留配置允许你以更精细的方式控制存储成本并满足安全性和合规性要求。使用 Loki 现有的配置覆盖机制完成配置:
阅读 Loki 存储保留文档[1]了解更多信息。
三、日志删除
Loki 现在支持在指定的时间范围删除选定日志流条目。
与自定义保留功能一样,通过 Compactor 组件支持删除。Compactor 公开用于删除任务的 API 端点。存在用于请求删除、列出现有删除请求及其状态以及取消挂起的删除请求的端点。
此功能的初始实现支持删除截至当前时间 - 24 小时的数据(你不能删除过去 24 小时内的数据)。此实现的主要要求是确保 Loki 可以始终遵守删除个人信息的请求。可以删除截至当前时间的数据,但更复杂。我们将来可能会迭代此功能以添加此类功能。
此功能是实验性的,仅支持BoltDB 托管索引存储[2]。你可以在日志条目删除文档中[3]了解有关此功能的更多信息。
四、录制规则
Loki 现在支持 Prometheus 风格的录制规则。录制规则使你能够定期对日志进行指标查询,将结果指标发送到 Prometheus[4] 和 Prometheus 兼容的系统例如 Cortex 和 Thanos。
录制规则的一个引人注目的用例是用于:无法通过检测来发送 Prometheus metrics 指标的软件。仅使用日志,你就可以创建 metrics 指标!
我们一直在尝试从 Loki 的 metrics.go 日志行创建每个租户 (org_id) 指标,该行输出大量单独的查询统计信息。
这也可以通过 Prometheus 和直方图来完成,但这种方法的一个优点是我们不需要生成具有租户标签维度的直方图,因此它减少了 Prometheus 中存储的系列数量。每个租户只生成一个系列,而不是每个租户生成一个系列乘以直方图中的桶数。Prometheus 中的记录规则也可以实现相同的减少到每个租户一个系列的效果,但在某些情况下,这种方法可能更适合你。
此功能是实验性的。有关更多详细信息,请参阅录制规则文档[5]。
五、模式解析器
使用新的模式解析器,编写 LogQL 查询以提取非结构化日志的标签变得更快、更容易。使用模式解析器,你可以避免编写繁琐的正则表达式,尤其是对于由文字和空格分隔的标记形成的常见日志格式。
考虑这个 NGINX 日志行:
0.191.12.2 - - [10/Jun/2021:09:14:29 +0000] "GET /api/plugins/versioncheck HTTP/1.1" 200 2 "-" "Go-http-client/2.0" "13.76.247.102, 34.120.177.193" "TLSv1.2" "US" ""
可以使用模式解析器表达式解析此日志行:
<ip> - - <_> "<method> <uri> <_>" <status> <size> <_> "<agent>" <_>
它提取这些字段:
"ip" => "0.191.12.2"
"method" => "GET"
"uri" => "/api/plugins/versioncheck"
"status" => "200"
"size" => "2"
"agent" => "Go-http-client/2.0"
要了解有关语法的更多信息,请参阅 LogQL 文档[6]。
六、分片摄取器
Loki 中的分片是查询前端用于拆分查询以进行并行计算的技术。在 v2.3.0 之前,未对最近的数据应用分片。使用分片摄取,所有时间范围都是并行化的。
**分片提高了性能:我们的环境从 ~1GB/s 的搜索速度跃升至 ~15GB/s。**它应该提高对大量流或具有大量数据的流的近期数据查询的搜索性能。
举个例子,看看从我们的 NGINX 入口控制器查询最后一小时的数据时的差异,它每小时记录大约 90GB:在摄取分片之前:
❯ logcli query '{container="ingress-nginx"} |= "trytofindme!!!"' --since=1h --stats 2>&1 | grep Summary
Summary.BytesProcessedPerSecond 784 MB
Summary.LinesProcessedPerSecond 1263304
Summary.TotalBytesProcessed 88 GB
Summary.TotalLinesProcessed 141420028
Summary.ExecTime 1m51.944531908s
摄取分片后:
❯ logcli query '{container="ingress-nginx"} |= "trytofindme!!!"' --since=1h --stats 2>&1 | grep Summary
Summary.BytesProcessedPerSecond 15 GB
Summary.LinesProcessedPerSecond 24171034
Summary.TotalBytesProcessed 88 GB
Summary.TotalLinesProcessed 142086646
Summary.ExecTime 5.878385063s
Ingester 分片默认处于启用状态,但仅当你运行一个查询前端组件负责创建发送到 ingesters 的拆分和分片时才会生效。
七、LogQL IP 地址匹配
对于想要对包含 IP 地址的日志进行更复杂过滤的任何人,LogQL 已经学习了许多新技巧来帮助你。
语法如下:ip("<pattern>")
. <pattern>
可以是:
单个 IP 地址。例子: ip("192.0.2.0")
,ip("::1")
IP 地址内的一个范围。示例: ip("192.168.0.1-192.189.10.12")
,ip("2001:db8::1-2001:db8::8")
CIDR 规范。示例: ip("192.51.100.0/24")
、ip("2001:db8::/32")
这允许你执行以下操作:返回匹配特定 IP 的日志行
{container="nginx"} |= ip("192.168.4.5")
返回不包括 IP 范围的日志行
{container="nginx"} != ip("192.168.4.1-192.168.4.10")
返回匹配特定子网的日志行
{container="nginx"} |= ip("192.168.4.0/24")
在LogQL 文档中[7]了解有关语法的更多信息[8]。
八、扩展阅读
Spring boot 微服务组件 mica 中的 mica-logging 组件支持 json 日志收集到 loki,也支持日志直接批量发送到 loki,欢迎试用。
参考资料
Loki 存储保留文档: https://grafana.com/docs/loki/latest/operations/storage/retention/#retention-configuration
[2]BoltDB 托管索引存储: https://grafana.com/docs/loki/latest/operations/storage/boltdb-shipper/
[3]日志条目删除文档中: https://grafana.com/docs/loki/latest/operations/storage/logs-deletion/
[4]Prometheus: http://grafana.com/oss/prometheus/
[5]录制规则文档: https://grafana.com/docs/loki/latest/rules/#recording-rules
[6]LogQL 文档: https://grafana.com/docs/loki/latest/logql/#pattern
[7]LogQL 文档中: https://grafana.com/docs/loki/latest/logql/ip
[8]更多信息: https://grafana.com/docs/loki/latest/logql/ip