# Grafana Loki: централизованный сбор логов с серверов

> Grafana Loki собирает логи с нескольких VDS в одном месте и ищет по ним через Grafana. Установка, Promtail, метки и примеры запросов LogQL.

Когда проект работает на трёх-пяти VDS, поиск нужной строки в логах превращается в обход серверов по SSH один за другим. Grafana Loki собирает логи со всех серверов в одно место и даёт искать по ним через тот же интерфейс Grafana, где уже смотрят метрики. Разберём установку Loki, агента Promtail и типичные запросы LogQL.

## Зачем нужен централизованный сбор логов и чем Loki отличается от ELK

Elasticsearch индексирует полный текст каждой строки лога, поэтому кластер ELK требует много памяти и диска даже на средних объёмах. Loki устроен иначе: он индексирует только метки (labels) — имя сервера, имя сервиса, уровень лога, — а сам текст хранит сжатым блоками. Поиск по меткам почти мгновенный, полнотекстовый поиск внутри найденных блоков чуть медленнее, зато инфраструктура для Loki требует в разы меньше ресурсов, чем для Elasticsearch.

Для парка из нескольких VDS с обычной нагрузкой это разумный компромисс: не нужен отдельный кластер из трёх узлов только под логи.

## Установка Loki на VDS через Docker Compose

Минимальный стек — Loki для хранения, Promtail для сбора и Grafana для просмотра — поднимается одним файлом:

```
services:
  loki:
    image: grafana/loki:3.1.0
    ports:
      - "3100:3100"
    volumes:
      - ./loki-data:/loki
    command: -config.file=/etc/loki/local-config.yaml

  grafana:
    image: grafana/grafana:11.1.0
    ports:
      - "3000:3000"
    volumes:
      - ./grafana-data:/var/lib/grafana
```

После `docker compose up -d` Loki принимает данные на порту 3100, а Grafana доступна на порту 3000 для настройки дашбордов и запросов.

## Promtail: сбор логов с серверов и отправка в Loki

Promtail ставится на каждый сервер, откуда нужны логи, читает файлы из `/var/log` и docker-контейнеров, добавляет метки и отправляет батчами в Loki. Конфиг агента:

```
server:
  http_listen_port: 9080

clients:
  - url: http://loki.internal:3100/loki/api/v1/push

scrape_configs:
  - job_name: nginx
    static_configs:
      - targets: ["localhost"]
        labels:
          job: nginx
          host: web-01
          __path__: /var/log/nginx/*.log
```

Метка `host` здесь критична: без неё в общем потоке логов с пяти серверов невозможно понять, откуда пришла конкретная строка.

## Настройка меток для быстрого поиска

В Loki важно не превращать в метку то, что часто меняется, — например, ID запроса или временную метку внутри строки. Каждое уникальное значение метки создаёт отдельный поток (stream), и тысячи уникальных значений превращают Loki в подобие того же Elasticsearch по нагрузке на индекс.

- В метки выносят стабильные значения: имя сервера, имя сервиса, окружение (prod/staging)
- ID запроса, email, IP-адрес ищут полнотекстовым запросом внутри уже отобранного потока, а не через метку
- Количество уникальных комбинаций меток держат в пределах нескольких сотен на инсталляцию

## Подключение Loki как источника данных в Grafana

В Grafana источник данных добавляется в разделе Connections → Data sources → Loki, URL указывается как `http://loki:3100` при общей Docker-сети. После сохранения логи ищутся во вкладке Explore тем же интерфейсом, что уже используют для графиков Prometheus.

## Запросы LogQL: примеры

LogQL сочетает выбор потока по меткам в фигурных скобках и фильтр по тексту после вертикальной черты:

```
{host="web-01", job="nginx"} |= "500"
{job="nginx"} | json | status >= 500
sum(rate({job="nginx"} |= "500" [5m])) by (host)
```

Первый запрос ищет строку "500" в логах nginx на конкретном сервере, второй разбирает JSON-лог и фильтрует по числовому полю status, третий считает частоту ошибок 500 в минуту по каждому серверу — удобно для алертов и дашбордов.

## Хранение и ротация логов

По умолчанию Loki хранит логи локально на диске без ограничения по времени, поэтому retention настраивают отдельно параметром `retention_period` в конфиге, иначе диск сервера рано или поздно заполнится. Для долгого архива логов свежие блоки можно выгружать в S3-совместимое хранилище — подробности в статье про [сравнение S3-провайдеров](https://www.zevshost.net/ru/kb/s3-oblachnoe-khranilishche-sravnenie/).

Сам стек Loki плюс Promtail плюс Grafana логично разворачивать рядом с уже настроенным [мониторингом Uptime Kuma](https://www.zevshost.net/ru/kb/uptime-kuma-monitoring/): метрики доступности и логи ошибок дополняют друг друга при разборе инцидента. Если серверов много и они объединены в [Docker Swarm](https://www.zevshost.net/ru/kb/docker-swarm-nastroika/), Promtail разворачивают как глобальный сервис на каждом узле кластера.

## Итог: чек-лист запуска Loki

Централизованные логи экономят часы поиска по инцидентам, если стек настроен с самого начала правильно, а не собирается на скорую руку после первого сбоя.

- Loki для хранения, Promtail на каждом сервере, Grafana для запросов
- Метка `host` обязательна на каждом источнике логов
- В метки — только стабильные значения, остальное — в текст лога
- Параметр retention настроен явно, а не оставлен по умолчанию

---

Источник: https://www.zevshost.net/ru/kb/grafana-loki-logi/
