我的实验室有几个Docker容器如下:
姓名 | Docker 映像 |
---|---|
Fluentd | 流利/fluentd:v1.16-1 |
Fluent-bit | cr.fluentbit.io/fluent/fluent-bit |
洛基 | grafana/loki |
格拉法纳 | grafana/grafana-enterprise |
球童 | 球童:建造者 |
我的目标是收集 Caddy 日志并在 Grafana 中将其可视化。
场景:Fluent-bit 跟踪日志并将其发送到 Fluentd。然后 Fluentd 将日志推送到 Loki。我的目标是使用 Fluentd 作为中央日志收集器。
问题在于 Grafana 端对这些日志的解析。
Caddy 日志采用(嵌套)JSON 格式。示例:
{“level”:“info”,“ts”:“1712949034.535184”,“logger”:“http.log.access.log1”,“msg”:“处理的请求”,“请求”:{“remote_ip”:“172.18.0.1”,“remote_port”:“39664”,“client_ip”:“172.18.0.1”,“proto”:“HTTP / 1.1”,“method”:“POST”,“host”:“grafana.darknet.com”,“uri”:“/ api / short-urls”,“headers”:{“Content-Length”:“580”],“Origin”:“http://grafana.darknet.com”],“Content-Type”:“application / json”],“User-Agent”:“Mozilla / 5.0(X11; Linux x86_64; rv:124.0)Gecko / 20100101 Firefox/124.0”],“Accept”:[“application/json,text/plain,*/*”],“X-Grafana-Org-Id”:[“1”],“Connection”:[“keep-alive”],“Accept-Language”:[“en-US,en;q=0.5”],“Accept-Encoding”:[“gzip, deflate"],"Referer":["http://grafana.darknet.com/explore?schemaVersion=1&panes=%7B%22Efb%22:%7B%22datasource%22:%22f779c221-7bd2-468d-9f9c-96e069b869f8%22,%22queries%22:%5B%7B%22refId%22:%22A%22,%22expr%22:%22%7Bjob%3D%5C%22caddy.log.loki%5C%22%7D%20%7C%20json%22,%22queryType%22:%22range%22,%22datasource%22:%7B%22type%22:%22loki%22,%22uid%22: %22f779c221-7bd2-468d-9f9c-96e069b869f8%22%7D,%22editorMode%22:%22code%22%7D%5D,%22range%22:%7B%22from%22:%22now-1m%22,%22to%22:%22now%22%7D%7D%7D&orgId=1"],"X-Grafana-Devi ce-Id”:[“f343e938e74b3a57997faff69d24de8a”],“Cookie”:[]}},“bytes_read”:580,“user_id”:“”,“duration”:0.011267887,“size”:72,“status”:200,“resp_headers”:{“X-Xss-Protection”:[“1; mode = block”],“日期”:[“2024 年 4 月 12 日星期五 19:10:34 GMT”],“Content-Length”:[“72”],“服务器”:[“Caddy”],“Cache-Control”:[“no-store”],“Content-Type”:[“application / json”],“X-Content-Type-Options”:[“nosniff”],“X-Frame-Options”:[“deny”]}}
到目前为止我已经尝试了两种不同的配置:
让 Fluent-bit 将日志发送到 Fluentd,然后 Fluentd 将日志转发给 Loki(标记为
caddy.log
)
架构:Cady --> Fluent-bit --> Fluentd --> Loki
让 Fluent-bit 发送日志直的至 Loki (标记为
caddy.log.loki
)
架构:Cady --> Fluent-bit --> Loki
这里我有以下 Fluent-bit 配置来发送日志到两个都Loki 和 Fluentd 同时使用,但具有不同的标签:
[INPUT]
Name tail
Path /var/log/caddy/*.log
Parser json
Tag caddy.log
Path_Key log_filename
# send logs to Fluentd
[OUTPUT]
Name forward
Host fluentd
Port 24224
Match caddy.*
# send logs straight to Loki
[OUTPUT]
name loki
match caddy.*
host loki
port 3100
labels job=caddy.log.loki
Fluentd 配置:
<source>
@type forward
</source>
<match caddy.*>
@type loki
url "http://loki:3100"
extra_labels {"job": "caddy.log"}
<buffer>
flush_interval 5s
flush_at_shutdown true
</buffer>
</match>
然后在 Grafana 中我可以浏览日志,并且在探索窗口中可以看到两个标签。
如果我选择标签,caddy.log.loki
日志将以纯 JSON 显示,如下所示。使用此表达式我可以解析它们:{job="caddy.log.loki"} | json
。提取一些嵌套的 JSON,例如:request_client_ip
但并非全部,例如request.headers
缺少了,但我可以忍受。
如果我选择标签,caddy.log
则日志将以“混合”格式显示:
似乎发生了一些转换,但我不确定在哪里。我可以用来logfmt
解析这些行。但我仍然留下一些未解析的字段(request
,resp_headers
),如下所示:
问题:
- 如果我添加 Fluentd 步骤,为什么日志不再以纯 JSON 形式呈现?
- 使用 Fluentd 在 Loki/Grafana 中传送和解析嵌套 JSON 日志的最佳方法是什么?
答案1
如果我添加 Fluentd 步骤,为什么日志不再以纯 JSON 形式呈现?
根据fluentd loki 输出插件文档,默认值为line_format
。key_value
你没有在配置中指定格式fluentd
,因此日志不是 JSON 格式,而是<key>=<value>
格式。
使用 Fluentd 在 Loki/Grafana 中传送和解析嵌套 JSON 日志的最佳方法是什么?
您可以尝试添加巢过滤您的fluentbit
配置:
[SERVICE]
parsers_file parsers.conf
[INPUT]
Name tail
Path /var/log/caddy/*.log
Parser json
Tag caddy.log
Path_Key log_filename
[FILTER]
Name nest
Match caddy.*
Operation lift
Nested_under request
# Nest filter can be chained
[FILTER]
Name nest
Match caddy.*
Operation lift
Nested_under headers
Add_prefix req_
[FILTER]
Name nest
Match caddy.*
Operation lift
Nested_under resp_headers
Add_prefix resp_
# send logs to Fluentd
[OUTPUT]
Name forward
Host fluentd
Port 24224
Match caddy.*
# send logs straight to Loki
[OUTPUT]
name loki
match caddy.*
host loki
port 3100
labels job=caddy.log.loki
结果:
请注意,没有参数的 LogQL json 解析器将跳过数组(https://grafana.com/docs/loki/latest/query/log_queries/#json),因此如果您想要带有数组的字段,则必须在参数中指定它,例如:
{job="caddy.log.loki"} |= `` | json request_user_agent=`["req_User-Agent"]`