Observability (Наблюдаемость)
Observability строится на трёх столпах: метрики (metrics), логи (logs) и трейсинг (traces). По отдельности каждый из них полезен, но вместе они дают полную картину. Observability не сводится к сбору данных — это культура проектирования системы с самого начала.
Observability: как понять, что происходит внутри системы
Вы выпустили систему в продакшен. Она работает. Но что именно она делает? Быстро ли отвечает? Не падает ли? Не теряет ли данные? Без инструментов наблюдения система — это чёрный ящик. Вы знаете, что что-то входит и что-то выходит, но не имеете понятия, что происходит внутри.
Observability (наблюдаемость) — это способность понять внутреннее состояние системы по её внешним проявлениям: логам, метрикам и трейсингу. Хорошо наблюдаемая система позволяет отвечать на вопрос “почему это произошло?” без развертывания нового кода или добавления дополнительных точек логирования.
Три столпа observability
1. Метрики (Metrics)
Метрики — это агрегированные числовые показатели, измеряемые с течением времени. В отличие от логов, которые описывают конкретные события, метрики дают суммарную картину: сколько запросов, как быстро, сколько ошибок.
Основные метрики для сервиса
| Категория | Метрика | Что измеряет |
|---|---|---|
| Нагрузка | RPS (Requests Per Second) | Количество HTTP/gRPC запросов в секунду |
| QPS (Queries Per Second) | Количество запросов к базе данных (SQL) | |
| TPS (Transactions Per Second) | Количество транзакций (например, Kafka producer) | |
| Производительность | Response time (latency) | Время ответа (p50, p95, p99 в миллисекундах) |
| Throughput | Количество обработанных байт/сообщений в секунду | |
| Качество | Errors rate | Доля запросов, завершившихся с ошибкой (HTTP 5xx, исключения) |
| Трафик | Traffic | Объём входящего/исходящего трафика (байты/сек) |
| Системные метрики | CPU usage | Процент использования CPU |
| RAM usage | Использование оперативной памяти | |
| HDD/SSD usage | Занято место на диске, IOPS, latency операций ввода-вывода | |
| Доступность | Uptime / Downtime | Время работы / время простоя с момента последнего запуска |
| Очереди | Queue size | Количество сообщений в очереди (RabbitMQ, Kafka lag) |
| Потоки | Thread count / Process count | Количество активных потоков в JVM/процессов в системе |
Как это выглядит в коде (пример с Prometheus + клиентской библиотекой):
from prometheus_client import Counter, Histogram
requests_total = Counter('http_requests_total', 'Total HTTP requests', ['method', 'endpoint'])
request_duration = Histogram('http_request_duration_seconds', 'Request duration', ['method', 'endpoint'])
@request_duration.time()
def handle_request(method, endpoint):
requests_total.labels(method=method, endpoint=endpoint).inc()
# логикаМетрики собираются, хранятся в TSDB (Prometheus, Graphite, InfluxDB) и визуализируются в дашбордах (Grafana). По ним строятся алерты: если p95 latency превысила 200 мс на 5 минут — отправляется уведомление дежурному инженеру.
Что аналитику нужно знать о метриках
- Собирайте их до инцидента. Нельзя добавить метрики после аварии, потому что тогда не будет исторических данных для сравнения.
- Различайте счётчики (counters) и датчики (gauges). Counters только увеличиваются (RPS, ошибки), Gauges могут увеличиваться и уменьшаться (размер очереди, CPU).
- Используйте процентили (p95, p99), а не среднее. Средняя latency может быть 50 мс, но 10% пользователей ждут по 5 секунд. p99 покажет это.
2. Логи (Logs)
Логи — это дискретные, структурированные записи о конкретных событиях: получен запрос, завершена обработка, произошла ошибка. Каждая запись содержит временную метку, сообщение и (в идеале) контекст.
Формат логов
Текстовые логи: 2025-01-15 10:30:00 ERROR Payment gateway timeout. Плохо поддаются автоматическому анализу.
Структурированные логи (JSON):
{
"timestamp": "2025-01-15T10:30:00Z",
"level": "ERROR",
"service": "payment-service",
"correlation_id": "123e4567-e89b-12d3-a456-426614174000",
"message": "Payment gateway timeout",
"payment_id": "pay_123",
"duration_ms": 3000
}Такой лог можно легко фильтровать по полю correlation_id, группировать по payment_id, строить гистограммы по duration_ms. Это обязательно для production.
Что логировать
- Входящие и исходящие запросы (логируйте метод, URL, статус, duration).
- Ошибки и исключения (с полным stacktrace — но не в поле
message, а в отдельном полеstacktrace). - Бизнес-события: “заказ создан”, “платёж выполнен”.
- Изменения состояния (переходы статуса заказа).
- Аутентификация и авторизация (кто, что делал, успешно или нет).
Централизованное логирование (ELK, Loki)
Логи с каждого сервера собираются в центральное хранилище (Elasticsearch, Loki), индексируются и становятся доступными для поиска. Это единственный способ искать логи по correlation_id в распределённой системе, когда запрос прошёл через пять сервисов.
Что аналитику нужно знать о логах
- Логи должны быть структурированными (JSON). Текстовые логи — это боль.
- Включайте correlation_id в каждую запись. Иначе вы не свяжете жалобу пользователя с логами инцидента.
- Уровни логирования: INFO (нормальный ход событий), WARN (проблемы, которые не требуют немедленного вмешательства), ERROR (требуют внимания инженера). Не логируйте всё на INFO, иначе тонны бесполезных записей скроют действительно важные ошибки.
3. Трейсинг (Traces)
Трейсинг показывает путь запроса через распределённую систему. Они связывают события в разных сервисах в одну цепочку и показывают, сколько времени занял каждый шаг.
Структура трейсинга
- Trace ID — уникальный идентификатор запроса (корреляция между сервисами).
- Span — одна операция в одном сервисе (HTTP вызов, SQL запрос, обработка сообщения). У каждого спана есть свой Span ID.
- Parent-child relationship — спаны могут быть вложенными, образуя дерево.
Пример визуализации (Jaeger, Zipkin):
Trace ID: 4bf92f35
├─ API Gateway (10 ms)
│ ├─ Order Service (45 ms)
│ │ ├─ Payment Service (30 ms)
│ │ └─ Inventory Service (12 ms)
│ └─ User Service (5 ms)Зачем нужен трейсинг
- Поиск узких мест. Трейсинг показывает, какой из вызовов самый долгий — внутренний сервис, БД или внешний API.
- Понимание зависимостей. Какие сервисы вызывают какие.
- Отладка задержек. Пользователь жалуется, что заказ оформляется 10 секунд — трейсинг покажет, где именно запрос зависал.
Инструменты: Jaeger, Zipkin, AWS X-Ray, Tempo.
Что аналитику нужно знать о трейсинге
- Требуют инструментации кода. Библиотеки для вашего языка (OpenTelemetry) автоматически создают спаны для HTTP, gRPC, SQL, но только если вы их настроили.
- Сэмплирование (sampling). Хранить 100% трейсинга слишком дорого. Обычно хранят 1-10% трейсинга + все ошибки (исключения).
- Трейсинг — лучшее дополнение к метрикам. Метрики показывают, что p95 latency выросла. Трейсинг показывают, почему: стал тормозить конкретный сервис.
Мониторинг: метрики, алерты и дашборды
Мониторинг — это процесс наблюдения за метриками и оповещения при их выходе за допустимые границы. Observability шире: она включает не только известные метрики, но и возможность задавать новые вопросы (ad-hoc query) по логам и трейсингу.
Основные метрики для сервиса (дополненный список)
| Группа | Метрика | Хорошее значение | Критическое значение |
|---|---|---|---|
| RPS | Запросов в секунду | Зависит от ёмкости | Превышение ёмкости на 80% → алерт |
| Response time (p99) | 99% запросов быстрее X мс | < 100 мс для чтения, < 500 мс для записи | > 200 мс (чтение), > 1000 мс (запись) |
| Errors rate | Доля 5xx ошибок | < 0.1% | > 1% |
| CPU | Загрузка процессора | < 70% | > 90% в течение 5 мин |
| RAM | Использование памяти | < 80% | > 90% |
| HDD/SSD | IOPS, latency, свободное место | < 10 мс latency, > 20% free | > 50 мс latency, < 10% free |
| Queue size | Количество сообщений в очереди | < 1000 (зависит от ёмкости) | > 10000 или рост без остановки (consumer отстаёт) |
| Uptime | Время работы процесса | > 7 дней | Перезапуск чаще раза в день |
| Thread count | Количество потоков в JVM/Go/Node | В пределах нормы (зависит от приложения) | Утечка потоков → постоянный рост |
Дашборды (Grafana)
Дашборды агрегируют метрики в одном месте (обычно Grafana). Аналитику не нужно знать, как их настраивать, но полезно уметь читать:
- Тренды нагрузки (RPS, CPU).
- Всплески ошибок и латентности (часто коррелируют).
- Карта здоровья сервисов (зелёный/красный).
Алерты
Алерты должны отправляться не на каждую аномалию, а только когда требуется действие человека. Плохой алерт: “CPU подскочил до 90% на 1 секунду”. Нормальный алерт: “p99 latency > 500 мс в течение 5 минут” — это уже инцидент.
Как три столпа работают вместе
Отдельно логи, метрики и трейсинг полезны, но по-настоящему мощны они в связке.
Сценарий: Метрики показывают, что p95 latency сервиса заказов выросла со 100 мс до 2 секунд.
- Вы идёте в трейсинг и видите, что запросы к сервису инвентаризации (внутри трейсинга) стали долгими.
- Внутри трейсинга находите, что сервис инвентаризации делает медленный SQL-запрос к БД.
- Вы ищете в логах по Trace ID этого запроса и видите конкретный SQL, который выполняется 1.8 секунды.
- Причина — неоптимальный план из-за отсутствия индекса.
graph LR
Metrics[Метрики: latency выросла] --> Traces[Трейсинг: какой сервис тормозит]
Traces --> Logs[Логи: конкретная ошибка/запрос]
Logs --> Fix[Исправление: добавить индекс]
Без трейсинга вы бы гадали, какой сервис виноват. Без логов не нашли бы конкретный SQL.
Что делает Observability системой, а не коллекцией инструментов
Observability проектируется, а не “добавляется потом”. Это означает:
- Correlation ID передаётся через все сервисы (в HTTP-заголовках, в сообщениях Kafka, в gRPC metadata).
- Логи структурированы (JSON), имеют фиксированный набор полей:
timestamp,level,service,correlation_id,message. - Метрики экспортируются в единую систему (Prometheus). Каждая метрика имеет метки (
method,endpoint,status_code), чтобы можно было фильтровать. - Трассировка охватывает все сервисы (через OpenTelemetry или проприетарные библиотеки).
Если система спроектирована без наблюдаемости, добавить её потом будет крайне сложно: придётся переписывать код и менять инструментарий уже в работающей системе, под нагрузкой.
Резюме
Observability — это способность понять внутреннее состояние системы по её внешним проявлениям. Она строится на трёх столпах:
- Метрики — агрегированные числовые показатели (RPS, latency, ошибки, CPU, RAM, размеры очередей). Позволяют следить за здоровьем системы, строить дашборды, настраивать алерты.
- Логи — дискретные структурированные записи о событиях. Позволяют расследовать конкретные инциденты, искать ошибки по correlation_id, аудит.
- Трейсинг — путь запроса через распределённую систему. Позволяют найти узкие места, понять задержки, увидеть зависимости между сервисами.
Для аналитика observability важна не только как набор инструментов, но и как дисциплина проектирования:
- Требуйте структурированных логов и передачи correlation_id с самого начала.
- Определите ключевые метрики для каждого сервиса (RPS, latency, ошибки, системные метрики) и бизнес-метрики (конверсия, активные пользователи).
- Убедитесь, что трассировка настроена для всех сервисов (хотя бы с сэмплированием 1%).
- Мониторинг без возможности ответить на вопрос “почему?” — это не observability. Добивайтесь, чтобы система отвечала не только на “что случилось”, но и на “почему это случилось”.