我们有多个应用程序在Kubernetes下运行,这些应用程序是用Python、Go、Ruby和Elixer编写的。我们使用Fluent Bit将所有日志转发到AWS Open Search。我们的所有组件都将其日志写入STDOUT/STDERR。一些组件以JSON格式写入,一些组件以非JSON文本格式写入。在Open Search UI中,JSON日志条目的全文不会解析为单独的字段。我们可以看到一些metedata字段后面跟了一个很长的json字符串。下面是一个例子:
以下是从OpenSearch UI复制的log
字段的完整内容
2023-01-09T23:41:56.279212506Z stdout F {"level":"WARN","ts":1673307716278.9448,"caller":"internal/internal_task_pollers.go:348","message":"Failed to process workflow task.","Namespace":"ai-platform-dev.59ee7","TaskQueue":"WORKFLOW_QUEUE","WorkerID":"1@workflow-worker-ai-workflow-worker-6c445f59f7-pgn6v@","WorkflowType":"NotesProWorkflow","WorkflowID":"workflow_1169649613530771459_1664751006481316721","RunID":"1ae58130-62d6-4f6a-a6db-8789be13d567","Attempt":12530,"Error":"lookup failed for scheduledEventID to activityID: scheduleEventID: 36, activityID: 36"}
注意,上面的log
字段提取在嵌入的json字符串开始之前有一些内部"字段",我指的是这部分
2023-01-09T23:41:56.279212506Z stdout F
我开始怀疑,log
字段的非JSON开头可能会导致es
fluent-bit输出插件无法解析/解码json内容,然后es
插件不会将json中的子字段交付给OpenSearch。
我正在考虑使用fluent-bit正则表达式解析器来只提取日志字符串的内部json组件,我假设该组件随后将被解析为json并作为单独的字段转发到OpenSearch。
我将尝试使用这个PARSER配置来使用regex将日志字符串的json部分提取到一个名为capturedJson的新字段中,然后将该字段解码为json(来自https://stackoverflow.com/a/66852383/833960的想法):
[PARSER]
Format regex
Name logging-parser
Regex ^(?<timestamp>.*) (?<stream>.*) .* (?<capturedJson>{.*})$
Decode_Field json capturedJson
Time_Format %FT%H:%M:%S,%L
Time_Key time
以非JSON格式记录日志的组件在OpenSearch中看起来很好。
如何配置FluentBit和OpenSearch以使json和非json组件在OpenSearch中正确呈现?
以下是所有组件共享的当前FluentBit配置文件:
{
"fluent-bit.conf": "[SERVICE]
Parsers_File /fluent-bit/parsers/parsers.conf
[INPUT]
Name tail
Tag kube.*
Path /var/log/containers/*.log
DB /var/log/flb_kube.db
Parser docker
Docker_Mode On
Mem_Buf_Limit 5MB
Skip_Long_Lines On
Refresh_Interval 10
[FILTER]
Name kubernetes
Match kube.*
Kube_URL https://kubernetes.default.svc.cluster.local:443
Merge_Log On
Merge_Log_Key data
Keep_Log On
K8S-Logging.Parser On
K8S-Logging.Exclude On
Buffer_Size 32k
[OUTPUT]
Name es
Match *
AWS_Region us-west-2
AWS_Auth On
Host opensearch.my-domain.com
Port 443
TLS On
Retry_Limit 6
Replace_Dots On
Index my-index-name
AWS_STS_Endpoint https://sts.us-west-2.amazonaws.com
"
}
以下是parsers.conf
的摘录
bash-4.2# cat parsers.conf
...
[PARSER]
Name json
Format json
Time_Key time
Time_Format %d/%b/%Y:%H:%M:%S %z
[PARSER]
Name docker
Format json
Time_Key time
Time_Format %Y-%m-%dT%H:%M:%S.%L
Time_Keep On
# --
# Since Fluent Bit v1.2, if you are parsing Docker logs and using
# the Kubernetes filter, it's not longer required to decode the
# 'log' key.
#
# Command | Decoder | Field | Optional Action
# =============|==================|=================
#Decode_Field_As json log
...
在OpenSearch中,我在名为log
的字段中看到完整的日志负载,它被定义为
如果我在Elastic中的索引上执行get并查找log
字段,则会看到:
GET my-index-name
{
}
...
"log" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
...
我是否应该将log
字段的类型修改为动态?我是否还需要更改FluentBit配置中的任何内容?
即使我的组件通常以json记录日志,有时也会向STDERR发出非json格式的输出,例如,如果发生了一些错误情况,绕过了应用程序日志处理。这也能处理吗?
我们正在使用:
- FluentBit 1.8.x
- 开放搜索1.3
我认为这与我的问题有关:https://github.com/microsoft/fluentbit-containerd-cri-o-json-log/blob/main/config.yaml
1条答案
按热度按时间pkln4tw61#
请按照官方文档中的说明使用CRI解析器