日志系统平台搭建

背景

随着项目增多, 随之而来的是众多的日志文件, 而不同项目应用的文件, 有可能分布在不同的服务器中. 且线上查看日志筛选有效信息不是很不方便, 项目bug排查的成本逐渐增加. 

为了提高工作效率, 减轻运维压力. 引入日志系统, 同一收集日志, 可以在页面中进行查看筛选, 极大提高排错效率. 

实现目标

日志收集
	需要采集相应的应用日志信息
	
日志分析
	分析,处理,聚合 日志数据

图形web展示
	界面展示, 可筛选搜索
	

技术选型

ELK

Elasticsearch + Logstash + Kibana

- Elasticsearch: 作为日志的存储和搜索系统
	开源分布式搜索引擎,提供搜集、分析、存储数据三大功能。
	它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。
	分布式的实时文件存储,每个字段都被索引并可被搜索, 可以扩展到上百台服务器,处理PB级结构化或非结构化数据

- Kibana: 作为可视化前端展示
	一个开源和免费的工具
	Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助汇总、分析和搜索重要数据日志。

- Logstash: 负责做日志的聚合和处理
	基于JRuby实现,可以跨平台运行在JVM上
	灵活性, 插件丰富, 配置简洁适用于多种场景
	性能与资源消耗大(默认的堆大小是 1GB)

EFK

Elasticsearch + Fluentd(或Filebeat) + Kibana

在容器化场景中,尤其是在Kubernetes环境中,用户经常使用的另一套框架是EFK架构。

Fluentd: 开源社区中流行的日志收集工具
	基于CRuby实现
	fluentd设计简洁,pipeline内数据传递可靠性高。
	相较于logstash,其插件支持相对少一些。
	
Filebeat: 
	使用go语言编写
	只是一个二进制文件没有任何依赖, 它占用资源极少
	保持每个文件的状态,并且频繁地把文件状态从注册表里更新到磁盘。
	如果在你的使用场景中,每天会产生大量的新文件,Filebeat的注册表文件会变得非常大

PLG

Promtail + Loki + Grafana

其中Grafana是一款开源的可视化和分析软件,它允许用户查询、可视化、警告和探索监控指标。主要提供时间序列数据的仪表板解决方案,支持超过数十种数据源(还在陆续添加支持中)。

Promtail: 是一个日志收集的代理,它会将本地日志的内容发送到一个Loki实例,它通常部署到需要监视应用程序的每台机器/容器上。Promtail主要是用来发现目标、将标签附加到日志流以及将日志推送到Loki。

Loki: 与其它日志系统不同的是,Loki只建立日志标签的索引而不索引原始日志消息,而是为日志数据设置一组标签,这意味着Loki的运营成本更低,效率也能提高几个数量级。

方案对比

ELK/EFK架构:
	-- 功能强大, 生态齐全
		Elasticsearch 提供近乎实时的方式来查看、分析海量的数据。
		Kibana 提供了许多可视化工具来进行数据分析, 高级功能比如异常检测等机器学习功能。
		logstash或Filebeat 可对提取日志进行格式化处理
		
	-- 全文索引, 查询速度快
		ES 将日志以非结构化json对象的形式存储在磁盘中, 并为每个对象都建立了索引
	
	-- 框架成熟, 生态健康
		功能复杂, 允许复杂操作
		数据处理与清洗有成熟的方案
		技术论坛等生态环境有很大优势
	
	-- 缺点
		功能复杂带来的就是资源占用与功能冗余
		倒排索引的切分和共享的成本较高

PLG系统:
	-- Loki 的数据存储是解耦的
		既可以在磁盘存储数据, 亦可以使用如Amazon S3的云存储系统
	
	-- 只对标签索引, 资源占用小
		loki中的日志带有一组标签名和值, 只对标签索引, 比全文索引操作成本更低, 但针对内容查询时需通过 LogQL 再单独查询
	
	-- 原生支持
		Grafana 原生支持, Promtail是专门为Loki量身定制的
	
	-- 适用于K8S得扩展性
    	可以为运行在同一节点上的K8S Pods做服务发现, 特别适合储存 K8S POD日志, 便于后续服务升级
	
	-- 缺点
		相对较轻, 功能单一, 不支持复杂操作
		技术论坛相对不活跃
		

系统架构基础

架构图

  • loki是主服务器,负责存储日志和处理查询。
  • promtail是专为loki定制的代理,负责收集日志并将其发送给 loki
  • Grafana用于 UI展示。

img

promtail 采集log日志文件信息, 通过api等方式发送至 loki 服务, loki 与 Grafana 连用, 实现日志的可视化展示.

Promtail

采集器

Promtail的用例专门针对Loki量身定制。它的主要操作模式是发现存储在磁盘上的日志文件,并将与一组标签关联的日志文件转发给Loki。
Promtail可以为与Promtail在同一节点上运行的Kubernetes Pod进行服务发现,充当容器Sidecar或Docker日志记录驱动程序,从指定的文件夹中读取日志并尾随系统日志。

Grafana

web 界面展示

Loki

preview

Distributor (分配器)
第一个接收日志的组件,Loki通过构建压缩数据块来实现批处理和压缩数据.

每秒可以接收数百万次写入, 并会对接收到的日志流进行正确性校验, 将验证后的chunk日志块分为若干批次, 并行发送到多个采集器Ingester。

问题点

- 通信:
	分配器通过 gRPC机制 和采集器进行通信, 无状态, 可以根据实际进行扩缩容

- 重复校验:
	分批, 并行
	分配器采用 一致性哈希 和 可配置的复制因子 结合使用, 来确定哪些 采集器 服务应该接受日志数据. 
	
	哈希 基于日志标签和租户ID的组合
	
	所有的 采集器 会将他们自己的标识(一组token) 注册到哈希环中, 同时上报其状态. 分配器 会找到与日志的哈希值最匹配的 token , 并将数据发送至该token的 所有者
	
	由于所有 分配器 共享同一个 哈希环, 所以可以向任何 分配器 发送写请求
	为了保证结果的一致性,Distributor 会等待收到至少一半加一个Ingester 的回复后才响应客户端。
Ingester (采集器)
组件ingester是一个有状态的组件,负责构建和刷新chunck,当chunk达到一定的数量或者时间后,刷新到存储中去。

img

问题点

- 构建
	ingester接收到日志并开始构建chunk, 基本上就是将日志进行压缩并附加到chunk上面。
	一旦 chunk 数据达到设定点或过了一定期限, 采集器会将其刷新到数据库(DynamoDB、S3、Cassandra 等等)
	刷新一个chunk之后,ingester然后创建一个新的空chunk并将新条目添加到该chunk中。

- 校验
	检验日志是否乱序
	日志时间戳递增接受
		传入的日志数据行完全一致, 会被忽略
		时间戳相同, 内容不同, 接受
	
- 存储
	对块和索引的存储, 使用单独的数据库,因为它们存储的数据类型不同。(如下图)
	
- 数据丢失
	如果采集器进程突然挂掉, 所有还没持久化的数据都会丢失, loki 通常配置多个副本(通常为3个) 来降低风险.
	

img

Querier
由Querier负责给定一个时间范围和标签选择器,Querier查看索引以确定哪些块匹配,并通过greps将结果显示出来。

问题点

- 过程
	它首先会尝试查询所有采集器的内存数据,然后再返回到后端存储中加载数据, 内置去重.

- 效率
	对于每个查询,一个查询器将为您显示所有相关日志。实现了查询并行化,提供分布式grep.

实现

以下为docker-compose搭建方法

配置文件下载

wget https://raw.githubusercontent.com/grafana/loki/v1.5.0/cmd/loki/loki-local-config.yaml -O loki-config.yaml

wget https://raw.githubusercontent.com/grafana/loki/v1.5.0/cmd/promtail/promtail-docker-config.yaml -O promtail-config.yaml

修改配置

vim loki-local-config.yaml 
	# 去掉这几行, 否则会报错
	wal:
        enabled: true
        dir: /tmp/wal
        recover: true
        
vim promtail-local-config.yaml
	# 修改 clients, 将host改为服务器地址
	# 添加 scrape_configs 对应的 labels 进行日志收集

搭建

$ wget https://raw.githubusercontent.com/grafana/loki/v1.5.0/production/docker-compose.yaml -O docker-compose.yaml

$ docker-compose up -d

参考 ocker-compose.yaml 文件

version: "3.6"

networks:
  loki:

services:
  loki:
    image: grafana/loki:1.5.0
    container_name: loki
    volumes:
      - $PWD:/etc/loki
    ports:
      - "3100:3100"
    command: -config.file=/etc/loki/loki-config.yaml
    networks:
      - loki

  promtail:
    image: grafana/promtail:1.5.0
    container_name: promtail
    volumes:
      - /var/log:/var/log
      - $PWD:/etc/promtail
      - /loki:/loki	# 该地址为映射 log 日志文件存放地址
    command: -config.file=/etc/promtail/promtail-config.yaml
    networks:
      - loki

  grafana:
    image: grafana/grafana
    container_name: grafana
    ports:
      - "3000:3000"
    networks:
      - loki
      

Grafana配置

访问 Grafana 界面
	web页面:http://{host}:3000/  进行登录(账号密码都是admin)
	
配置添加 loki 数据源
	DATA SOURCES => Loki => 填写 HTTP 地址(loki server地址)
	
点击 Explore 即可查看日志了 
	logQL 查询

多节点配置

服务器中配置 promtail 容器即可(或使用二进制文件)

使用

界面化操作

Grafana 提供了界面化操作

log browser 指定选择部分job, 或者filename

logQL 指令

详情参考官网: https://grafana.com/docs/loki/latest/logql/

{job="apache"}	// 显示 job 标签为 apache 的日志
{job="syslog"} // 显示 job 标签为 syslog 的日志
{job=~"apache|syslog"} // 显示 job 标签为 apache 或者 syslog 的日志
{job="apache", filename="xxx.log"}	// 指定日志文件名查询
{job="apache"} |= "error" // 显示 job 标签为 apache 并且包含 error 内容的日志

Logo

开源、云原生的融合云平台

更多推荐