Furion平台中fagent(多pod)需要上报日志信息,其中包括:
- fagent java程序运行的信息(方便用户定时执行失败等问题)
- fagent执行的请求样本sample(方便用户查看具体的请求数据)
如何解决日志信息的诉求,使用到一个最新开源的项目Loki
Loki介绍
Loki的第一个稳定版本于2019年11月19日发布,是Grafana Labs 团队最新的开源项目,是一个水平可扩展,高可用性,多租户的日志聚合系统。它的设计非常经济高效且易于操作,因为它不会为日志内容编制索引,而是为每个日志流编制一组标签。项目受 Prometheus 启发,官方的介绍就是:Like Prometheus, but for logs.,类似于 Prometheus 的日志系统
Loki 日志系统由以下3个部分组成:
- loki是主服务器,负责存储日志和处理查询
- promtail是专为loki定制的代理,负责收集日志并将其发送给 loki
- Grafana用于查询和显示日志
整体架构

Loki 日志存储架构:

如图所示,Loki 包含Distributor、Ingester、Querier和可选的Query frontend五个组件。每个组件都会起一个用于处理内部请求的 gRPC 服务器和一个用于处理外部 API 请求的 HTTP/1服务器
i. Distributor
Distributor 是客户端连接的组件,用于收集日志
在 promtail 收集并将日志发送给Loki 之后, Distributor 就是第一个接收它们的组件,每秒可以接收数百万次写入。Distributor会对接收到的日志流进行正确性校验,并将验证后的chunk日志块分批并行发送到Ingester。
ii. Ingester
Ingester 接收来自Distributor的日志流,并将日志压缩后存放到所连接的存储后端。

Ingester接受日志流并构建数据块,其操作通常是压缩和追加日志。每个Ingester 的生命周期有PENDING, JOINING, ACTIVE, LEAVING 和 UNHEALTHY 五种状态。处于JOINING和ACTIVE状态的Ingester可以接受写请求,处于ACTIVE和LEAVING状态时可以接受读请求。
Ingester 将收到的日志流在内存中打包成 chunks ,并定期同步到存储后端。由于存储的数据类型不同,Loki 的数据块和索引可以使用不同的存储
当满足以下条件时,chunks 会被标记为只读:
iii. Querier
Querier 用来查询日志,可以直接从 Ingester 和后端存储中查询数据。当客户端给定时间区间和标签选择器之后,Querier 就会查找索引来确定所有匹配 chunk ,然后对选中的日志进行 grep并返回查询结果。查询时,Querier先访问所有Ingester用于获取其内存数据,只有当内存中没有符合条件的数据时,才会向存储后端发起同样的查询请求。
需要注意的是,对于每个查询,单个 Querier 会 grep 所有相关的日志。目前 Cortex 中已经实现了并行查询,该功能可以扩展到 Loki,通过分布式的 grep 加速查询。此外,由于副本因子的存在,Querier可能会接收到重复的数据,所以其内置了去重的功能,对拥有同样时间戳、标签组和消息内容的日志进行去重处理
Loki与其他日志聚合系统差别:
- 不对日志进行全文本索引。通过存储压缩的,非结构化的日志以及仅索引元数据,Loki更加易于操作且运行成本更低
- 使用与Prometheus相同的标签对日志流进行索引和分组,从而使您能够使用与Prometheus相同的标签在指标和日志之间无缝切换。
- 特别适合存储Kubernetes Pod日志。诸如Pod标签之类的元数据会自动被抓取并建立索引
- 在Grafana中原生支持(需要Grafana v6.0及以上)
集群部署
Loki官方提供了 4 种安装方式:
- 通过 Tanka 安装
- 通过 Helm 安装
- 通过Docker 或Docker Compose安装
- 二进制包安装
接下来使用二进制包安装的方式进行安装部署
一、loki
#下载压缩文件 curl -O -L "https://github.com/grafana/loki/releases/download/v2.0.0/loki-linux-amd64.zip" #解压文件 unzip "loki-linux-amd64.zip" #执行文件授权 chmod a+x "loki-linux-amd64"
#下载Loki和Promtail的配置文件 wget https://raw.githubusercontent.com/grafana/loki/master/cmd/promtail/promtail-local-config.yaml
简单版本的yaml文件配置如下:
auth_enabled: false server: http_listen_port: 3100 grpc_listen_port: 39095 #grpc监听端口,默认为9095 grpc_server_max_recv_msg_size: #grpc最大接收消息值,默认4m grpc_server_max_send_msg_size: #grpc最大发送消息值,默认4m ingester: lifecycler: address: 127.0.0.1 #IP地址 ring: kvstore: store: inmemory replication_factor: 1 final_sleep: 0s chunk_idle_period: 5m chunk_retain_period: 30s max_transfer_retries: 0 max_chunk_age: 20m #一个timeseries块在内存中的最大持续时间。如果timeseries运行的时间超过此时间,则当前块将刷新到存储并创建一个新块 schema_config: configs: - from: 2018-04-15 # index 使用的存储 store: boltdb # chunks 使用的存储 object_store: filesystem schema: v11 index: prefix: index_ period: 168h # 指定 index 和 chunks 可能使用的存储配置,具体使用哪个由 schema_config配置决定 storage_config: boltdb: directory: /opt/loki/loki_data/index
#启动Loki命令 nohup ./loki-linux-amd64 -config.file=loki-local-config.yaml > loki.log 2>&1 & #查看启动是否成功(查看3100端口的进程是否存在) netstat -tunlp | grep 3100 #或者根据名称查找进程(执行命令后有下边的显示,则启动成功) ps -ef | grep loki-linux-amd64 $ root 11037 22022 0 15:44 pts/0 00:00:55 ./loki-linux-amd64 -config.file=loki-local-config.yaml #或者查看日志信息loki.log
二、promtail
#下载压缩文件 curl -O -l "https://github.com/grafana/loki/releases/download/v2.0.0/promtail-linux-amd64.zip" #解压文件 unzip promtail-linux-amd64.zip #执行文件授权 chmod a+x promtail-linux-amd64
#下载Promtail的配置文件 wget https://raw.githubusercontent.com/grafana/loki/master/cmd/promtail/promtail-local-config.yaml
更多参数请看官网https://grafana.com/docs/loki/latest/clients/promtail/configuration/
简单版本的yaml文件配置如下:
# 配置promtail作为一个服务器,开启一个http端口 server: http_listen_port: 9080 grpc_listen_port: 0 # 指明promtail的配置文件在什么地方生成,重启的时候会读取一些信息 positions: filename: /tmp/positions.yaml # 配置promtail怎么连接loki,它作为loki的客户端 clients: - url: http://172.30.162.116:3100/loki/api/v1/push #loki服务器地址 # 配置一些常用的抓取策略 scrape_configs: - job_name: jmxlog static_configs: - targets: - localhost labels: job: jmxlogs __path__: /app/jmxlog/*.log # 收集日志的位置
# Promtail启动 nohup ./promtail-linux-amd64 -config.file=promtail-local-config.yaml > promtail.log 2>&1 & # 确认服务启动 # 可以通过查看日志文件promtail.log或者查看端口9080进程是否启动成功
三、grafana
#下载安装grafana命令,下列命令执行成功后。在/usr/sbin文件夹下会有grafana-server执行文件 wget https://dl.grafana.com/oss/release/grafana-7.3.2-1.x86_64.rpm # 安装grafana包 yum install grafana-7.3.2-1.x86_64.rpm #启动grafana,grafana会占用服务器3000端口,记得保证3000端口不被占用 cd /usr/sbin # 启动 service grafana-server start
添加数据源
1. 访问web页面
http://localhost:3000/ 进行登录(账号密码都是admin),点击下图中的位置,找到Loki,配置数据源

2. 保存数据源
填写数据源的访问地址并保存

3. 日志查看
配置好数据源之后就可以点击下图中的位置,进行日志查看

4. 日志查看效果

此处搜索的{job=“jmxlogs”}为promtail配置
5. 查询基本语法
= 完全相同。
!= 不平等。
=~ 正则表达式匹配。
!~ 不要正则表达式匹配。
fagent日志
1. fagent java程序日志信息
fagent使用的是Spring Boot框架,引入SLF4J,然后写入日志信息
@Slf4j log.info("agent心跳上报: " + slaveHeartBeatEntity.toString());
log4j2.xml
<Configuration status="INFO"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}][%t][%level][%C:%L][%traceId][%userId] %m%n"/>
Console> <RollingFile name="RollingFile" fileName="logs/swqa-fagent.log" filePattern="logs/swqa-fagent-%d{yyyy-MM-dd}.log"> <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}][%t][%level][%C:%L][%traceId][%userId] %m%n" /> <Policies> <TimeBasedTriggeringPolicy/>
Policies>
RollingFile> <Async name="Async"> <AppenderRef ref="Console"/> <AppenderRef ref="RollingFile"/>
Async>
Appenders> <Loggers> <Root level="INFO"> <AppenderRef ref="Async"/>
Root>
Loggers>
Configuration>
2. fagent执行的请求样本
JmeterRunServiceImpl
public class JmeterRunServiceImpl{
public void jmeterExecute(ExecParamDto execParamDto) {
// 测试结果文件路径 // jmx用例文件夹对应的相对路径名 String jmxDir = fileName.substring(0, fileName.lastIndexOf(".")); // 测试结果文件csv文件的名称 String currentTimeStr = System.currentTimeMillis() + ""; String Suffix4 = currentTimeStr.substring(currentTimeStr.length() - 4); String csvName = jmxDir.substring(jmxDir.lastIndexOf(File.separator) + 1) + Suffix4 + ".csv"; // 测试结果文件csv文件的真实路径 String csvPath = casePath + File.separator + jmxDir + File.separator + csvName; } }
JmeterResultCollector
public class JmeterResultCollector extends ResultCollector {
@Override public void sampleOccurred(SampleEvent sampleEvent) {
super.sampleOccurred(sampleEvent); } }
问题排查
在搭建过程中遇到一些奇奇怪怪的问题,下面记录其中一些问题,mark一下
一、grafana添加loki数据源报502错误

报错502,开始以为是链路啥问题,查看了loki的启动日志

loki的yaml文件的读取失败,修改了config的信息,解决问题
二、grafana添加loki数据源报400错误

看报错信息,现在是的时间阶段,开始判断是否因为查询的时间太长,但是调整时间和yaml文件的初始时间,错误仍然存在
三、grafana启动失败
根据网上的文档,下载7.3.2版本的grafana,然后通过
cd /usr/sbin ./grafana-server start
cd /usr/sbin ./grafana-server web
失败
/etc/init.d/grafana-server start
失败
最后使用的启动命令:
cd /usr/sbin service ./grafana-server start

启动成功
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/218611.html原文链接:https://javaforall.net
