【Furion】Loki日志系统

【Furion】Loki日志系统Furion 平台中 agent 多 pod 需要上报日志信息 其中包括 agentjava 程序运行的信息 方便用户定时执行失败等问题 agent 执行的请求样本 sample 方便用户查看具体的请求数据 如何解决日志信息的诉求 使用到一个最新开源的项目 LokiLoki 介绍 Loki 是 GrafanaLabs 团队最新的开源项目 是一个水平可扩展 高可用性 多租户的日志聚合系统 它的设计非常经济高效且易于操作 因为它不会为日志内容编制索引 而是为每个日志流编制一组标签 项目受 Prometheus

Furion平台中fagent(多pod)需要上报日志信息,其中包括:

  1. fagent java程序运行的信息(方便用户定时执行失败等问题)
  2. 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 种安装方式:

  1. 通过 Tanka 安装
  2. 通过 Helm 安装
  3. 通过Docker 或Docker Compose安装
  4. 二进制包安装

接下来使用二进制包安装的方式进行安装部署

一、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

(0)
上一篇 2026年3月17日 下午11:50
下一篇 2026年3月17日 下午11:51


相关推荐

  • lua文件加密解密

    lua文件加密解密文章目录前言 lua 文件加密解密加密 lua 前言 lua 修改器语法函数看文档 https max book118 com html 2022 0122 622201522300 shtmlua 文件加密解密下载加密解密的 jar 文件链接 https pan baidu com s 1628x8YM6eUu pwd 1234 提取码 1234 来自百度网盘超级会员 V5 的分享首先你要有一个加密的 lua 脚本 后缀可能是什么 luax luaxxx 使用文档打开是乱码的解

    2026年3月18日
    1
  • 如何求平均数众数中位数_离散系数

    如何求平均数众数中位数_离散系数平均数、中位数、众数,在分析中如何使用?01平均值的种类02平均数、中位数还是众数?03全距和数值分布01平均值的种类请检查下面的陈述:1、一个快速致富的方法就是做一名职业橄榄球员,2015年美国国家橄榄球联盟球星的平均收入是220万美元。2.、为在大学里取得好成绩,学生需要付出的努力越来越少了。根据最近一项调查,大学生每周平均花在学习上的时间是12.8小时,和20年前大学生的学习时长相比,前者大概只有后者的一半。两个例子当中都使用了“平均”这个词,但是实际上有三种不同的方法来测定平

    2025年12月15日
    4
  • Spring IOC和AOP 原理彻底搞懂

    Spring IOC和AOP 原理彻底搞懂br Spring 提供了很多轻量级应用开发实践的工具集合 这些工具集以接口 抽象类 或工具类的形式存在于 Spring 中 通过使用这些工具集 可以实现应用程序与各种开源技术及框架间的友好整合 比如有关 jdbc 封装的数据访问工具 SpringJDBC 有关编写单元测试的 springtest 包以及 spring mock 有关访问动态脚本语言的 SpringScript 另外还有发送邮件的工具 SpringMail 日程及任务处理工具 Springschedu 等 可以这么说 大多数企业级应用开发中

    2026年3月17日
    2
  • 《大话数据结构》边读边感

    《大话数据结构》边读边感第一章:数据结构绪论数据结构:是相互之间存在一种或多种特定关系的数据元素的集合。数据:是描述客观事物的符号,式计算机可以操作的对象,是能被计算机识别,并输入给计算机处理的符号集合。数据输入有两个前提:1、可以输入的计算机中;2、能被计算机程序处理数据元素:是组成数据的,有一定意义的基本单位,在计算机中通常作为整体处理。也被称为记录。数据项:一个数据元素可以由若干个数据项组成;数据项数据不可

    2022年6月24日
    26
  • OJ错误提示类型

    OJ错误提示类型答案正确(Acepted,AC)  恭喜你!所提交的代码通过了数据!这个评测结果应该是大家最喜欢见到的,也非常好理解。如果是单点测试,那么没通过一组数据,就会返回一个Accepted;如果是多点测试,那么只有当通过了所有数据时,才会返回Accepted。编译错误(CompileError,CE)  很显然,如果代码没有办法通过编译,那么就会返回CompileError。这是要…

    2022年6月24日
    24
  • C++实现超分辨率 RDN

    C++实现超分辨率 RDNRDN(由残差密集网络实现的图像超分辨率)在《RDN-TensorFlow-master》有一个3倍模型(也只有这一个了):rdn_5_3_64_x3这里用C++实现这个的3倍重建:流程图:密集残差块:这个残差块结构内部和前面的ESRGAN(前面的文章)中的密集残差块是一样的,只是外部有点不同。定义密集残差块:struct密集残差块//4个卷积层…

    2022年6月18日
    29

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号