在 Fluentd Bit 中可以使用 read 或 socket 方式处理日志
在 docker-compose 中当有服务要转发 Log 到 EFK 平台我们可以如下配置,24224 port 就是与 Fluentd Bit 沟通的点。
logging:
driver: fluentd
options:
fluentd-address: 192.168.101.129:24224
tag: web-backend
在过程中发现先前已开发完的应用程序,要如何区分开发环境,以利於分析时做区分使用以下打 labels
方式。抑或着在在开发的应用程序上进行打标签的动作来识别,以 spring boot 来说可以在 logback 中定义。
logging:
driver: fluentd
options:
fluentd-address: "192.168.101.129:3003"
labels: "production_status"
labels:
production_status: "dev"
目前在调研的时候有发现配置档名称需要是 fluent-bit.conf,否则会出现无法读取到档案的问题,但这问题也不确定是不是我的问题XD
每个传入数据(Log、Metric)都视为一个事件(Event)或记录(Record)
Mar 8 10:03:36 ubuntu dockerd[18162]: time="2021-03-08T10:03:36.491688014+08:00" level=info msg="NetworkDB stats ubuntu(857ee003b9b7) - netID:zkgfqq2qthpzdtgrk2w3clhqo leaving:false netPeers:1 entries:2 Queue qLen:0 netMsg/s:0"
Mar 8 10:03:36 ubuntu dockerd[18162]: time="2021-03-08T10:03:36.493309528+08:00" level=info msg="NetworkDB stats ubuntu(857ee003b9b7) - netID:6r7udn06llggcz5awzjfm992m leaving:false netPeers:1 entries:3 Queue qLen:0 netMsg/s:0"
Mar 8 10:07:43 ubuntu systemd[1]: Started Session 124 of user xxxx.
Mar 8 10:08:36 ubuntu dockerd[18162]: time="2021-03-08T10:08:36.691648447+08:00" level=info msg="NetworkDB stats ubuntu(857ee003b9b7) - netID:zkgfqq2qthpzdtgrk2w3clhqo leaving:false netPeers:1 entries:2 Queue qLen:0 netMsg/s:0"
上面提供的日志共有 4 个独立事件,而每个事件由一些特定的组件组合,像是 TIMESTAMP、MESSAGE 等。
对事件进行修改或删除都视为过滤(Filtering)。
范例
被转发至 Fluent Bit 的每个事件都被分配一个标签(Tag)。标签是一个内部字串,路由器在之後阶段用它确定它必须经过哪个 Filter
或 Output
阶段。
input 为 Forward 是不分配标签。标记必须始终匹配规则,这与路由会有关连。
用於表示创建事件的时间,每个事件都会包含。
Fluentd bit 允许将收集和处理的事件透过路由传递到一个或多个目的地,这是使用匹配(Match)来完成。
匹配是一个简单的规则,用於选择与标签(Tag)匹配已定义规则的事件。
来源端数据可以是结构或是非结构化。结构化可以有 Key:Value 格式,并在做过滤时可更加方便。
Fluent Bit 处理数据时,使用系统记忆体堆作为主要和临时的位置来储存事件,接着再将它们发送到私有储存区中,以处理事件。可以这麽的理解用於将处理後的数据放置到临时位置,直到准备好发送为止
在记忆体中缓冲是一个最快的机制,缓冲(Buffering)是一个储存事件的位置,在处理和提交事件时,仍然能够储存事件。
当获取第三方服务事件时,该服务的网路故障或延迟非常普遍时,当接收到要处理的新数据时无法够快交付数据时,将可能会面临backpressure
,使得记忆体大量被消耗。而 Mem_Buf_Limit
能够抑制获取的事件数据量,进而避免。
整体资料流程如下图所示
每个步骤都有相关的套件可使用
范例
[INPUT]
Name cpu
Tag my_cpu
[INPUT]
Name mem
Tag my_mem
[OUTPUT]
Name es
Match my_cpu
[OUTPUT]
Name stdout
Match my_mem # 为了将数据输出至目的,因此必须做匹配动作
当 Input 插件发出事件时,会将事件分组成一个块(Chunk),通常是 2Mb,预设下块都在记忆体中创建。
记忆体是一个很快的机制,对系统附载也小。但当网路发生问题或是有延迟,导致服务无法以正常速率进行传送事件,此使记忆体的消耗将大幅增加并不断累积数据,使得数据超出了传递的大小。这将有机会触发 OOM,因此可使用 mem_buf_limit
方式进行限制,当超过 mem_buf_limit
限制则 Input 会暂停运作,同时间遗失数据的可能性将增加。
使用 Filesystem 缓冲有助於 backpressure 和记忆体控制。
为 Input 进行记忆体和档案系统缓冲的配置将会有性能和数据安全的优势。使用 Filesystem 时系统会将块(Chunk)映射至硬碟上形成一个副本,同时会控制块的量以处里记忆体高使用率和 backpressure 产生的作用。
storage.max_chunks_up
预设为在记忆体储存 128 个块。在能够使用块下能够进行交付或接收数据,剩下的块是非启用状态这些将会用在档案系统中,除非可进行交付,否则不再记忆体中使用。
当 Input 启用 mem_buf_limit
和 storage.type
作为档案系统,当 mem_buf_limit
达到阈值时,不是暂停 Input,而是所有新数据将转到档案系统中已关闭的块(Chunk)。这控制了记忆体也保证数据不遗失。
块(Chunk)也许会透过 Tag 将其路由至目的地。而目的地可以有很多个目标,而每个传送到目标的速率将会不一样,而这不一样将会使其中一个目标产生 backpressure
。可透过 storage.total_limit_size
进行限制,该限制当被触发时,输出到目的地的队列中最旧的块(Chunk)将被丢弃。
相关的储存配置可参考此链接
架构如下图,我们可以这样设计
蓝色为一台主机,而红色是不同开发环境的主机,fluent
充当 agent,在每台主机蒐集 log 并将其传送至 Elasticsearch 上,後须搭配 Praeco
实现 log 告警。
在 fluent-bit
配置如下,Filter 可以想成是 pipeline 概念。
[SERVICE]
flush 1
log_Level info
daemon off
parsers_File parsers.conf
# use driver method
[INPUT]
name forward
listen 0.0.0.0
port 24224
tag docker.socket
# use read
[INPUT]
name tail
tag docker.file
path /fluentd/log/containers/web.log
DB /var/log/flb_docker.db
mem_buf_limit 5MB
skip_long_lines Off
refresh_interval 10
Docker_Mode On
Docker_Mode_Flush 4
Docker_Mode_Parser multiline2 # 捕获 JAVA Exception Stack
[FILTER]
Name parser
Match docker.socket
Key_Name log
Parser spring # 解析 JAVA log
Reserve_Data On
Preserve_Key On
[FILTER]
Name parser
Match docker.file
Key_Name log
Parser docker # 处里 Json
Reserve_Data On
Preserve_Key On
[FILTER]
Name parser
Match docker.file
Key_Name log
Parser h365
Reserve_Data On # 将原始直对保留在解析的结果中
Preserve_Key On # 将原始的 Key_Name 字段保留在解析的结果中
# 新增 Tag
[FILTER]
Name record_modifier
Match docker.file
Record production_status dev
Record container_name web
Remove_key time
[OUTPUT]
name es
match *
host 192.168.101.129
port 3001
index fluent-bit
logstash_format on
logstash_Prefix 120.log
logstash_dateformat %Y%m%d
replace_dots on
retry_limit false
parser,这部分其实满重要,如果 Log 没制订统一规范时,解析会变得很麻烦。解析部分就得研究正规表示XD
[PARSER]
Name spring
Format regex
Regex /^(?<time>((\d)+((-|:)\d+)+(\W+)\S+)+)(\s)?(?<level>\S+)\W+(?<logger>\S+)\W+(?<message>(\S|\s)*)/
Time_Key time
Time_Format %b %d %H:%M:%S
[PARSER]
Name multiline2
Format regex
Regex /(?<log>^{"log":"((\d)+((-|:)\d+)+.*))/
[PARSER]
Name docker
Format json
Time_Key time
Time_Format %Y-%m-%dT%H:%M:%S.%L
Time_Keep On
[PARSER]
Name h365
Format regex
Regex /^(?<time>((\d)+((-|:)\d+)+))(\S)+(\s)+(?<thread>(\S)+)(\W)+(?<level>\S+)(\W+)(?<message>(\S|\s)*)/
Time_Key time
Time_Format %b %d %H:%M:%S
当然可以用 --log-driver
转发
docker run -it -d -p 80:80 --log-driver fluentd --log-opt fluentd-address=tcp://192.168.101.129:24224 --log-opt labels=production_statu
s=testing --log-opt tag=web nginx
使用 docker-compose logging 设定进行日志转发,此方式本地不会储存 Log,配置如下
logging:
driver: fluentd
options:
fluentd-address: "192.168.101.120:24224"
tag: "spring boot"
labels: "production_status"
labels:
production_status: "dev"
会存在无法分辨是哪个容器产生,因此使用 labels
关键字实现自订义标签。这样可用来解决分辨问题源,可参考此链接。
>>: [Day 3] - 『转职工作的Lessons learned』 - 资料库转换
第四个范例跟机器视觉与影像辨识有关, 我们先来了解一下什麽是机器视觉. 机器视觉 机器视觉想要做的事...
预设版型? 前⾯提到说预设的版型是 app/views/layouts/application.ht...
前言 目标:串接虾皮订单、标签资讯,目前串接虾皮 OpenAPI 2.0 版本,串接手册 串接步骤:...
继上篇主要以区块链三个特徵叙写,下篇笔者将探讨区块链的价值、治理,这篇会是比较实用一点的生活应用面向...
前言 没错,今年再度在最後一天急急忙忙赶稿。 在这个好像不会任何一个框架,就无法存活的前端圈里 决定...