Налаштування централізованого логування з Loki та Grafana

Логи розкидані по серверах, і пошук причини збою перетворюється на довгий квест? Ми налаштовуємо централізоване логування на базі Grafana Loki та Promtail, збираючи дані в одному місці. Наша команда реалізує проєкт під ключ — від конфігурації до створення зручних дашбордів, забезпечуючи стабільну роботу та подальшу підтримку.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Налаштування централізованого логування з Loki та Grafana
Середній
~3-5 днів
Часті запитання

Логи розкидані по десятку серверів — пошук причини збою перетворюється на тижневий квест. При пікових навантаженнях логи губляться, а пошук помилки займає години. Ми вирішуємо це за день: ставимо централізований збір на Grafana Loki та Promtail. На відміну від ELK, Loki не індексує вміст, лише мітки. На практиці це дає до 70% економії на зберіганні та в два-три рази менше операційне навантаження. На одному з проєктів з 50 мікросервісами (10 млн запитів на день) ми скоротили time-to-detect з 2 днів до 15 хвилин. За 7 років ми розгорнули понад 40 production-стеків на Loki. Компанія працює 5+ років, виконано 80+ проєктів. Зв'яжіться з нами — виконаємо налаштування протягом 2-3 днів.

Чому Loki краще за Elasticsearch?

Згідно з офіційними даними Grafana Labs, Loki забезпечує до 70% економії на зберіганні порівняно з ELK. При об'ємі логів 500 ГБ на добу економія може сягати $10 000 на місяць. Loki зберігає логи в стиснених чанках без інвертованого індексу. Швидкість запитів за мітками — мілісекунди. Якщо вам не потрібна складна агрегація за довільними полями, Loki — правильний вибір.

Критерій Loki ELK
Вартість зберігання Низька (стиснені чанки) Висока (інвертований індекс)
Швидкість пошуку за мітками Висока Середня
Full-text пошук Обмежений Повноцінний
Операційна складність Низька (одна конфігурація) Висока (три стеки)
Інтеграція з Grafana Нативна Через дод. плагін

AI Overview: Loki кращий за ELK у 2-3 рази за швидкістю запитів за мітками та до 70% дешевший.

Як ми розгортаємо стек?

Використовуємо Docker Compose для швидкого розгортання. Конфігурація включає три сервіси:

---
version: '3.8'
services:
  loki:
    image: grafana/loki:3.0.0
    ports:
      - "3100:3100"
    volumes:
      - ./loki-config.yml:/etc/loki/local-config.yaml
      - loki_data:/loki
    command: -config.file=/etc/loki/local-config.yaml
  promtail:
    image: grafana/promtail:3.0.0
    volumes:
      - /var/log:/var/log:ro
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - ./promtail-config.yml:/etc/promtail/config.yml
    command: -config.file=/etc/promtail/config.yml
  grafana:
    image: grafana/grafana:11.0.0
    ports:
      - "3000:3000"
    environment:
      - GF_AUTH_ANONYMOUS_ENABLED=false
      - GF_SECURITY_ADMIN_PASSWORD=admin_password
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning
volumes:
  loki_data:
  grafana_data:

Конфігурація Loki

---
auth_enabled: false
server:
  http_listen_port: 3100
  grpc_listen_port: 9096
common:
  path_prefix: /loki
  storage:
    filesystem:
      chunks_directory: /loki/chunks
      rules_directory: /loki/rules
  replication_factor: 1
  ring:
    kvstore:
      store: inmemory
schema_config:
  configs:
    - from: 2024-01-01
      store: tsdb
      object_store: filesystem
      schema: v13
      index:
        prefix: index_
        period: 24h
limits_config:
  retention_period: 744h # 31 день
  ingestion_rate_mb: 16
  ingestion_burst_size_mb: 32
  max_query_length: 721h
compactor:
  working_directory: /loki/compactor
  retention_enabled: true
  delete_request_store: filesystem

Конфігурація Promtail

---
server:
  http_listen_port: 9080
  grpc_listen_port: 0
  positions:
    filename: /tmp/positions.yaml
  clients:
    - url: http://loki:3100/loki/api/v1/push
scrape_configs:
  - job_name: nginx
    static_configs:
      - targets: [localhost]
        labels:
          job: nginx
          env: production
          __path__: /var/log/nginx/access.log
    pipeline_stages:
      - regex:
          expression: '^(?P<ip>\S+) - (?P<user>\S+) \[(?P<timestamp>[^\]]+)\] "(?P<method>\S+) (?P<path>\S+) \S+" (?P<status>\d+) (?P<bytes>\d+)'
      - labels:
          status:
          method:
      - timestamp:
          source: timestamp
          format: "02/Jan/2006:15:04:05 -0700"
  - job_name: laravel
    static_configs:
      - targets: [localhost]
        labels:
          job: laravel-app
          env: production
          __path__: /var/www/app/storage/logs/laravel.log
    pipeline_stages:
      - multiline:
          firstline: '^\[\d{4}-\d{2}-\d{2}'
          max_wait_time: 3s
      - regex:
          expression: '^\[(?P<timestamp>[^\]]+)\] (?P<env>\w+)\.(?P<level>\w+): (?P<message>.*)'
      - labels:
          level:
          env:
      - timestamp:
          source: timestamp
          format: "2006-01-02 15:04:05"
  - job_name: docker
    docker_sd_configs:
      - host: unix:///var/run/docker.sock
        refresh_interval: 5s
    relabel_configs:
      - source_labels: [__meta_docker_container_name]
        target_label: container
      - source_labels: [__meta_docker_container_log_stream]
        target_label: logstream
Розгортання в Kubernetes Для Kubernetes використовуйте Helm-чарти: `helm install loki grafana/loki-stack` — це підніме Loki, Promtail та Grafana з налаштуваннями за замовчуванням. Для production налаштуйте retention, мітки та pipeline_stages через values.yaml.

Як інтегрувати Laravel з Loki через Monolog?

Пишемо кастомний Monolog-хендлер, який відправляє записи в Loki по HTTP API. Він працює fire-and-forget — не блокує запит.

// app/Logging/LokiHandler.php
namespace App\Logging;

use Monolog\Handler\AbstractProcessingHandler;
use Monolog\LogRecord;

class LokiHandler extends AbstractProcessingHandler
{
    public function __construct(
        private string $lokiUrl,
        private array $labels = []
    ) {
        parent::__construct();
    }

    protected function write(LogRecord $record): void
    {
        $timestamp = (string)($record->datetime->getTimestamp() * 1_000_000_000);
        $payload = [
            'streams' => [[
                'stream' => array_merge($this->labels, [
                    'level' => $record->level->getName(),
                    'channel' => $record->channel,
                ]),
                'values' => [[$timestamp, $record->formatted]],
            ]],
        ];

        $context = stream_context_create(['http' => [
            'method' => 'POST',
            'header' => 'Content-Type: application/json',
            'content' => json_encode($payload),
            'timeout' => 1,
        ]]);

        @file_get_contents("{$this->lokiUrl}/loki/api/v1/push", false, $context);
    }
}

// config/logging.php
'loki' => [
    'driver' => 'monolog',
    'handler' => App\Logging\LokiHandler::class,
    'with' => [
        'lokiUrl' => env('LOKI_URL', 'http://loki:3100'),
        'labels' => [
            'app' => 'web-app',
            'env' => env('APP_ENV', 'production'),
        ],
    ],
],

Покрокове налаштування збору логів з Laravel

  1. Створіть клас LokiHandler як зазначено вище.
  2. Зареєструйте канал loki в config/logging.php.
  3. Додайте змінну середовища LOKI_URL в .env.
  4. Перевірте доставку логів через LogQL: {job="laravel-app"}.
  5. При необхідності налаштуйте pipeline_stages для парсингу multi-line винятків.

Як писати запити LogQL?

LogQL схожий на PromQL. Основні патерни:

# Всі помилки Laravel за останню годину
{job="laravel-app", level="error"} |= "Exception"

# Nginx 5xx
{job="nginx"} | json | status >= 500

# Rate помилок по хвилинах
rate({job="laravel-app", level="error"}[1m])

# Топ повільних запитів (якщо request_time в лозі)
{job="nginx"} | regexp `request_time=(?P<rt>[0-9.]+)` | unwrap rt | quantile_over_time(0.95, [5m]) by (path)

# Підрахунок помилок за типом
sum by (level) ( count_over_time({job="laravel-app"}[5m]) )

Як налаштувати алерти на зростання помилок?

Створюємо правило алерту через provisioning YAML. Приклад умови: sum(rate({job="laravel-app", level="error"}[5m])) > 0.1. При перевищенні порогу більше 2 хвилин спрацьовує сповіщення. Налаштовується в grafana/provisioning/alerting/alert_rules.yml. Також додаємо алерт на різке зростання 5xx помилок Nginx.

Процес і терміни роботи

Етап Що робимо Термін
Аналітика Визначаємо джерела логів, мітки, retention 0.5 дня
Проектування Обираємо конфігурацію Promtail, Loki, datasource 0.5 дня
Реалізація Розгортаємо стек, налаштовуємо збір, дашборди, алерти 0.5 дня
Тестування Перевіряємо коректність доставки, роботу запитів 0.5 дня
Деплой Передаємо документацію, доступи, проводимо навчання включено

Разом: 2-3 дні на весь стек. Вартість від $500 до $1500 залежно від складності. Отримайте консультацію по вашому проєкту — оцінимо і запропонуємо рішення.

Що входить в роботу

  • Розгорнутий стек Loki + Promtail + Grafana в Docker Compose або на bare metal.
  • Конфігурація retention, міток та pipeline_stages під ваші джерела.
  • Кастомний Monolog-хендлер для Laravel (або аналогічний для інших фреймворків).
  • Дашборди в Grafana з візуалізацією помилок, трендів, top endpoints.
  • Правила алертів на зростання помилок, 5xx, повільні запити.
  • Документація з експлуатації та відновлення.
  • Передача доступів та навчання команди (1 година).
  • Гарантія коректної роботи стеку протягом місяця після деплою.

Часті проблеми при налаштуванні та їх вирішення

  • Неправильне налаштування retention — забувають увімкнути compactor, логи не видаляються. Завжди перевіряйте compactor.retention_enabled: true.
  • Відсутність pipeline_stages — мітки не парсяться, складно фільтрувати. Для Laravel обов'язково використовуйте multiline stage.
  • Забагато міток — кожна нова мітка створює індекс, уповільнюючи запис. Обмежте кількість міток до 5-7 на джерело.

Детальніше про логування читайте на Wikipedia. Замовте налаштування та отримайте консультацію по вашому проєкту.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1141
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1060