---
title: 'Спостережуваність: логи, метрики та здоров’я для Laravel та мікросервісів | DevSense'
description: 'Як моніторити стан застосунку під навантаженням: структуроване логування, метрики, трасування, correlation ID між сервісами та спектр інструментів від syslog до Prometheus, Loki, OpenTelemetry та APM.'
faq:
    - { question: 'В чому різниця між рівнем логування (log level) та контекстом логу (log context)?', answer: "Рівень логування (наприклад, DEBUG, INFO, WARNING, ERROR) класифікує важливість повідомлення для фільтрації логів у продакшені. Контекст логу — це структуровані метадані (масиви з ID користувача, ID запиту, часом виконання), прикріплені до запису, що дозволяють автоматизовано індексувати та пов'язувати логи без парсингу тексту." }
    - { question: 'Чому метрики з надвисокою унікальністю значень (high-cardinality) небезпечні для Prometheus?', answer: "Prometheus зберігає метрики як записи у часовій базі даних. Кожна унікальна комбінація міток (labels) створює новий часовий ряд. Запис високодетальних параметрів (наприклад, ID користувачів або повні URL-адреси) призводить до «вибухового зростання кількості рядів», що переповнює оперативну пам'ять сервера Prometheus." }
    - { question: 'Як розподілене трасування передає контекст між мікросервісами?', answer: 'Розподілене трасування використовує HTTP-заголовки (такі як `X-Request-Id` або стандарт W3C `traceparent`) для передачі унікального ID трасування (trace ID) та ID поточного кроку (span ID). Кожна мікрослужба в ланцюжку витягує цей заголовок, логує його та передає далі у зовнішніх HTTP-запитах або заголовках черг.' }
    - { question: 'Чому Laravel Telescope потрібно відключати в продакшені?', answer: 'Laravel Telescope записує детальний контекст кожного запиту, SQL-запити та логи безпосередньо в базу даних. У високонавантаженому продакшені цей оверхед на запис даних знижує загальну продуктивність застосунку, перевантажує основну базу даних та швидко вичерпує дисковий простір.' }
published: '2026-05-31'
---
# Спостережуваність: логи, метрики та перевірка здоров’я у монолітах та мікросервісах на Laravel

Фраза «на моїй машині все працює» — це не стратегія моніторингу. У продакшені системи ламаються **цілком конкретними способами**: переповнюється диск, зростає затримка в чергах, відвалюється зовнішнє API за таймаутом або одна з реплік віддає застарілі дані. Правильно побудована спостережуваність (observability) дозволяє швидко зрозуміти: **що змінилося**, **у кого саме** та **на якому кроці стався збій** — без необхідності підключатися по SSH до кожного сервера. Ці принципи однакові як для моноліту на **Laravel**, так і для **сотні мікросервісів**; змінюються лише **інструменти** та **складність інтеграції**.

**Пов’язані матеріали:** [PHP: пул з’єднань до БД](php-database-connection-pooling) · [Бази даних під навантаженням](database-performance-and-scaling) · [API-шлюзи та обмін повідомленнями](../microservices/api-gateway)

## Зміст

* [Три стовпи: логи, метрики, трасування](#pillars)
* [Розбіжності за оточеннями](#environments)
* [Моноліт на Laravel: практичні шари](#monolith)
* [Мікросервіси: кореляція та трасування](#microservices)
* [Спектр інструментів: від класики до сучасності](#tools)
* [Під навантаженням: семплювання, кардинальність, вартість](#load)
* [Алерти, які люди будуть поважати](#alerting)
* [Часті помилки](#common-mistakes)
* [Чеклист](#checklist)
* [Квіз для самоперевірки](#self-test-quiz)

---

<a id="pillars"></a>
## Три стовпи: логи, метрики, трасування

| Стовп | Що пояснює | Типові помилки |
|--------|---------|------------------|
| **Логи** | *Що сталося покроково?* (помилки, аудит, контекст налагодження) | Неструктурований текст, який неможливо відфільтрувати; логування секретів; **INFO**-флуд у продакшені |
| **Метрики** | *Скільки, як швидко, порівняно з учорашнім днем?* | Мітки з **високою кардинальністю** (ID користувача або повний URL у кожній метриці); графіки, на які ніхто не дивиться |
| **Трасування** | *Яка ланка в ланцюжку запитів гальмує?* | Відсутність **передачі контексту** (correlation ID), через що мікросервіс Б «не знає», що його запис викликаний запитом А |

Ці елементи доповнюють один одного: **всплеск помилок** (метрика) вказує на конкретний інтервал часу, за яким ви знаходите **пов'язані логи** та **слід (trace)** повільної транзакції. Жоден зі стовпів не замінює інші.

---

<a id="environments"></a>
## Розбіжності за оточеннями

* **Локальне оточення / розробка** — максимум **швидкості розробки**: `tail` логу, Telescope, докладне виведення помилок на екран, брейкпоінти. **Не переносьте** цей рівень деталізації у продакшн без змін.
* **Staging / pre-prod** — копіює продакшн-інфраструктуру логування та дашбордів (по можливості), щоб виявляти помилки класу «все працювало, поки ми не ввімкнули JSON-логування в Loki».
* **Production** — оптимізація під **сигнал**, **вартість зберігання** та **безпеку**: структуровані логи без персональних даних, семплювання налагодження, **health checks**, що відображають реальний стан залежностей.

> [!NOTE]
> **Принцип сумісності контрактів**
> Мета полягає не у використанні абсолютно однакових інструментів усюди, а в **сумісності контрактів** (однакові імена полів correlation ID, однакові імена ключових метрик), щоб при інциденті розробникам не доводилося перевчитися.

---

<a id="monolith"></a>
## Монолит на Laravel: практичні шари

### Логування застосунку

* Використовуйте канали в **`config/logging.php`**: `stack`, `daily`, `syslog` або виведення в stdout у форматі **JSON**, щоб контейнери могли агрегувати логи.
* Віддавайте перевагу **структурованим полям** (масив `context`), а не склеюванню текстових рядків.
* Прикріплюйте **request id**, **user id** (якщо дозволено політикою), **queue job id** — все, що допоможе зв'язати один рядок логу з рештою історії.

Приклад налаштування каналу логування:
```php
// config/logging.php
'channels' => [
    'stack' => [
        'driver' => 'stack',
        'channels' => ['daily'],
        'ignore_exceptions' => false,
    ],
    // ...
],
```

Використання в коді:
```php
// app/Http/Controllers/OrderController.php
Log::info('Order processed successfully', [
    'order_id' => $order->id,
    'user_id' => auth()->id(),
    'execution_time_ms' => $timeMs,
]);
```

### Життєвий цикл запиту (Request lifecycle)

* Middleware для **correlation id**: приймайте вхідний `X-Request-Id` або генеруйте його на льоту; повертайте його у відповідях; передавайте його у фонові завдання та вихідні HTTP-запити.
* Використання **`Log::withContext()`** у сучасних версіях Laravel допомагає зберегти наскрізний контекст запиту без ручної передачі параметрів.

### Черги та планувальник

* **Horizon** (Redis) надає **глибину черг, пропускну здатність, невдалі завдання** — ставтеся до цього як до первинного моніторингу, а не просто зручної адмінки.
* Завдання за розкладом: логуйте **старт/завершення/тривалість**; налаштовуйте алерти на **пропущені запуски** (через cron-heartbeat служби).

### Глибокий аналіз (не для продакшена)

* **Telescope** незамінний на **local/staging**; тримайте його **вимкненим** у продакшені, якщо у вас немає строгої фільтрації за IP/ролями та ви не боїтеся оверхеду на базу даних.
* **Laravel Pulse** показує **повільні запити, SQL-запити, завантаження черг** — але стежте за обсягом зібраних даних на навантажених системах.

### Здоров’я та готовність (Health and readiness)

* Ендпоінт **`/up` (Health)** у Laravel 11+: розділяйте поняття **liveness** («процес запущено») та **readiness** («застосунок готовий відповідати, база даних та кеш доступні»). Це критично для балансувальників та Kubernetes.

### Помилки як продукт

* **Sentry**, **Flare**, **Bugsnag** — групування стактрейсів, трекінг релізів та хлібні крихти. Вони доповнюють системні логи, але не замінюють **метрики завантаження системи**.

---

<a id="microservices"></a>
## Мікросервіси: кореляція та трасування

Коли один HTTP-виклик проходить ланцюжок **gateway → сервіс А → сервіс Б → брокер повідомлень → worker**, звичайний access-лог кожного сервісу окремо стає **марним**.

### Correlation ID

* Передавайте стабільний ідентифікатор при кожному вихідному виклику (`X-Request-Id` або стандарт **W3C `traceparent`**).
* Логуйте його на вході в **кожному** сервісі; передавайте в **асинхронних** повідомленнях (всередині payload завдання або заголовках брокера).

### Розподілене трасування

* **OpenTelemetry** — сучасний **вендоро-незалежний** стандарт для збору трасувань; агенти відправляють дані в **Jaeger**, **Tempo**, **Zipkin** або SaaS-рішення.
* Зрілість бібліотек в PHP-екосистемі різниться — перевіряйте **авто-інструментацію** для вашого HTTP-клієнта, драйвера БД та брокера черг. Частковий трейс все одно краще, ніж його повна відсутність.

### Межі сервісів

* Стандартизуйте політики **таймаутів, повторних спроб (retries) та ідемпотентності**. Моніторинг покаже «лавиноподібні ретраї», якщо кожен шар буде сліпо переотправляти запити.

---

<a id="tools"></a>
## Спектр інструментів: від класики до сучасності

### Рівень хоста та мережі

* **syslog**, **rsyslog**, **logrotate** — централізація текстових файлів; досі актуально як транспортний шар.
* **Nagios**, **Icinga**, **Zabbix** — базові перевірки хостів, ping, диски, RAM. Менше про логи застосунку, більше про інфраструктурний базис.

### Агрегація логів

* **ELK / Elastic Stack** (Elasticsearch, Logstash/Beats, Kibana) — потужний пошук за логами; вимагає зваженого підходу до адміністрування або бюджетів на SaaS.
* **Graylog**, **Splunk** (enterprise) — альтернативні рішення в цьому ж сегменті.

### Метрики та дашборди

* Збір метрик **Prometheus** + дашборди **Grafana** — стандарт де-факто для **Kubernetes** та віртуальних машин. **Alertmanager** для маршрутизації алертів.
* **VictoriaMetrics**, **Mimir**, **Thanos** — рішення для довгострокового зберігання метрик Prometheus.

### Логи «як метрики»

* **Grafana Loki** — зберігання логів на основі міток (labels). Дешевше в експлуатації порівняно з повноцінним індексуванням кожного слова в пошукових движках.

### Хмарні рішення

* **AWS CloudWatch**, **Google Cloud Logging/Monitoring**, **Azure Monitor** — нативні інструменти, якщо ваша інфраструктура повністю розгорнута в одного провайдера.

### SaaS «все в одному»

* **Datadog**, **New Relic**, **Honeycomb** — логи, метрики, APM, RUM; **швидкий старт**, але **оплата за обсяг** вимагає жорсткого контролю кардинальності даних.

### Помилки та APM для PHP

* **Sentry** (помилки + performance), **Scout**, **Tideways** (профайлінг PHP) — популярні інструменти в Laravel-спільноті.

### Хвиля стандартизації

* **OpenTelemetry (OTel)** — уніфіковані SDK та експортери. **Collector** може розподіляти дані по різних бекендах, запобігаючи прив'язці до одного вендора (lock-in).

---

<a id="load"></a>
## Під навантаженням: семплювання, кардинальність, вартість

* **Обсяг логів** зростає лінійно з трафіком. Логування кожного запиту в `DEBUG`-режимі у форматі JSON може споживати більше CPU, ніж сам застосунок. Використовуйте **рівні логів** та семплювання.
* **Мітки Prometheus**: ніколи не використовуйте **необмежені** значення (ID сесій, email, повні динамічні URL) як назви або значення міток — це призведе до **кардинального вибуху** метрик.
* **Семплювання трасувань**: зберігайте **100%** помилок та повільних запитів; звичайні успішні запити семплюйте (наприклад, зберігайте лише 1% або 5%).
* **Зберігання (Retention)**: розділяйте логи на **гарячі** (доступні відразу), **холодні** (у дешевому об'єктному сховищі для аудиту) та **ті, що видаляються**.

---

<a id="alerting"></a>
## Алерти, які люди будуть поважати

Налаштовуйте сповіщення на події, які впливають на користувачів або вказують на швидку відмову: **вигорання SLO (SLO burn)**, різке зростання **кількості помилок**, затримка в чергах **p95 (queue latency)**, критичний залишок **диска**, закінчення **SSL-сертифікатів**.

Уникайте алертів за «шумними» метриками, якщо до них немає чітких інструкцій (runbooks). «CPU > 80%» протягом 5 хвилин найчастіше **не** вимагає будити чергового; «**успішність платежів** впала на 15%» — вимагає негайно.

---

<a id="common-mistakes"></a>
## Часті помилки

1. **Мітки метрик з високою унікальністю (High-Cardinality)**: Додавання динамічних даних (наприклад, `user_id` або `email`) як лейблів для Prometheus, що призводить до перевитрати пам'яті та падіння моніторингу.
2. **Логування конфіденційних даних**: Запис масиву `$request->all()` при вході користувача, через що паролі, токени та персональні дані потрапляють у текстові логи.
3. **Залишений Telescope в продакшені**: Запис усіх SQL-запитів та запитів застосунку без очищення, що займає корисний дисковий простір та навантажує СУБД.
4. **Відсутність таймаутів на зовнішні виклики**: Запити до сторонніх сервісів без вказання ліміту часу очікування, через що воркери PHP-FPM зависають і швидко вичерпують пул процесів.

---

<a id="checklist"></a>
## Чеклист

1. **Структуровані логи** пишуться в stdout або лог-шиппер; використовується **один** correlation id для синхронних та асинхронних ланцюжків.
2. Відстежуються **Golden Signals** для кожного сервісу: latency, traffic, errors, saturation (плюс **глибина черг** для воркерів Laravel).
3. Ендпоінти перевірки **здоров’я** тестують **реальні** залежності; розділені **liveness** та **readiness** перевірки.
4. Помилки відстежуються через виділений інструмент (Sentry/Bugsnag); **Telescope** та аналоги доступні лише на не-прод оточеннях.
5. Проведена перевірка **вартості та кардинальності** перед включенням детальних логів та міток.

---

## Підсумок

Спостережуваність — це **частина продукту**: той самий код Laravel, який обслуговує користувачів, повинен надавати **докази** своєї коректної роботи та вказувати точне місце збою при його виникненні.

---

<a id="self-test-quiz"></a>
## Квіз для самоперевірки

### Запитання 1: У чому полягає основна небезпека додавання email користувачів як міток (labels) у метриках Prometheus?
- А) Prometheus не підтримує текстові значення в мітках.
- Б) Це призводить до вибухового зростання кількості часових рядів (cardinality explosion) та падіння сервера метрик.
- В) Це порушує політику безпеки протоколу HTTP.

<details>
<summary>Показати правильну відповідь</summary>

**Правильна відповідь: Б**
Кожен унікальний email створює новий часовий ряд у базі даних Prometheus. При зростанні кількості користувачів Prometheus швидко вичерпає оперативну пам'ять.
</details>

### Запитання 2: Для чого потрібна readiness-перевірка застосунку в Kubernetes або балансувальниках навантаження?
- А) Щоб переконатися, що процес сервера просто запустився.
- Б) Щоб перевірити, чи готовий застосунок обробляти трафік (наприклад, чи встановлені з'єднання з БД та кешем).
- В) Для логування повільних запитів.

<details>
<summary>Показати правильну відповідь</summary>

**Правильна відповідь: Б**
Readiness probe перевіряє готовність застосунку приймати користувацькі запити. Якщо перевірка не проходить, балансувальник тимчасово виключає вузол з розподілу трафіку.
</details>