Filebeat + ZincSearch 实现轻量级日志管理

Filebeat + ZincSearch 实现轻量级日志管理。Filebeat:轻量级日志采集工具; Zinc:ElasticSearch 的轻量级替代,其 API 可与 ES 通用;

Filebeat + ZincSearch 实现轻量级日志管理

Filebeat:轻量级日志采集工具;

Zinc:ElasticSearch 的轻量级替代,其 API 可与 ES 通用;

本文采用 Filebeat 采集日志,输出到 Zinc 进行存储与展示。

原因:相较于 LogStash(Java 开发),Filebeat(GO开发) 虽然功能更精简,但是上手更快,特别是占用资源大大减少。ElasticSearch 过于笨重,本文采用 ZincSearch 替代 ES。

本文运行环境为 Windows10

安装

安装 ZincSearch

下载对应版本:Releases · zinclabs/zinc (github.com)

windows 环境,切换到二进制执行文件目录,运行以下语句即可

1
2
3
4
set ZINC_FIRST_ADMIN_USER=admin
set ZINC_FIRST_ADMIN_PASSWORD=123456
mkdir data
zinc.exe

Quickstart - ZincSearch

安装 FileBeat

下载并安装:Download Filebeat • Lightweight Log Analysis | Elastic, 根据 “C:\ProgramData\Elastic\Beats\filebeat\filebeat.example.yml” 文件,创建 filebeat.yml 文件。文件内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# filebeat.example.yml
setup.template.settings:
  index.number_of_shards: 1

setup.ilm.enabled: false
setup.template.enabled: true
setup.template.overwrite: true
setup.template.name: "nginx-log"
setup.template.pattern: "nginx-log-*"

filebeat.inputs:
- type: log
  enabled: true
  paths: ["D:/Other/nginx-1.21.6/logs/*.log"]

output.elasticsearch:
  hosts: ["http://127.0.0.1:4080"]
  path: "/es/"
  index: "nginx-log-%{+yyyy.MM.dd}"
  username: "admin"
  password: "123456"
1
2
3
4
5
# 测试 Filebeat 访问 ZincSearch
filebeat test output

# 运行 Filebeat(powershell 管理员身份)
filebeat -e -c filebeat.yml -d "publish"

Zinc 官方的 Filebeat 配置样例:https://docs.zincsearch.com/ingestion/filebeat/

日志访问及查询

http://localhost:4080/ui/search

image-20221108172633100

Docker 方式安装

Zinc

1
2
3
4
5
# D:/zinc/data 为存储目录
# 4080 为访问端口
# ZINC_FIRST_ADMIN_USER 为管理员账号
# ZINC_FIRST_ADMIN_PASSWORD 为管理员密码
docker run -d -v D:/zinc/data:/data -e ZINC_DATA_PATH="/data" -p 4080:4080 -e ZINC_FIRST_ADMIN_USER=admin -e ZINC_FIRST_ADMIN_PASSWORD=123456 --name zinc public.ecr.aws/zinclabs/zinc:latest

Filebeat

1
2
3
docker pull docker.elastic.co/beats/filebeat:8.5.0

docker run -d --name=filebeat --user=root --volume="D:/data/filebeat/filebeat.docker.yml:/usr/share/filebeat/filebeat.yml:ro" --volume="/var/lib/docker/containers:/var/lib/docker/containers:ro" --volume="/var/run/docker.sock:/var/run/docker.sock:ro" docker.elastic.co/beats/filebeat:8.5.0 filebeat -e --strict.perms=false -E output.elasticsearch.hosts=["elasticsearch:4080"]
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# filebeat.yml
filebeat.config:
  modules:
    path: ${path.config}/modules.d/*.yml
    reload.enabled: false

filebeat.autodiscover:
  providers:
    - type: docker
      hints.enabled: true

processors:
- add_cloud_metadata: ~

output.elasticsearch:
  hosts: ["http://127.0.0.1:4080"]
  path: "/es/"
  username: "admin"
  password: "123456"

测试

耗时 并发数 成功数 失败数 qps 最长耗时 最短耗时 平均耗时 下载字节 字节每秒 错误码
1s 100 1278 0 1520.84 125.31 20.22 65.75 200:1278
2s 100 2730 0 1607.42 171.58 20.22 62.21 200:2730
3s 100 3991 0 1569.82 227.7 15.39 63.7 200:3991
4s 100 5376 0 1567.4 227.7 15.39 63.8 200:5376
5s 100 6611 0 1535.95 227.7 15.39 65.11 200:6611
6s 100 8018 0 1552.28 227.7 15.39 64.42 200:8018
7s 100 9507 0 1577.76 227.7 15.39 63.38 200:9507
7s 100 10000 0 1594.01 227.7 4.37 62.73 200:10000

************************* 结果 stat **************************** 处理协程数量: 100 请求总数(并发数*请求数 -c * -n): 10000 总请求时间: 7.316 秒 successNum: 10000 failureNum: 0 ************************* 结果 end ****************************

1
2
3
OS 名称:			Microsoft Windows 10 专业版
处理器:		   Intel64 Family 6 Model 165 Stepping 3 GenuineIntel ~3096 Mhz
物理内存总量:      16,132 MB

优化

优化后的 filebeat 配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#=========================== Filebeat inputs =============================
max_procs: 1                            # *限制一个CPU核心,避免过多抢占业务资源
queue.mem.events: 2048                  # 存储于内存队列的事件数,排队发送 (默认4096)
queue.mem.flush.min_events: 1536        # 小于 queue.mem.events ,增加此值可提高吞吐量 (默认值2048)
#queue.mem.flush.timeout: 1s             # 这是一个默认值,到达 min_events 需等待多久刷出
filebeat.inputs:
- type: log
  enabled: true
  ignore_older: 48h                     # 忽略这个时间之前的文件(根据文件改变时间)
  max_bytes: 20480                      # *单条日志的大小限制,建议限制(默认为10M,queue.mem.events * max_bytes 将是占有内存的一部分)
  recursive_glob.enabled: true          # 是否启用glob匹配,可匹配多级路径(最大8级):/A/**/*.log => /A/*.log ~ /A/**/**/**/**/**/**/**/**/*.log  
  paths:                                # 日志文件路径
    - /data/logs/**/*.log
  exclude_files: [.*file1.*|stdout.log|.*file2.*] # 忽略的文件列表,正则匹配
  fields:                               # 在事件json中添加字段
    appName: ${serviceName}
    agentHost: ${hostIp}
  fields_under_root: true               # 将添加的字段加在JSON的最外层
  tail_files: false                     # 不建议一直开启,从日志文件的最后开始读取新内容(保证读取最新文件),但是如果有日志轮转,可能导致文件内容丢失,建议结合 ignore_older 将其设置为false
  multiline:                            # 多行匹配日志 (https://www.elastic.co/guide/en/beats/filebeat/7.2/multiline-examples.html)
    pattern: '\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}' # 匹配一个以 [YYYY-MM-DD HH:mm:ss 开头的行
    negate: true                        # 将 pattern 取否(即不匹配pattern的情况)
    match: after                        # 将其追加到上一行之后 pattern + negate + match 组合成一条语意为: 如果不匹配 [YYYY-MM-DD HH:mm:ss 开头的行,则将其合并到当前行的上一行
    max_lines: 200                      # 最多匹配多少行,如果超出最大行数,则丢弃多余的行(默认500)
    timeout: 1s                         # 超时时间后,即使还未匹配到下一个行日志(下一个多行事件),也将此次匹配的事件刷出 (默认5s)

#=============================== Processors ===============================
# 省略
#=============================== output ===============================
output.kafka:
  enabled: true
  hosts: ['ip1:9092','ip2:9092']
  topic: 'my_topic'
  partition.round_robin:
    reachable_only: true
  worker: 4
  required_acks: 1
  compression: gzip
  max_message_bytes: 1000000            # 10MB

可额外使用 CGroup 对 cpu 和内存使用量进行限制

参考

【1】Quickstart - ZincSearch

【2】[Filebeat quick start: installation and configuration | Filebeat Reference 8.5] | Elastic

【3】go单体日志采集zincsearch方案实现_Golang_脚本之家 (jb51.net)

【4】记Filebeat系统资源使用优化 - 简书 (jianshu.com)

Gear(夕照)的博客。记录开发、生活,以及一些不足为道的思考……