Проблема: вы запустили приложение в продакшен. Пользователи жалуются на медленную работу, но вы не знаете где именно проблема. База данных? Сеть? Какой-то из 15 микросервисов? Без мониторинга вы слепой пилот.
Решение: мониторинг и наблюдаемость. 67% компаний используют Prometheus в продакшене, 70% комбинируют Prometheus с Grafana. Для логов стандарт де-факто — стек ELK (Elasticsearch, Logstash, Kibana).
Цифры: команды с хорошей наблюдаемостью на 90% быстрее находят проблемы, среднее время восстановления падает с 45 до 25 минут.
В статье: разница между мониторингом и наблюдаемостью, как настроить Prometheus + Grafana, как настроить ELK, какие показатели отслеживать в первую очередь (четыре золотых сигнала), примеры запросов и панелей.
1. Мониторинг против наблюдаемости: в чём разница
Мониторинг — отслеживание заранее определённых показателей и оповещения когда что-то идёт не так.
Наблюдаемость — способность понять внутреннее состояние системы по её выходным данным (показатели, логи, трассировки).
Простая аналогия:
Мониторинг — панель приборов в машине. Показывает скорость, уровень топлива, предупреждения
Наблюдаемость — открыть капот и понять почему загорелась лампочка
| Аспект | Мониторинг | Наблюдаемость |
|---|---|---|
Подход | Реактивный (реагирует после) | Проактивный (предсказывает до) |
Фокус | Известные показатели | Понимание неизвестного |
Вопрос | "Что сломалось?" | "Почему сломалось? Как исправить?" |
Данные | Показатели, оповещения | Показатели + логи + трассировки |
Цель | Определить проблему | Понять первопричину |
Системы | Хорошо для простых систем | Необходимо для распределённых систем |
Пример:
Мониторинг: "Оповещение! Использование процессора 95%"
Наблюдаемость: "Процессор нагружен потому что сервис оплаты отправляет 1000 повторных запросов к базе из-за тайм-аута соединения который вызван сетевой задержкой между серверами"
Три столпа наблюдаемости:
Показатели (метрики): числовые измерения производительности во времени (загрузка процессора, использование памяти, запросы в секунду)
Логи: детальные записи событий в приложениях (кто, что, когда)
Трассировки: путь запроса через все микросервисы (откуда пришёл, куда пошёл, сколько времени в каждом сервисе)
Вывод: вам нужно и то и другое. Мониторинг говорит "что-то не так", наблюдаемость помогает понять "что именно и почему".
2. Что отслеживать в первую очередь: четыре золотых сигнала
Google в своей книге по инженерии надёжности сайтов описал четыре ключевых показателя которые нужно отслеживать в любой системе:
1. Задержка (Latency)
Время ответа на запрос. Важно: отдельно считайте задержку успешных и неудачных запросов.
Что смотреть:
50-й перцентиль (медиана) — типичный пользовательский опыт
95-й перцентиль — опыт более медленных 5% запросов
99-й перцентиль — опыт самых медленных 1% запросов
Не используйте среднее значение! Среднее скрывает выбросы. Если 99% запросов 100мс, а 1% — 10 секунд, среднее покажет 199мс и вы не увидите проблему.
2. Трафик (Traffic)
Сколько нагрузки получает ваша система.
Примеры:
Веб-сервис: HTTP запросов в секунду
База данных: транзакций в секунду
Стриминг: гигабайт в секунду
3. Ошибки (Errors)
Процент неудачных запросов.
Типы ошибок:
Явные: HTTP 500, 503, исключения
Неявные: HTTP 200 но с некорректными данными
Политические: запрос успешен но нарушает соглашение об уровне обслуживания (ответ за 3 секунды вместо обещанных 300мс)
4. Насыщенность (Saturation)
Насколько заполнены ресурсы системы.
Примеры:
Загрузка процессора: 80% от максимума
Использование памяти: 12ГБ из 16ГБ
Заполнение диска: 450ГБ из 500ГБ
Очередь запросов: 50 запросов в ожидании
Важно: большинство систем начинают деградировать до достижения 100%. Например, база данных может замедляться уже на 80% использования процессора.
Вариации: RED и USE
RED метод (для микросервисов и API):
Rate (Частота): запросов в секунду
Errors (Ошибки): число неудачных запросов
Duration (Длительность): время обработки запроса
USE метод (для инфраструктуры: серверы, диски):
Utilization (Утилизация): процент времени когда ресурс занят
Saturation (Насыщенность): объём работы которую ресурс не может обслужить
Errors (Ошибки): счётчик ошибок ресурса
3. Prometheus + Grafana: настройка и примеры
Что это
Prometheus: система мониторинга с открытым кодом для сбора и хранения показателей временных рядов. Разработана в SoundCloud в 2012, сейчас второй проект (после Kubernetes) принятый в Cloud Native Computing Foundation.
Grafana: платформа визуализации. Не хранит данные, а запрашивает их из источников (Prometheus, Elasticsearch, и др) и отрисовывает панели.
Почему это стандарт:
75% внедрений Kubernetes используют Prometheus
67% компаний используют Prometheus в продакшене
Prometheus 2.51 (апрель 2025) обрабатывает миллионы активных серий на обычных дисках
Быстрая установка через Docker
# docker-compose.yml
version: '3'
services:
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
ports:
- "9090:9090"
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.retention.time=15d'
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana-data:/var/lib/grafana
volumes:
prometheus-data:
grafana-data:
Конфигурация Prometheus
# prometheus.yml
global:
scrape_interval: 15s # Как часто собирать показатели
evaluation_interval: 15s # Как часто проверять правила
# Откуда собирать показатели
scrape_configs:
# Мониторинг самого Prometheus
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
# Мониторинг хоста (нужен node_exporter)
- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']
# Мониторинг вашего приложения
- job_name: 'my-app'
static_configs:
- targets: ['my-app:8080']
Экспортеры (exporters)
Экспортеры — компоненты которые собирают показатели из систем которые сами их не отдают.
| Экспортер | Для чего | Основные показатели |
|---|---|---|
node_exporter | Сервера Linux | Процессор, память, диск, сеть |
windows_exporter | Сервера Windows | Процессор, память, диск, сеть |
mysqld_exporter | MySQL базы | Запросы, соединения, репликация |
postgres_exporter | PostgreSQL базы | Соединения, блокировки, размер |
redis_exporter | Redis | Память, попадания, промахи |
blackbox_exporter | Проверки доступности | HTTP, DNS, TCP, ICMP |
Язык запросов PromQL
Примеры полезных запросов:
# Загрузка процессора (в процентах)
100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# Использование памяти (в процентах)
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100
# Свободное место на диске (в процентах)
100 - ((node_filesystem_avail_bytes / node_filesystem_size_bytes) * 100)
# Запросы в секунду
rate(http_requests_total[5m])
# Процент ошибок
rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) * 100
# 95-й перцентиль задержки
histogram_quantile(0.95,
rate(http_request_duration_seconds_bucket[5m])
)
# 99-й перцентиль задержки
histogram_quantile(0.99,
rate(http_request_duration_seconds_bucket[5m])
)
Подключение Grafana к Prometheus
Откройте Grafana:
http://localhost:3000Войдите (логин: admin, пароль: admin)
Меню → Configuration → Data Sources → Add data source
Выберите Prometheus
URL:
http://prometheus:9090Save & Test
Готовые панели
На grafana.com/grafana/dashboards тысячи готовых панелей.
Популярные:
ID 1860: Node Exporter Full (детальные показатели сервера)
ID 3662: Prometheus 2.0 Stats (статистика самого Prometheus)
ID 7249: Kubernetes Cluster Monitoring
ID 9628: PostgreSQL Database
Импорт панели:
Grafana → Dashboards → Import
Введите ID панели (например 1860)
Load → выберите источник Prometheus → Import
Настройка оповещений в Grafana
# Пример: оповещение если загрузка процессора > 80%
Alerting → Alert rules → Create alert rule
Query A:
100 - (avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
Condition:
WHEN last() OF query(A) IS ABOVE 80
Evaluate: every 1m for 5m # Проверять каждую минуту, срабатывать если 5 минут подряд
Notifications:
- Email
- Slack
- Telegram
- PagerDuty
4. ELK Stack: логи и их анализ
Что такое ELK
ELK — аббревиатура трёх компонентов:
Elasticsearch: поисковая и аналитическая база данных. Хранит и индексирует логи
Logstash: конвейер обработки данных. Собирает логи из разных источников, обрабатывает, отправляет в Elasticsearch
Kibana: веб-интерфейс для визуализации. Строит графики и панели по данным из Elasticsearch
+ Beats: лёгкие сборщики данных (Filebeat для файлов, Metricbeat для показателей, и т.д.)
Современная альтернатива Logstash: многие заменяют Logstash на Fluentd или Fluent Bit — они легче и быстрее.
Почему ELK для логов
В распределённой системе логи разбросаны по десяткам серверов. Нужно централизованное хранилище где можно:
Искать по всем логам сразу
Фильтровать по уровню (info, warning, error)
Смотреть контекст вокруг ошибки
Строить графики по частоте ошибок
Находить корреляции между событиями
Установка через Docker
# docker-compose.yml для ELK
version: '3'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.11.0
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- xpack.security.enabled=false
ports:
- "9200:9200"
volumes:
- elasticsearch-data:/usr/share/elasticsearch/data
kibana:
image: docker.elastic.co/kibana/kibana:8.11.0
ports:
- "5601:5601"
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
depends_on:
- elasticsearch
logstash:
image: docker.elastic.co/logstash/logstash:8.11.0
ports:
- "5044:5044"
volumes:
- ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
depends_on:
- elasticsearch
volumes:
elasticsearch-data:
Конфигурация Logstash
# logstash.conf
input {
# Принимать логи через Beats
beats {
port => 5044
}
# Или через TCP
tcp {
port => 5000
codec => json
}
}
filter {
# Парсинг JSON логов
if [message] =~ /^\{/ {
json {
source => "message"
}
}
# Парсинг даты
date {
match => ["timestamp", "ISO8601"]
}
# Добавление геолокации по IP
geoip {
source => "client_ip"
}
}
output {
# Отправка в Elasticsearch
elasticsearch {
hosts => ["elasticsearch:9200"]
index => "logs-%{+YYYY.MM.dd}"
}
# Дублирование в консоль для отладки
stdout {
codec => rubydebug
}
}
Структурированные логи в приложении
Вместо обычного текста отправляйте JSON:
# Плохо (неструктурированный лог)
logger.info("User logged in")
# Хорошо (структурированный лог)
logger.info({
"event": "user_login",
"user_id": 12345,
"ip": "192.168.1.1",
"timestamp": "2026-02-02T10:30:00Z",
"level": "info"
})
Почему структурированные логи:
Легко фильтровать по полям
Не нужны регулярные выражения для парсинга
Быстрее индексация в Elasticsearch
Можно строить агрегации (сколько логинов за час)
Настройка Kibana
Откройте Kibana:
http://localhost:5601Management → Stack Management → Index Patterns
Create index pattern → введите
logs-*Выберите поле времени:
@timestampCreate index pattern
Полезные запросы в Kibana
# Все ошибки за последний час
level:error
# Ошибки конкретного сервиса
level:error AND service_name:"payment-service"
# HTTP 500 ошибки
http.status_code:500
# Медленные запросы (больше 1 секунды)
response_time:>1000
# Ошибки конкретного пользователя
user_id:12345 AND level:error
# Комбинация фильтров
service_name:"auth-service" AND (level:error OR level:critical)
Визуализации в Kibana
Что создать:
Метрика: общее количество ошибок за период
Круговая диаграмма: распределение логов по уровням (info 80%, warning 15%, error 5%)
Линейный график: количество ошибок во времени
Таблица топ-10: какие сервисы генерируют больше всего ошибок
Тепловая карта: ошибки по времени суток и дням недели
5. Что мониторить в первую очередь: чек-лист по приоритетам
Приоритет 1: Критичные показатели (без них система слепая)
Для веб-приложений:
☐ Запросы в секунду
☐ Задержка ответа (50-й, 95-й, 99-й перцентили)
☐ Процент ошибок (4xx, 5xx)
☐ Доступность сервиса (uptime)
Для инфраструктуры:
☐ Загрузка процессора
☐ Использование памяти
☐ Свободное место на диске
☐ Сетевой трафик (входящий/исходящий)
Для баз данных:
☐ Количество подключений
☐ Время выполнения запросов
☐ Медленные запросы (больше 1 секунды)
☐ Размер базы данных
☐ Статус репликации
Приоритет 2: Бизнес-показатели (влияют на деньги)
☐ Регистрации пользователей в час
☐ Успешных оплат в минуту
☐ Конверсия оформления заказа
☐ Время до первого взаимодействия пользователя
☐ Процент брошенных корзин
Приоритет 3: Показатели опыта пользователя
☐ Время загрузки страницы (Real User Monitoring)
☐ Время до интерактивности
☐ Ошибки JavaScript на клиенте
☐ Процент успешных действий пользователя
Приоритет 4: Детальные показатели (для глубокой диагностики)
☐ Попадания в кеш / промахи
☐ Размер очереди сообщений
☐ Число открытых файловых дескрипторов
☐ Сборка мусора (garbage collection)
☐ Размер пула соединений к базе
6. Настройка оповещений: что и когда оповещать
Проблема шумных оповещений
Если оповещения срабатывают каждые 5 минут, команда начинает их игнорировать. Правило: оповещение должно означать "кто-то должен действовать прямо сейчас".
Уровни серьёзности
| Уровень | Когда | Действие | Канал |
|---|---|---|---|
Критичный | Сервис недоступен, данные теряются | Немедленное вмешательство | Пейджер, звонок |
Высокий | Деградация производительности, многие пользователи затронуты | Действие в течение 15 минут | Slack, SMS |
Средний | Проблема затрагивает часть пользователей | Действие в рабочее время | Email, Slack |
Низкий | Потенциальная проблема в будущем | Запланировать исправление | Тикет, email |
Примеры хороших оповещений
# Критичный: сервис недоступен
Оповещение: Сервис платежей недоступен
Условие: rate(http_requests_total{job="payment-service"}[5m]) == 0
Длительность: 2 минуты
Действие: Немедленно проверить, откатить последний деплой если нужно
# Высокий: высокий процент ошибок
Оповещение: Высокий процент ошибок 5xx
Условие: rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) > 0.05
Длительность: 5 минут
Действие: Проверить логи, найти причину
# Средний: медленные ответы
Оповещение: Задержка 99-го перцентиля выше SLA
Условие: histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m])) > 1.0
Длительность: 10 минут
Действие: Профилировать приложение, оптимизировать запросы
# Низкий: диск заполняется
Оповещение: Диск заполнится через 4 часа
Условие: predict_linear(node_filesystem_free_bytes[1h], 4*3600) < 0
Длительность: 30 минут
Действие: Очистить логи, увеличить диск
Правила оповещений
Оповещайте о симптомах, а не о причинах: "API медленный" (симптом) лучше чем "Загрузка процессора 80%" (причина)
Используйте время ожидания: не оповещайте при первом превышении порога, подождите 5 минут чтобы исключить краткосрочные всплески
Группируйте похожие оповещения: не отправляйте 50 оповещений если падает целый датацентр, отправьте одно "Датацентр US-EAST недоступен"
Добавляйте контекст: оповещение должно содержать ссылку на панель, runbook, график
Регулярно пересматривайте: если оповещение срабатывает но никто не действует — удалите его
7. Лучшие практики: как не утонуть в данных
1. Начинайте с четырёх золотых сигналов
Не пытайтесь мониторить всё сразу. Начните с задержки, трафика, ошибок, насыщенности. Это даст вам 80% понимания состояния системы.
2. Используйте метки (labels) правильно
Плохо: создавать отдельную метрику для каждого пользователя:
user_123_requests_totaluser_456_requests_total
Хорошо: одна метрика с метками:
requests_total{user_id="123"}requests_total{user_id="456"}
Правило: используйте метки для измерений с низкой кардинальностью (десятки значений, не миллионы). Не создавайте метку для ID пользователя если у вас миллион пользователей.
3. Настройте хранение данных
Высокое разрешение (15 секунд): храните 1-3 дня
Среднее разрешение (1 минута): храните 7-15 дней
Низкое разрешение (5 минут): храните 90 дней
Долгосрочное хранение: используйте Thanos или Cortex для агрегации и хранения в объектном хранилище (дешёво)
4. Создавайте панели для инцидентов, не для красоты
Лучшие панели помогают во время проблем, а не просто красиво выглядят.
Структура панели для инцидентов:
Обзорная панель вверху: общее состояние системы, активные оповещения, ключевые показатели
Секции по сервисам: каждый критичный сервис — своя строка с показателями
Ссылки на ресурсы: runbook, инструкции, процедуры эскалации
Корреляции: ошибки приложения + недавние изменения инфраструктуры
5. Автоматизируйте там где возможно
Используйте инфраструктуру как код:
Конфигурация Prometheus — в Git
Панели Grafana — экспорт в JSON, хранение в Git
Правила оповещений — версионирование
Развёртывание — через Terraform, Ansible, Helm
6. Логи: храните недолго, индексируйте выборочно
Полнотекстовая индексация всех логов дорогая.
Стратегия:
Info логи: храните 3-7 дней, индексируйте только временные метки и поля
Warning/Error логи: храните 30 дней, полная индексация
Аудит логи: храните 1-2 года, архивируйте в объектное хранилище
Альтернатива ELK: Grafana Loki индексирует только метки, а не весь текст логов. Это дешевле на порядок и быстрее для большинства задач.
8. Частые ошибки
Ошибка 1: Мониторить всё подряд
Команды пытаются собирать тысячи показателей "на всякий случай". Результат: огромные затраты на хранение, панели бесполезны во время инцидента.
Как избежать: начните с четырёх золотых сигналов. Добавляйте новые показатели только когда они помогли бы решить реальный инцидент.
Ошибка 2: Использовать среднее значение вместо перцентилей
Среднее скрывает выбросы. Если 99% запросов отвечают за 100мс, а 1% за 30 секунд, среднее покажет 400мс и вы не увидите что 1% пользователей страдает.
Как избежать: всегда смотрите на перцентили: 50-й (медиана), 95-й, 99-й.
Ошибка 3: Оповещения без действия
Оповещение "Загрузка процессора 80%" срабатывает, команда смотрит, ничего не делает, оповещение исчезает само.
Как избежать: каждое оповещение должно требовать действия. Если не требует — удалите оповещение или повысьте порог.
Ошибка 4: Нет runbook для оповещений
Срабатывает оповещение в 3 часа ночи, дежурный не знает что делать.
Как избежать: для каждого оповещения создайте runbook с шагами диагностики и исправления.
Ошибка 5: Логи без структуры
Неструктурированные текстовые логи невозможно эффективно анализировать.
Как избежать: используйте структурированные логи (JSON), включайте поля: timestamp, level, service_name, request_id.
Ошибка 6: Не корреляция данных
Показатели в Prometheus, логи в ELK, трассировки в Jaeger — всё раздельно.
Как избежать: используйте единый идентификатор запроса (trace_id) во всех системах. Добавляйте ссылки между системами (из панели Grafana на логи в Kibana).
9. Чек-лист запуска мониторинга
Месяц 1: Базовый мониторинг
☐ Установить Prometheus + Grafana
☐ Установить node_exporter на все сервера
☐ Настроить сбор показателей инфраструктуры (процессор, память, диск)
☐ Импортировать готовую панель Node Exporter Full (ID 1860)
☐ Настроить первое оповещение (например, диск заполнен на 90%)
Месяц 2: Мониторинг приложений
☐ Добавить в приложение экспорт показателей (эндпоинт /metrics)
☐ Начать собирать четыре золотых сигнала (задержка, трафик, ошибки, насыщенность)
☐ Создать панель для каждого критичного сервиса
☐ Настроить оповещения для высокого процента ошибок
Месяц 3: Централизованные логи
☐ Установить ELK Stack
☐ Настроить Filebeat на серверах для отправки логов
☐ Переключить приложения на структурированные логи (JSON)
☐ Создать панели в Kibana для ошибок по сервисам
☐ Настроить оповещение на всплески ошибок в логах
Месяц 4+: Углубление
☐ Добавить мониторинг баз данных (mysqld_exporter, postgres_exporter)
☐ Настроить распределённую трассировку (Jaeger или Tempo)
☐ Корреляция показателей, логов и трассировок через trace_id
☐ Создать runbook для каждого оповещения
☐ Настроить долгосрочное хранение (Thanos для показателей)
☐ Регулярный пересмотр оповещений (удаление шумных)
10. Стоимость мониторинга
Самостоятельное развёртывание (открытый код)
Затраты:
Сервера: ~$200-500/месяц (зависит от объёма данных)
Хранилище: ~$50-200/месяц
Время инженеров: 20-40 часов/месяц на настройку и поддержку
Итого: $250-700/месяц + время команды
Управляемые решения
| Сервис | Стоимость | Что включено |
|---|---|---|
Grafana Cloud | От $0 (50ГБ логов, 10К серий бесплатно) | Prometheus + Loki + Tempo + Grafana |
Datadog | От $15/хост/месяц | Всё включено + APM |
New Relic | От $0 (100ГБ + 1 пользователь) | Показатели, логи, трассировки |
Elastic Cloud | От $95/месяц | Управляемый ELK Stack |
Окупаемость
Один серьёзный инцидент может стоить $50,000-500,000 (простой + потеря выручки + репутация).
Хороший мониторинг:
Обнаруживает проблемы на 60% быстрее
Сокращает время восстановления с 45 до 25 минут
Предотвращает 30-40% инцидентов (проактивное обнаружение)
Если мониторинг предотвратит 2 крупных инцидента в год, он окупится в 50-500 раз.
Вывод: начните с бесплатных инструментов открытого кода (Prometheus + Grafana + ELK). Когда команда вырастет или нужен меньше операционных хлопот — рассмотрите управляемые решения.
А лучшие вакансии для DevOps ищите на hirehi.ru