📜 Grafana Loki

Логи по меткам: LogQL, promtail, метки, фильтры и метрики из логов.

Шпаргалки · Инфраструктура · #loki #grafana #logs #observability

Идея

Loki индексирует только метки (labels), а текст логов хранит сжатыми блоками. Дёшево и просто, как Prometheus, но для логов. Просмотр в Grafana (Explore). Сборщики: Promtail, Grafana Alloy, Fluent Bit, Vector.

LogQL: выбор потока

{app="api"}
{app="api", env="prod"}
{app=~"api|web", env!="dev"}       # регулярка и исключение

Операторы меток: =, !=, =~, !~.

Фильтры по тексту

{app="api"} |= "error"             # содержит
{app="api"} != "healthcheck"       # не содержит
{app="api"} |~ "timeout|refused"   # регулярка
{app="api"} |= "error" != "debug"

Разбор строк

{app="api"} | json                              # поля из JSON
{app="api"} | json | status >= 500
{app="api"} | logfmt | level="error"
{app="api"} | pattern "<ip> - <_> <method> <path>"
{app="api"} | regexp "(?P<code>\\d{3})"
{app="api"} | line_format "{{.level}} {{.msg}}"

Метрики из логов

rate({app="api"} |= "error" [5m])                       # ошибок в секунду
sum by (status) (count_over_time({app="api"} | json [1m]))
topk(5, sum by (path) (rate({app="api"} | json [5m])))

Promtail (фрагмент)

server: { http_listen_port: 9080 }
clients: [{ url: http://loki:3100/loki/api/v1/push }]
scrape_configs:
  - job_name: app
    static_configs:
      - targets: [localhost]
        labels: { job: app, env: prod, __path__: /var/log/app/*.log }

Приёмы

  • Метки должны иметь мало значений (сервис, окружение). Не делайте меткой ID пользователя или IP: взрывается кардинальность.
  • Порт 3100 (HTTP API), готовность /ready.
  • Связь логов и трейсов: в Grafana задайте derived fields с trace_id ссылкой на Tempo.