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

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

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

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

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

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

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

Часті запитання

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

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1422
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1287
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    984
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1249
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    986
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    1000

Логи розкидані по десятку серверів — пошук причини збою перетворюється на тижневий квест. При пікових навантаженнях логи губляться, а пошук помилки займає години. Ми вирішуємо це за день: ставимо централізований збір на 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. Замовте налаштування та отримайте консультацію по вашому проєкту.