在之前的文章
日志系统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, 解析完成后将fbKey字段以及数据remove掉:
<filter fb.dapeng>
@type record_transformer
enable_ruby
<record>
tag ${record["fbKey"].split('/')[3]}
</record>
remove_keys fbKey
</filter>
好了, 这样改动之后, fluent-bit就单独独立出来了, 我们只用关注挂载在本地的日志文件, 其他服务重启也就不会影响日志的收集工作了.
todo
- 我们可以将其他服务器的日志定时同步到单独的efk服务器上, 路径按照一定的规则比如:
/data/logs/模块tag/服务器hostname/*.log
这样, 在fluentd中解析出tag和hostname, 也不需要占用其他服务器的资源, 将服务与日志管理独立开来. - 也可以将fluent-bit采集服务放在需要日志采集的服务器上, 然后将采集到的数据发到日志服务器fluentd中处理, 其中
fluentd -> kafka -> elasticsearch
的流程也为我们进行实时日志告警提供了便利, 只需要监听kafka中level: ERROR级别的日志, 然后做告警通知处理即可.
参考官方文档:
https://docs.fluentd.org/
https://docs.fluentbit.io/man…