Итоги модуля: главное коротко
В главе собрано главное из девяти глав модуля. На каждую главу отведён один раздел: несколько фраз о сути и один пример со стенда. Новых понятий здесь нет. Глава нужна, чтобы повторить модуль и быстро найти нужное место в подробных главах.
Сервис разбирают по данным, которые он сохранил заранее: метрики показывают масштаб, логи — что случилось, трассы — где ушло время.
- Раздел
- Повторение
- Уровень
- После глав 1.1–1.9
- Связанные главы
- Весь модуль 1
- Зачем это знать
- Держать в голове весь путь от жалобы до проверенного вывода
§1После развёртывания
Пока программа работает на компьютере разработчика, ошибку ищут терминалом, отладчиком, повтором запроса и правкой кода. После развёртывания ни один из этих способов не работает: процессов несколько, они на других серверах, и упавший процесс уже перезапущен. Остаются только данные, которые сервис сохранил во время работы.
Код ответа о многом не сообщает. На стенде два запроса к /products вернули одинаковый ответ, а длились по-разному.
| Сценарий | Код ответа | Клиент ждал | Уровень записи |
|---|---|---|---|
| fast | 200 | 84,0 мс | INFO |
| slow | 200 | 3026,6 мс | INFO |
По коду ответа эти запросы неразличимы, поэтому сохраняют длительность. Проверка /health тоже не помогает: она сообщает, что процесс жив, и не обращается к рабочему маршруту. Одна ручная проверка после жалобы почти ничего не доказывает: если медленным оказывается каждый двадцатый запрос, десять проверок подряд с вероятностью 60% будут быстрыми.
Подробно: глава 1.1. Данные нужно собирать регулярно, и это задача мониторинга.
§2Мониторинг
Мониторинг — регулярный сбор, хранение и анализ данных о работе сервиса. Он состоит из пяти шагов: измерить, сохранить с временем, сопоставить, показать и отреагировать. Если выпадает любой шаг, цепочка перестаёт работать.
Число на панели читается, только если известны объект, величина, единица и способ расчёта. Одно значение без истории мало что говорит, поэтому значения собирают во временной ряд и сравнивают с обычным уровнем: с тем же часом вчера или неделю назад.
Доли считают из количеств. Проценты разных экземпляров усреднять нельзя, и пример это показывает.
| Расчёт | Формула | Результат |
|---|---|---|
| Неверно: среднее процентов | (50% + 0%) / 2 | 25% |
| Верно: сумма количеств | (5 + 0) / (10 + 990) | 0,5% |
Первый экземпляр обработал 10 запросов, второй — 990, и у второго вес в 99 раз больше. Что измерять у сервиса, подсказывают четыре сигнала: задержка, трафик, ошибки и насыщение. Правило оповещения описывает проблему пользователя: «доля ошибок выше 2% в течение 5 минут».
Подробно: глава 1.2. Мониторинг отвечает на заранее заданные вопросы; для новых нужна наблюдаемость.
§3Наблюдаемость и телеметрия
Мониторинг отвечает на вопросы, заданные заранее. Наблюдаемость — свойство системы: можно ли по уже сохранённым данным ответить на новый вопрос, не меняя код. Пример — медленные большие отчёты: если размер отчёта не записан вместе с длительностью, зависимость между ними найти нельзя.
Данные, которые система сообщает о себе, называются телеметрией. Основных видов три, и разбор обычно идёт в таком порядке.
| Сигнал | На какой вопрос отвечает | Пример |
|---|---|---|
| Метрика | Что и когда ухудшилось | Доля ответов 500 за час |
| Лог | Что случилось с конкретным запросом | Текст исключения запроса 2797ad2d… |
| Трасса | На каком этапе ушло время | Три секунды на dependency.wait |
Телеметрию создаёт сама программа: такой код называют инструментацией. Записи одного запроса связывает общий request_id. В метки метрик его не добавляют: каждое новое значение метки создаёт новый ряд, и рядов станет столько, сколько запросов.
Подробно: глава 1.3. Дальше три сигнала по отдельности, начиная с метрик.
§4Метрики
Метрика сворачивает много измерений в несколько чисел. Счётчик (counter) только растёт, и пользу даёт его прирост за интервал. Мгновенное значение (gauge) показывает состояние в момент измерения. Гистограмма (histogram) хранит число измерений по корзинам.
speed = (15240 - 15000) / 10 # прирост счётчика за 10 секунд
print(speed) # 24.0 запроса в секундуДля длительности одного среднего мало. В прогоне из двадцати запросов к стенду три показателя разошлись в разы.
| Показатель | Значение | Что описывает |
|---|---|---|
| Среднее | 379,470 мс | Ни один запрос столько не длился: два медленных подняли сумму |
| Медиана | 85,739 мс | Типичный запрос; медленные не видны |
| p95 | 3024,239 мс | Граница медленных 5% запросов |
Перцентили разных экземпляров не усредняют: сначала складывают гистограммы, затем считают перцентиль по сумме.
Подробно: глава 1.4. Метрика показывает масштаб, подробности события хранит лог.
§5Логи
Лог — последовательность записей о событиях. Полезная запись отвечает на вопросы «когда», «где», «что произошло» и «к какому запросу относится». Записи пишут в JSON, чтобы по каждому полю можно было искать.
{"timestamp": "2026-09-22T13:23:26.548004+00:00", "level": "ERROR",
"service": "products-api", "route": "/products", "status": 500,
"duration_ms": 76.503, "request_id": "1cf09e6f86f04fa7b6b4941d75d388e9"}Уровень записи показывает важность события: DEBUG, INFO, WARNING, ERROR, CRITICAL. Traceback читают снизу вверх: последняя строка сообщает тип исключения, над ней указаны файл и строка. Клиент получает только request_id, а traceback остаётся в логе. Пароли, токены и персональные данные в логи не записывают.
Подробно: глава 1.5. Где запрос потратил время, показывает третий сигнал.
§6Трассы
Трасса — запись об одной операции в виде этапов на общей шкале времени. Этап (span) хранит имя, начало и длительность. На стенде трасса медленного запроса сразу показывает место задержки.
| Этап | Длительность |
|---|---|
| validate | 11,1 мс |
| dependency.wait | 3000,6 мс |
| serialize | 10,6 мс |
| Весь обработчик | 3022,3 мс |
Здесь этапы идут друг за другом, и их длительности складываются. Так бывает не всегда. Вложенные этапы входят в родительский, и их не складывают: 500 + 400 + 300 мс — это один запрос на 500 мс. Параллельные этапы перекрываются: кэш на 40 мс и внешний API на 900 мс вместе занимают 900 мс. Долю медленных запросов по трассам не считают, потому что трассы сохраняют выборочно; для этого есть метрики.
Подробно: глава 1.6. Все три сигнала работают вместе при разборе инцидента.
§7Разбор инцидента
Расследование идёт от жалобы к проверенному выводу: уточнить жалобу, оценить масштаб по метрикам, сузить область, посмотреть трассу, выдвинуть гипотезы и проверить их, проверить исправление. На каждом шаге отделяют измеренное от предполагаемого.
| Шаг | Что нашли |
|---|---|
| Метрики | Медиана 90 → 95 мс, p95 160 → 4200 мс: медленной стала небольшая часть запросов |
| Разбивка по экземплярам | p95 на api-2 — 9800 мс, на остальных около 160 мс; на api-2 новая версия |
| Трасса | Из 2910 мс запрос 2800 мс ждал соединение, сам SQL — 35 мс |
| Гипотезы | В новой версии пул уменьшен с 10 до 2; нужно 62 × 0,04 ≈ 2,5 соединения |
| Исправление | После возврата пула p95 на api-2 — 155 мс при том же потоке |
Вывод «база данных тормозила» был бы неверным: база отвечала за 35 мс. Отчёт называет механизм, измерения и способ проверки.
Подробно: глава 1.7. Метрики для такого разбора собирают Prometheus и Grafana.
§8Prometheus и Grafana
Приложение отдаёт текущие значения на странице /metrics. Prometheus сам опрашивает её с заданным интервалом и сохраняет значения с временем. Grafana отправляет запросы к Prometheus и строит панели.
sum by (status) (rate(lab_http_requests_total[1m]))Запрос читают изнутри наружу: значения счётчика за минуту, средний прирост в секунду, сумма по коду ответа. Окно rate берут не меньше четырёх интервалов опроса. Числа на панелях сверяют с Prometheus: на стенде панель «Завершённые запросы» показала 401, это 363 + 38 из таблицы Prometheus. Первым делом после запуска проверяют страницу Target health: если цель не в состоянии UP, все панели будут пустыми.
Подробно: глава 1.8. Весь путь можно пройти самостоятельно в практике.
§9Практика
В практике сервис запускается на своём компьютере, скрипт отправляет двадцать запросов, по сохранённым файлам считаются показатели, затем меняется одна величина и прогон повторяется. Результат оформляется по бланку расследования.
Главное требование к выводу — его можно проверить. Запись «сервис работает медленно» не принимается. Запись «2 из 20 запросов прогона (10%) заняли больше 1000 мс; источник — results/requests.csv, столбец client_ms» принимается: в ней названы выборка, величина, порог, единица и файл.
Подробно: глава 1.9. Последний раздел собирает модуль в одну цепочку.
§10Весь модуль в одной цепочке
Модуль сводится к одному порядку действий. Сервис заранее создаёт телеметрию: метрики, логи и трассы. Мониторинг собирает метрики и сообщает об отклонении. По метрикам оценивают масштаб и сужают область, по логам находят запросы, по трассам — этап, на котором ушло время. Гипотезу проверяют изменением и новым измерением, а вывод записывают так, чтобы его мог пересчитать другой человек.
| Термин | Одной строкой |
|---|---|
| Мониторинг | Регулярный сбор, хранение и анализ данных о работе системы |
| Наблюдаемость | Возможность ответить на новый вопрос по уже сохранённым данным |
| Телеметрия | Данные, которые система сообщает о себе: метрики, логи, трассы |
| Метрика | Число по группе событий или состояние, хранится как временной ряд |
| Лог | Запись об одном событии с контекстом |
| Трасса | Этапы одной операции на общей шкале времени |
| Перцентиль p95 | Длительность, которую не превысили 95% запросов |
| Кардинальность | Число рядов, которые получаются из всех сочетаний меток |
Как Prometheus собирает метрики, подробно разобрано в модуле 2.