linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • Симулятор
  • База знаний
  • Собеседование
Index
Categories
All entries
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
home/linux/kb/Observability и мониторинг/loki-grafana-logging

kb/observability ── Observability и мониторинг ── intermediate

Loki: label-based логи, LogQL, Promtail/Vector pipeline

Loki - log aggregation с label-based индексом (не full-text как Elastic). Дёшево на S3-storage. Promtail/Vector как агенты. LogQL похож на PromQL: фильтр + parse + aggregation. Cardinality - враг.

view as markdownaka: loki, logql, promtail, vector-loki, grafana-loki

Зачем Loki

Elasticsearch, full-text search всех полей log'а. Каждое слово индексируется. Стоимость:

  • 1 TB/день логов = ~30 GB/день RAM на heap (3-5× source size)
  • $30K/месяц ES cluster vs $5K/месяц для S3-Loki
  • Indexing latency, реальная боль на >100K events/s

Loki (Grafana Labs, 2018) перевернул подход:

  • Индексируется только labels (как в [[prometheus-basics|Prometheus]])
  • Сам log payload, compressed chunks на S3-compatible storage
  • Поиск = «выбор stream'ов по labels» + «grep по chunk'ам»
  • Дёшево, scale почти бесконечный

Trade-off: полно-текстовый поиск медленнее, но 95% запросов в observability, {service=X, level=error} |= "timeout", что Loki обрабатывает быстро.

Архитектура

┌─────────┐  push      ┌──────────┐  write     ┌─────────┐
│ Promtail│ ─────────► │  Loki    │ ─────────► │   S3    │
│ (agent) │            │ (server) │            │ (chunks)│
└─────────┘            └──────────┘            └─────────┘
┌─────────┐  push           ▲                       ▲
│  Vector │ ────────────────┘                       │
└─────────┘                                         │
     ▲                                              │
     │ tail files / journald / docker         read  │
     │                                              │
┌────┴────┐                                  ┌──────┴───┐
│ /var/log│                              ◄── │  Grafana │
└─────────┘                                  └──────────┘
                                               LogQL query

Components Loki в кластере:

  • distributor, принимает push, hashing
  • ingester, буферизует chunks в RAM, flush на S3 каждые 10-30 мин
  • querier, читает chunks с S3 + ingester для recent
  • query-frontend, splits большие queries, кэширует
  • compactor, мерджит index'ы, retention enforcement

Stream и labels

Stream в Loki = уникальная комбинация labels:

{service="api", env="prod", host="node-12", level="info"}

Каждый stream, отдельный chunked-file на S3. Внутри stream, log lines в порядке времени.

Подобно [[metric-types|Prometheus series]], кардинальность = product unique values каждого label. >10K активных streams в одном tenant → деградация. Опасные labels:

  • request_id (миллионы), никогда
  • user_id, никогда, в payload пиши
  • pod_name (k8s), может быть тысячи, OK с retention
  • host, десятки-сотни, OK
  • level, 4-5 значений, идеально

Правило: labels = низкая кардинальность, остальное, в log line.

LogQL, query language

PromQL-like, но на логах.

Stream selector + line-filter:

{service="api", env="prod"} |= "error"
{service="api"} |~ "timeout|refused"          # regex
{service="api"} != "healthcheck"              # exclude
{service=~"api.*"} | json | level="error"     # parse JSON

Operators:

OpЧто делает
|=line contains substring
\!=line not contains
|~line matches regex
\!~line not matches regex

Parsers (после |):

  • json, парсит JSON, поля доступны как level, user_id, etc
  • logfmt, для key=value логов
  • regexp, | regexp "(?P<status>\d+)"
  • pattern, | pattern "<_> [<level>] <msg>"
  • unpack, для Fluentbit-обёрнутых

Metrics из логов (Loki как time-series):

rate({service="api"} |= "error" [5m])              # error rate в req/s
sum by (status)(count_over_time({service="api"} | json [1m]))

Это дёшево, Loki считает на лету без индекса. Используется в alerting когда метрика отсутствует (alerting-rules-alertmanager).

Promtail, Loki-native agent

Discovers log files, парсит, добавляет labels, пушит:

yaml
scrape_configs:
  - job_name: system
    static_configs:
      - targets: [localhost]
        labels:
          job: varlogs
          __path__: /var/log/*.log
  - job_name: containers
    docker_sd_configs:
      - host: unix:///var/run/docker.sock
    relabel_configs:
      - source_labels: ['__meta_docker_container_name']
        regex: '/(.*)'
        target_label: container
      - source_labels: ['__meta_docker_container_log_stream']
        target_label: stream
    pipeline_stages:
      - cri: {}
      - json:
          expressions: {level: level, msg: msg, trace_id: trace_id}
      - labels:
          level:
      - structured_metadata:
          trace_id:

pipeline_stages, преобразование log line. structured_metadata (Loki 2.9+), поля без cardinality cost (trace_id, request_id), searchable но не индексируется как label. Решение проблемы high-card identifiers.

Vector, alternative agent

Vector (Datadog, opensource), более мощный pipeline:

toml
[sources.in]
type = "kubernetes_logs"
[transforms.parse]
type = "remap"
inputs = ["in"]
source = '''
. = parse_json!(.message) ?? .
.level = downcase(string!(.level))
'''
[sinks.loki]
type = "loki"
inputs = ["parse"]
endpoint = "http://loki:3100"
labels = {service = "{{ kubernetes.container_name }}", level = "{{ level }}"}
remove_label_fields = true

Vector умеет:

  • Multi-sink: одновременно Loki + S3 + Kafka
  • VRL (Vector Remap Language), JS-like для парсинга
  • Backpressure handling: disk-buffered queue
  • Sampling, filtering до отправки

Используй Vector если pipeline сложный или нужны несколько backend'ов.

Retention и storage

Loki стоимость почти 100%, S3 storage. Расчёт:

  • 1 GB/день logs → compressed ~100-200 MB chunks
  • 90d retention → ~15 GB на S3 → $0.35/мес (S3 standard)
  • Index ~5% от chunks: $0.02/мес

Total: <$1/мес для ~100 GB logs. Сравни с Datadog ($1.27/GB/мес).

Конфиг retention:

yaml
limits_config:
  retention_period: 90d
compactor:
  retention_enabled: true
  retention_delete_delay: 2h

Sizing rules of thumb

  • 1 TB/day ingest = 3 ingester + 2 querier + S3
  • Ingester RAM ≈ chunks_in_flight × 1.5 MB
  • Compactor, 1-2 vCPU, не нагружен
  • Index lookup в querier, fast, бутылочное горлышко обычно chunk-fetch

Loki vs Elastic vs ClickHouse

КритерийLokiElasticClickHouse
Indexlabel-onlyfull-textcolumnar
StorageS3 (cheap)local SSDlocal/S3
Cost @ 1TB/day~$5K/мес~$30K/мес~$10K/мес
Full-text speedсреднеvery fastfast (with skip-index)
AggregationsLogQL metricsaggregations APISQL
Multi-tenancyyesчерез indexчерез DB

ClickHouse-based (SigNoz, Quickwit), компромисс: дешевле Elastic, быстрее Loki на full-text. Растёт в популярности.

Когда что-то пошло не так

  • Cardinality explosion, десятки тысяч streams. loki-canary показывает active streams. Удали dynamic labels. См. cardinality-explosion.
  • Logs не приходят, Promtail logs (journalctl -u promtail): auth failure, network, disk full в /tmp.
  • «too many outstanding requests», query frontend rate-limit. Сужай range, добавляй labels selector.
  • entry too far behind, log line > max_line_size (default 256 KB). Truncate в agent или подними limit.
  • Search возвращает 0 хотя логи есть, wrong tenant header (X-Scope-OrgID), или label selector не матчится. Проверь {__path__=~".+"}.
  • Loki OOM на ingester, chunks_per_user_per_target превышен. Уменьшай interval flush'а или растяни retention в memory.
  • Promtail отстаёт от логов, disk-IO на read; кубер pod logs rotated. Используй Vector с persistent buffer.

§ команды

bash
logcli query '{service="api"} |= "error"' --limit 50 --since 1h

Loki CLI - 50 последних error-line за час из service=api

bash
logcli query 'sum by (level)(count_over_time({service="api"} | json [1m]))' --limit 5

Metrics из логов - count by level за минуту, как в Prometheus

bash
curl -s 'http://loki:3100/loki/api/v1/labels' | jq

Все labels в системе - первый шаг диагностики cardinality

bash
curl -s 'http://loki:3100/loki/api/v1/label/service/values' | jq

Все значения label 'service' - сколько уникальных streams

bash
promtail -config.file=/etc/promtail/config.yaml -log.level=debug

Promtail в debug-режиме - видно какие файлы tail и куда push

bash
journalctl -u promtail -n 100 -f

Live логи самого Promtail - типичный source ошибок ingestion

bash
vector validate /etc/vector/vector.toml

Валидация Vector config до запуска - в CI

§ см. также

  • prometheus-basicsPrometheus: scrape, TSDB, PromQL и production-pitfallsPrometheus - сервер мониторинга: сам опрашивает приложения по HTTP, собирает числовые метрики, хранит во встроенной БД ~15 дней. По ним строят графики в Grafana и алерты через Alertmanager. Стандарт de-facto в Kubernetes.
  • cmd-journalctljournalctl - журнал systemd`journalctl` читает binary-журнал systemd-journald. Это центральный лог системы: kernel, systemd-сервисы, syslog - всё через один интерфейс.
  • auditdauditd - syscall и file auditauditd пишет события ядра в /var/log/audit/audit.log: file watches (-w), syscall rules (-a), exec'и. ausearch для поиска, aureport для отчётов. Основа compliance (PCI-DSS, HIPAA, ФЗ-152).
  • tracing-basicsDistributed tracing: span, context propagation, samplingTracing - граф spans (parent-child) одного логического запроса через сервисы. Context передаётся HTTP-header traceparent (W3C). Sampling: head (на edge, дёшево) или tail (в Collector, точнее). Backend: Jaeger, Tempo, Zipkin.
  • cardinality-explosionCardinality explosion: как убить Prometheus и как чинитьCardinality = uniq(metric × labels). Каждый series ≈ 3 KB RAM, 10M series = 30 GB RAM, Prom OOM-цикл. Source: user_id-labels, пути с ID, dynamic version. Diag - topk по __name__. Cure - drop labels через relabel или нормализация в коде.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки