Grafana Loki,轻量级日志系统
Grafana Loki,轻量级日志系统
在生产环境中,日志的采集、加工、存储、检索、分析、可视化和监控告警是不可或缺的环节。企业通常会选择云厂商自带的日志系统或基于开源解决方案自建日志系统。本文将介绍一种轻量级的开源日志系统方案——基于Grafana+Loki+Alloy的架构。
Loki简介
Loki是Grafana生态的一部分,它是一个可水平扩展、高可用性、多租户日志聚合系统,灵感来自Prometheus。与Prometheus不同的是,Loki专注于日志而不是指标,并通过推送而不是拉取来收集日志。Loki的设计非常经济高效,并且具有高度可扩展性。与其他日志系统不同,Loki不对日志内容进行索引,而只对日志的元数据进行索引,将其作为每个日志流的一组标签。
数据存储格式
Grafana Loki有两种主要的文件类型:
- index:索引;存储Loki标签,如日志级别、来源、分组
- chunk:块;存储日志条目本身
架构
一个典型的基于Loki的日志系统由3个组件组成:
- Agent:代理或客户端,例如Grafana Alloy或Promtail,随Loki一起分发。代理抓取日志,通过添加标签将日志转换为流,并通过HTTP API将流推送到Loki。
- Loki主服务器:负责摄取和存储日志以及处理查询。它可以部署在三种不同的配置中,有关更多信息,请参阅部署模式。
- Grafana:用于查询和显示日志数据。您还可以使用LogCLI或直接使用Loki API从命令行查询日志。
工作流程
写流程
- distributor接收带有流和日志行的HTTP POST请求。
- distributor会hash计算请求中包含的每个流,决定发给一致性hash环中的哪个ingester。
- distributor把每个流发给合适处理它的ingester及其副本。
- ingester接收带有日志行的流,并为流的数据创建一个块或附加到现有块。每个租户和每个标签集,块都是唯一的。
- ingester回复写操作结果。
- distributor等待大多数ingester确认写入完成。
- distributor在收到至少法定数量的确认写入时响应成功(2xx状态码)。或者在写入操作失败时响应错误(4xx或5xx状态码)。
读流程
- 查询前端(query frontend)接收到携带LogQL的HTTP GET请求。
- 查询前端将查询拆分为子查询并将它们传递给查询调度程序(query scheduler)。
- querier(查询器)从调度程序(scheduler)中提取子查询。
- querier将查询传递给所有保存数据的ingester。
- ingester返回与查询匹配的记忆数据(如果有)。
- 如果ingester没有返回或返回的数据不足,querier会延迟从后备存储加载数据并对其运行查询。
- querier遍历所有接收到的数据并进行重复数据删除,将子查询的结果返回到查询前端。
- 查询前端等待查询的所有子查询完成并由querier返回。
- 查询前端将两个结果合并为最终结果并将其返回给客户端。
Alloy简介
Alloy是Grafana生态的一部分,是一个多功能的可观测性收集器,可以摄取各种格式的日志并将其发送到Loki。推荐Alloy作为向Loki发送日志的主要方法,因为它为构建高度可扩展和可靠的可观测性流水线提供了更强大和特征丰富的解决方案。
Alloy的组件
Type | Component |
---|---|
Collector | loki.source.api |
Collector | loki.source.awsfirehose |
Collector | loki.source.azure_event_hubs |
Collector | loki.source.cloudflare |
Collector | loki.source.docker |
Collector | loki.source.file |
Collector | loki.source.gcplog |
Collector | loki.source.gelf |
Collector | loki.source.heroku |
Collector | loki.source.journal |
Collector | loki.source.kafka |
Collector | loki.source.kubernetes |
Collector | loki.source.kubernetes_events |
Collector | loki.source.podlogs |
Collector | loki.source.syslog |
Collector | loki.source.windowsevent |
Collector | otelcol.receiver.loki |
Transformer | loki.relabel |
Transformer | loki.process |
Writer | loki.write |
Writer | otelcol.exporter.loki |
Writer | otelcol.exporter.logging |
快速搭建
参阅Grafana官网文档,我们可以用Docker Compose部署以下服务,快速体验Loki生态:
- flog:生成日志行。flog是常见日志格式的日志生成器。
- Grafana Alloy:它从flog上抓取日志线,并通过网关将它们推送到Loki。
- 网关(nginx):接收请求并根据请求的URL将它们重定向到适当的容器。
- Loki read组件:它运行一个查询前端和一个查询器。
- Loki write组件:它运行一个分发器和一个Ingester。
- Loki 后端组件:它运行索引网关、压缩器、标尺、Bloom压缩器(实验)和Bloom网关(实验)。
- Minio:Loki用来存储其索引和块。
- Grafana:它提供了在Loki中捕获的日志行的可视化。
准备
# 1、准备目录
mkdir evaluate-loki
cd evaluate-loki
# 2、下载默认配置文件
wget https://raw.githubusercontent.com/grafana/loki/main/examples/getting-started/loki-config.yaml -O loki-config.yaml
wget https://raw.githubusercontent.com/grafana/loki/main/examples/getting-started/alloy-local-config.yaml -O alloy-local-config.yaml
wget https://raw.githubusercontent.com/grafana/loki/main/examples/getting-started/docker-compose.yaml -O docker-compose.yaml
部署
docker compose up -d
注:由于某些限制,Docker官方镜像仓库在国内访问受阻,导致拉取镜像失败,解决方案可以使用“魔法”,对于没条件使用“魔法”的读者朋友,笔者推荐您使用国内镜像加速和代理解决方案,详细配置可参照Docker/DockerHub 国内镜像源/加速列表(1月27日更新-长期维护)-腾讯云开发者社区-腾讯云
验证
待所有容器都处于Up且healthy状态,可通过docker ps命令查看
- Read组件:http://your_server_IP:3101/ready
- Write组件:http://your_server_IP:3102/ready
- Grafana Alloy UI:http://your_server_IP:12345
预期如下:
Grafana
查看日志
可以使用LogCli或者Grafana可视化界面查看日志,使用 Grafana 查询 Loki 数据源的数据
- 访问Grafana:http://your_server_IP:3000/
- 已经整合了Loki数据源
- 点击 Explore 查看
- 使用Code模式,编写 LogQL 查询
查询示例:
标签检索
# 比如我们要查看 container 标签值 为 evaluate-loki-flog-1 的日志
{container="evaluate-loki-flog-1"}
{container="evaluate-loki-grafana-1"}
包含值
# 查看 container 标签值 为 evaluate-loki-flog-1 ,且 json 格式中 status字段值为404
{container="evaluate-loki-flog-1"} | json | status=`404`
计算
sum by(container) (rate({container="evaluate-loki-flog-1"} | json | status=`404` [$__auto]))
其他
{container="evaluate-loki-flog-1"}
{container="evaluate-loki-flog-1"} |= "GET"
{container="evaluate-loki-flog-1"} |= "POST"
{container="evaluate-loki-flog-1"} | json | method="POST"
{container="evaluate-loki-flog-1"} | json | status="401"
{container="evaluate-loki-flog-1"} != "401"
更多 LogQL 语法请参阅:LogQL: Log query language | Grafana Loki documentation
总结
本文简要介绍了基于Grafana+Loki+Alloy构建的开源日志系统的架构、快速入门,希望为大家在做日志采集监控分析场景需求时提供参考解决方案。
通过本文,我们可以发现Loki这套系统架构既能做write组件也能做reader组件还能做backend组件,Loki本身是一个融合了多个模块的单体应用,但它可以根据所需功能解耦,可以进行分布式部署,从部署层面看最终呈现出一些微服务特征。
这种介于单体和微服务之间的另一种架构风格“巨型单体模块化”,即同一个应用封装了某个业务场景的多种功能模块,可单体部署也可分布式部署,分布式部署后整体协同实现了单体全部功能,这类架构风格可以进一步抽象出一种架构思想:“部分即整体,拥有自相似性”,这是一种可行且美妙的架构思想,其美妙程度不亚于数学中的分形,当然“巨型单体模块化”目前仅适用于某些特定业务场景,其也会带来一些挑战,比如在一个单体中融入太多模块,过于巨型臃肿,资源占用,代码重复率,耦合度增加,模块之间依赖等问题,可能还得引入可插拔技术工具去解耦,但这无疑增加了复杂度,但至少提供了一种软件架构思路。