共计 3062 个字符,预计需要花费 8 分钟才能阅读完成。
在之前的文章 日志系统 EFK 搭建 中提到了一些还未解决的问题, 同时也发现一些新的问题, 比如在 docker 重启的时候, 采集日志的时间倒退(日志采集的偏移量记录出现问题). 请教大佬的意思是在容器重启时, 里面的 fluent-bit 进程直接被 kill 掉, 导致记录日志读取偏移量的 db 没有及时持久化, 所以现在是想关闭原本 dapeng 自带的 fluent-bit, 另外开启一个 fluent-bit 的容器去采集其他容器挂载到本地的日志, 这样只要保证 fluent-bit 的容器尽量运行正常就可以了.
fluent-bit 服务
首先使用官网的 fluent-bit 镜像, 这里为了测试, 使用 debug 版本
fluent-bit:
image: fluent/fluent-bit:1.2-debug
container_name: fluent-bit
restart: on-failure:3
volumes:
- /data/var/fluent-bit/etc/:/fluent-bit/etc/
- /data/var/fluent-bit/log/:/fluent-bit/log/
- /data/var/fluent-bit/db/:/fluent-bit/db/
- /data/logs/:/var/logs/
environment:
- hostname=${host_ip}
- fluentd_host=${host_ip}
- fluentd_port=24224
# fluent-bit 容器内部采集日志路径配置
- fbInputPath=/var/logs/*/*.log
# (测试发现 fbInputPath 不支持逗号分隔的多个路径)
#- fbInputPath=/var/logs/admin/*.log,/var/logs/common/*.log,/var/logs/crm/*.log,/var/logs/delivery/*.log,/var/logs/openApi/*.log,/var/logs/order/*.log,/var/logs/payment/*.log,/var/logs/product/*.log,/var/logs/purchase/*.log,/var/logs/schedule/*.log,/var/logs/wanboMiniprogram/*.log,/var/logs/wanboService/*.log,/var/logs/wanboWechatService/*.log,/var/logs/wechat/*.log
- fbInputExcludePath=/var/logs/*/fluent*.log,/var/logs/*/console.log,/var/logs/*/gc*.log
- fbInputTag=dapeng
- LANG=zh_CN.UTF-8
- TZ=CST-8
labels:
- project.source=
- project.extra=public-image
- project.depends=
- project.owner=
对应的 fluent-bit 配置文件 /data/var/fluent-bit/etc
:
1.fluent-bit.conf
[SERVICE]
Flush 1
Daemon OFF
Log_Level info
Log_File /fluent-bit/log/fluent-bit.log
Parsers_File parse_file.conf
[INPUT]
Name tail
Path ${fbInputPath}
Exclude_Path ${fbInputExcludePath}
Tag ${fbInputTag}
Multiline on
Buffer_Chunk_Size 2m
buffer_max_size 30m
Mem_Buf_Limit 32m
DB.Sync Normal
db_count 400
Path_Key fbKey
Parser_Firstline tail_multiline
db /fluent-bit/db/logs.db
[FILTER]
Name record_modifier
Match *
Record hostname ${hostname}
[FILTER]
Name modify
Match *
Condition Key_Does_Not_Exist message
Add message Key_Does_Not_Exist:message
[FILTER]
Name grep
Match *
Exclude message Key_Does_Not_Exist:message
[OUTPUT]
Name Forward
Match *
Upstream upstream.conf
#Host ${fluentd_host}
#Port 24224
Retry_Limit 1
- 其中 INPUT 的 Path_Key: 将附加被监视文件的名称作为记录的一部分。赋值成为映射中的键。即 parse 解析后的 record 中 会有 (fbKey -> 日志文件的路径) 此键值对
- FILTER record_modifier: 向 record 记录中增加键值对(hostname -> ${hostname})
- FILTER modify: 满足 Condition 条件后, 对记录做修改(record 中不存在 message 键时, 增加键值对 message -> Key_Does_Not_Exist:message)
- FILTER grep: 匹配 record 键, 类似 shell 中的 grep (匹配 message 键的值为 Key_Does_Not_Exist:message 则排除此 record)
其中 modify 和 grep 配合使用, 过滤掉没有 message 键的记录
2.parse_file.conf
[PARSER]
Name tail_multiline
Format regex
Regex (?<logtime>^\d{2}-\d{2} \d{2}:\d{2}:\d{2} \d{3}) (?<threadPool>[^]+) (?<level>[^]+) \[(?<sessionTid>\w*)\] - (?<message>.*)
3.upstream.conf
[UPSTREAM]
name fb-forward
[NODE]
name upstream-fluentd
host fluentd 服务器 ip
port 24224
注意, 尝试发现 fluent-bit.conf 文件可通过 ${key}访问环境变量中的值, 但 upstream.conf 文件中不能获取到环境变量
fluentd 改动
在 fluent.conf
文件中需要加上一个 filter 来处理 fluent-bit 中通过 Path_Key 附带的文件路径, 因为我们的日志路径 /data/logs/[各模块 tag]/*.log, 所以可以通过 enable_ruby 来使用 ruby 表达式从 record 中解析出每个日志文件所属的 tag
<filter fb.dapeng>
@type record_transformer
enable_ruby
<record>
tag ${record["fbKey"].split('/')[3]}
</record>
</filter>
好了, 这样改动之后, fluent-bit 就单独独立出来了, 我们只用关注挂载在本地的日志文件, 其他服务重启也就不会影响日志的收集工作了.
参考官方文档:
https://docs.fluentd.org/
https://docs.fluentbit.io/man…