# 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/uk/kb/s3-oblachnoe-khranilishche-sravnenie/).

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

## Підсумок: чекліст запуску Loki

Централізовані логи заощаджують години пошуку під час інцидентів, якщо стек налаштований з самого початку правильно, а не збирається нашвидкуруч після першого збою.

- Loki для зберігання, Promtail на кожному сервері, Grafana для запитів
- Мітка `host` обов'язкова на кожному джерелі логів
- У мітки — лише стабільні значення, решта — у текст логу
- Параметр retention налаштований явно, а не залишений за замовчуванням

---

Джерело: https://www.zevshost.net/uk/kb/grafana-loki-logi/
