Meu laboratório possui alguns contêineres Docker como segue:
nome | Imagem do Docker |
---|---|
Fluente | fluente/fluente:v1.16-1 |
Fluente | cr.fluentbit.io/fluent/fluent-bit |
Loki | grafana/loki |
Grafana | grafana/grafana-empresa |
Caddie | caddie: construtor |
Meu objetivo é coletar logs do Caddy e visualizá-los no Grafana.
Cenário: O Fluent-bit segue os logs e os envia para o Fluentd. Em seguida, o Fluentd envia os logs para o Loki. Meu objetivo é usar o Fluentd como coletor central de logs.
O problema é a análise desses logs do lado do Grafana.
Os logs do Caddy estão no formato JSON (aninhado). Amostra:
{"level":"info","ts":1712949034.535184,"logger":"http.log.access.log1","msg":"solicitação tratada","request":{"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"],"Origem":["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"],"Aceitar":["aplicativo /json, texto/simples, */*"],"X-Grafana-Org-Id":["1"],"Connection":["keep-alive"],"Accept-Language":["en-US,en;q=0.5"],"Aceitar -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-Device-Id":["f343e938e74b3a57997faff69d24de8a"],"Cookie":[]}},"bytes_read":580,"user_id":"","duration":0.011267887,"size":72,"status":200,"resp_headers":{"X-Xss-Protection":["1; mode=block"],"Data ":["Sexta-feira, 12 de abril de 2024 19:10:34 GMT"],"Content-Length":["72"],"Servidor":["Caddy"],"Cache-Control":["no- store"],"Content-Type":["application/json"],"X-Content-Type-Options":["nosniff"],"X-Frame-Options":["deny"]}}["Caddy"],"Cache-Control":["no-store"],"Content-Type":["application/json"],"X-Content-Type-Options":["nosniff"], "Opções de quadro X":["deny"]}}["Caddy"],"Cache-Control":["no-store"],"Content-Type":["application/json"],"X-Content-Type-Options":["nosniff"], "Opções de quadro X":["deny"]}}
Eu tentei duas configurações diferentes até agora:
Faça com que o Fluent-bit envie os logs para o Fluentd e, em seguida, o Fluentd encaminhe os logs para o Loki (marcado como
caddy.log
)
. Esquema:Cady --> Fluent-bit --> Fluentd --> Loki
Faça com que o Fluent-bit envie os logs diretamente para o Loki (marcado como
caddy.log.loki
)
Esquema:Cady --> Fluent-bit --> Loki
Aqui eu tenho a seguinte configuração do Fluent-bit para enviar logs para Loki e Fluentd ao mesmo tempo, com tags diferentes:
[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
Configuração do 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>
Depois, no Grafana, posso navegar pelos logs e tenho os dois rótulos disponíveis na janela Explorar.
Se eu escolher a tag, caddy.log.loki
os logs serão exibidos em JSON simples, conforme mostrado abaixo. Com esta expressão posso analisá-los: {job="caddy.log.loki"} | json
. Parte do JSON aninhado é extraído, por exemplo: request_client_ip
mas nem todo , por exemplo, request.headers
está faltando, mas posso conviver com isso.
Se eu escolher a tag caddy.log
, os logs serão exibidos em formato "misto":
Parece que ocorreu alguma transformação, mas não tenho certeza de onde. Posso usar logfmt
para analisar as linhas. Mas ainda fico com alguns campos não analisados ( request
, resp_headers
) conforme mostrado abaixo:
Questões:
- por que os logs não são mais renderizados em JSON simples se eu adicionar a etapa Fluentd?
- qual seria a melhor maneira de enviar e analisar logs JSON aninhados em Loki/Grafana com Fluentd?
De acordo com os documentos do plugin de saída fluentd loki , o padrão
line_format
ékey_value
. Você não especificou o formato em suafluentd
configuração, portanto os logs não estão em JSON, mas em<key>=<value>
formato.Você pode tentar adicionar o filtro Nest à sua
fluentbit
configuração:Resultado:
Observe que o analisador LogQL json sem parâmetros irá pular arrays ( https://grafana.com/docs/loki/latest/query/log_queries/#json ), então se você quiser campos com arrays você deve especificá-los nos parâmetros, por exemplo: