---
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>