Metrics
«Возможность осуществить авторизацию» — так выглядела строка в таблице метрик интернет-магазина, которая мне попадалась. В соседней колонке разработка ответила: «Каким образом считаем?» Напротив «корректного отображения остатков и цен» стояло ещё честнее: «Не понятно как мониторить это». Я регулярно вижу этот разрыв. Список того, что хочется знать о сервисе, пишется за час. Метрикой он становится после нескольких неудобных решений: что считаем событием, чем успех отличается от неуспеха и что с этим числом можно будет делать через полгода.
Лист про эти решения. Метрика — числовой ряд во времени с именем и набором меток (label), и почти всё важное о ней определяется в момент инструментирования: тип, единица, метки, границы гистограммы. Поменять потом можно, но каждая правка ломает либо историю, либо чужие дашборды и алерты.
Границы с соседями. Systematic Troubleshooting берёт RED, USE и золотые сигналы как способ искать поломку; здесь они отвечают на вопрос, что инструментировать. Telemetry Economics считает кардинальность в деньгах; здесь она свойство модели данных. Что из метрик будит человека, решают SLI-based Alerting и Symptom vs Cause Alerting, а какая метрика становится SLI — SLO Engineering.
Что должен уметь
Заголовок раздела «Что должен уметь»Главный навык на уровне L4 — выбирать тип метрики под вопрос, который ей зададут потом. Я считаю его главным, потому что ошибку в типе не видно в день выкатки. Summary исправно рисует p99 одной реплики, и только когда реплик становится двадцать, выясняется, что общий перцентиль из двадцати готовых не собрать.
L3
- Читает экспозицию сервиса и различает counter, gauge и histogram по допустимым операциям: от счётчика берут скорость роста, от gauge — текущее значение, из гистограммы — долю запросов быстрее порога.
- Инструментирует обработчик запроса: счётчик запросов, счётчик ошибок, длительность гистограммой; имя и единицы по конвенции, без самодельных сокращений.
L4
- Выбирает гистограмму там, где перцентиль придётся считать по нескольким репликам, и объясняет, почему summary этого не даст.
- Проектирует метки: у каждой конечный и заранее известный набор значений; число рядов оценивает до выкатки, перемножая кардинальности меток.
- Подбирает модель под тип нагрузки — запрос и ответ, конвейер обработки, пакетное задание — и для каждого называет ключевую метрику.
- Ставит границу бакета на порог, по которому сервис будут судить, либо берёт нативную гистограмму и обходится без ручных границ.
L5
- Вводит единую модель инструментирования для сервисов команды: общие имена и метки, библиотека или middleware, чтобы базовые метрики появлялись без ручной работы.
- Меняет метрику как контракт: новая живёт рядом со старой, срок старой объявлен, дашборды и алерты переведены до удаления.
- Доводит продуктовую формулировку до события с определением успеха и записывает, чего метрика не видит.
- Делит метрики на те, без которых сервис не починить прямо сейчас, и остальные; для первых выбирает самый короткий путь доставки.
L6+
- Ставит ограничения на входе: лимит рядов на сервис по умолчанию, проверку запаса в CI, жизненный цикл метрик с понятными стадиями.
- Решает, где организации хватит клиентских библиотек Prometheus, а где оправдан переход на OpenTelemetry и его семантические конвенции.
- Следит, чтобы автоматика не принимала пропавшую метрику за ноль: при потере данных масштабирование и канареечный анализ останавливаются, а не действуют.
Материалы
Заголовок раздела «Материалы»- Betsy Beyer et al. (eds) — Site Reliability Engineering (O’Reilly, 2016), глава 6 «Monitoring Distributed Systems», автор Rob Ewaschuk. Четыре золотых сигнала из неё знают все, а раздел «Worrying About Your Tail» цитируют гораздо реже. Советую прочитать именно его: на одном примере показано, почему метрика по среднему скрывает хвост.
Статьи и доклады
Заголовок раздела «Статьи и доклады»- Prometheus — Metric types и Histograms and summaries. Вторую страницу обязательно прочитать до первой гистограммы в коде: в ней объяснено, почему готовые перцентили нельзя агрегировать, и прямо сказано, что при возможности стоит брать нативные гистограммы.
- Prometheus — Instrumentation. Лучшее из известных мне коротких руководств о том, что именно инструментировать: три типа сервисов и ключевые метрики каждого. Там же ориентир по числу значений у метки.
- Prometheus — Metric and label naming. Одна страница правил для имён: базовые единицы, суффиксы, что не кладут в метки.
- Lukasz Mierzwa — How Cloudflare runs Prometheus at scale (Cloudflare, 2023). Кардинальность объяснена от устройства хранилища, а не от счёта за него. Читать обязательно ради второй половины, где описаны лимиты на входе.
- Kubernetes — Metrics For Kubernetes System Components. Раздел про жизненный цикл метрики — готовый образец контракта: что разрешено менять на каждой стадии и как метрика уходит.
- GitLab — Metrics Catalog. Открытый каталог метрик GitLab.com: декларативное описание сервисов и их индикаторов. Пример того, как единая модель инструментирования выглядит в настоящем репозитории.
- Gil Tene — How NOT to Measure Latency (InfoQ). Доклад о типичных ошибках в измерении задержки. Советую посмотреть до того, как выбирать перцентили для дашборда.
- Руслан Боярский — Метрики для метрик: опыт выстраивания SLOs/SLIs для платформы мониторинга (DevOpsConf, 2025). Как платформа мониторинга получила собственные SLO. По моему конспекту, главная мысль доклада для этого листа одна: в момент сбоя пользователям платформы хватает небольшой части метрик, и доставку стоит строить вокруг неё.
Инструменты
Заголовок раздела «Инструменты»- Клиентские библиотеки Prometheus — прямой путь: тип выбирается в коде, экспозиция отдаётся по HTTP. По моим наблюдениям, чаще берут их, когда хранилище одно и это Prometheus или совместимое с ним.
- OpenTelemetry Metrics API — те же счётчики и гистограммы плюс семантические конвенции для имён. Имеет смысл, когда сервисы уже отдают трейсы через OpenTelemetry или хранилищ несколько; по моим наблюдениям, ради одних метрик на него переходят редко.
- promtool check metrics — линтер экспозиции из поставки Prometheus: проверяет согласованность имён и умеет оценивать кардинальность. Удобен отдельным шагом в CI.
Best practices
Заголовок раздела «Best practices»Самый подробный публичный рассказ о том, как метрики ведут себя на масштабе, — разбор Cloudflare, опубликованный в марте 2023 года. На тот момент у них работало 916 экземпляров Prometheus и около 4,9 миллиарда временных рядов. Интереснее чисел то, как устроен вход. Каждое приложение по умолчанию может отдать не больше 200 рядов, меток на ряд — не больше 64. Хочешь больше — лимит поднимается явной правкой в конфигурации, и CI перед слиянием проверяет, что у серверов Prometheus хватит запаса на добавку. Автор формулирует правило коротко: перешёл отметку в 200 рядов — пора задуматься о своих метриках.
Тип метрики я выбираю от вопроса, который ей зададут. Счётчик только растёт, смотрят у него на скорость роста, и отвечает он на «сколько раз и как часто». Gauge отвечает на «сколько сейчас». Для числа событий он не годится: между двумя опросами всплеск успевает появиться и исчезнуть, и в хранилище от него не остаётся ничего. С длительностью сложнее. Выбор между гистограммой и summary выглядит делом вкуса, пока сервис живёт в одной реплике, а документация Prometheus говорит прямо: готовые квантили агрегировать нельзя, и общий p90 по нескольким репликам из них не собрать. Гистограмма хранит распределение. Перцентиль по ней считается на стороне запроса, за любое окно и по любому набору реплик. Там же стоит совет при возможности брать нативные гистограммы: в Prometheus они стабильны с версии 3.8.0, но их сбор по-прежнему включается явно.
Среднее прячет хвост. В шестой главе SRE Book есть пример, который стоит помнить наизусть: сервис со средней задержкой 100 мс при тысяче запросов в секунду, и один процент запросов у него легко занимает пять секунд. Если страница собирается из нескольких таких сервисов, 99-й перцентиль одного бэкенда становится медианой фронтенда. Отсюда практическое правило: длительность собирают распределением, а не одним числом. Границу бакета полезно поставить ровно на порог, по которому сервис будут судить. Оговорка есть в документации Prometheus: когда порог поменяется, раскладку бакетов придётся менять в коде.
Набор метрик я собираю от типа нагрузки, а не от списка «что бы ещё померить». Для сервиса, который отвечает на запросы, это RED: число запросов, ошибки, длительность. Для ресурса — USE. Как этими наборами искать поломку, разобрано в Systematic Troubleshooting, повторять не буду. Важнее третий случай, про который забывают: конвейеры и пакетные задания, для которых в руководстве Prometheus по инструментированию названы другие ключевые метрики — сколько вошло, сколько в работе, когда обработали последний элемент. У пакетного задания главная метрика одна: время последнего успеха. Конвейер, который встал, по RED выглядит здоровым. Ошибок нет, потому что нет запросов.
Как единая модель выглядит на практике, видно в открытом каталоге метрик GitLab. У каждого сервиса перечислены индикаторы, и каждый раскладывается на три метрики: частоту операций, частоту ошибок и apdex. Насыщение описано отдельным списком. Сервисы с одинаковой раскладкой читаются одним дашбордом и одним набором алертов, и новому сервису не приходится изобретать свою.
Метка — обещание конечного набора значений. Число рядов у метрики равно произведению числа значений её меток, поэтому одна метка с идентификатором пользователя превращает метрику в миллионы рядов. Чем это кончается в деньгах, разобрано в Telemetry Economics; здесь мне важна модель. Ориентир из документации Prometheus строже, чем принято думать: кардинальность метрики держать ниже десяти, большинство метрик вообще без меток, а при сотне значений искать другое решение. Идентификатор запроса или заказа измерением метрики не бывает. Ему место в логе или трейсе.
Я регулярно вижу, как одна и та же величина в соседних сервисах называется по-разному: request_time, http_latency_ms, duration. Каждое имя по отдельности понятно, вместе они делают невозможным общий дашборд и общий алерт. Правила давно написаны: базовые единицы, то есть секунды и байты, а не миллисекунды и мегабайты; единица в суффиксе; _total у накопительного счётчика. Договориться о них с разработкой проще до первого сервиса, чем после двадцатого. Держать договорённость помогает promtool check metrics в CI.
Ошибочную метрику не правят на месте. Когда команда доходит до SLO, почти всегда случается озарение: считали не то и не так. Дальше идёт ошибка, которую я считаю самой дорогой в этой теме: формулу меняют в той же метрике под тем же именем. С этого дня ряд состоит из двух несравнимых половин, новые значения могут отличаться от старых на порядки, и ни один график за квартал больше ничего не значит. Рабочий порядок другой. Новая метрика заводится рядом со старой, какое-то время пишутся обе, дашборды и алерты переезжают, и только потом старая удаляется. Образец такого контракта есть у Kubernetes: метрика проходит стадии от alpha до stable, стабильную не переименовывают и не меняют ей тип, а уходит она через объявленное устаревание.
Не все метрики равны, и проверяется это двумя вопросами. Позволяет ли метрика оценить здоровье сервиса прямо сейчас? И если она перестанет обновляться, помешает ли это чинить сервис в ту же минуту, пока идёт инцидент? Метрик, прошедших оба вопроса, обычно немного. Остальное добавлено на всякий случай или из любопытства, и разделение полезно не ради порядка: от него зависит доставка. Важные метрики идут в хранилище кратчайшим путём. Остальные могут ехать через буфер и теряться первыми, когда плохо самой системе мониторинга.
Метрики отвечают не на все вопросы, и три границы стоит назвать прямо. Первая — отдельный запрос. Метрика знает, что один процент запросов медленный, и не знает, какие именно; за этим идут в трейсы и логи. Вторая — малый трафик. На десяти запросах в час перцентиль не работает как сигнал: каждое значение в нём — один конкретный запрос. Третья — корректность. Вопрос про остатки и цены из той таблицы упирается сюда же: сервис, который исправно отдаёт неверную цену, по всем своим метрикам здоров. Такое ловят сверкой данных и проверками снаружи, а не счётчиком внутри.
Связанные листья
Заголовок раздела «Связанные листья»- Systematic Troubleshooting — те же RED, USE и золотые сигналы, но как метод поиска поломки. Метрики, которых нет, в день инцидента уже не добавить.
- Telemetry Economics — что решения о метках и рядах стоят в деньгах и как держать бюджет на телеметрию.
- SLO Engineering — SLI собирается из метрик этого листа; гистограмма с бакетом на пороге — половина готового индикатора.
- SLI-based Alerting — какие метрики превращаются в алерт и по какой формуле.
- Symptom vs Cause Alerting — метрики причин остаются на дашборде, будят метрики симптомов.
- Performance & Profiling — когда метрика показала хвост, а откуда он берётся, видно только в профиле.
- Logging и Distributed Tracing — куда уходят идентификаторы, которым не место в метках.
Открытые вопросы
Заголовок раздела «Открытые вопросы»Перевод классических гистограмм на нативные я для себя не закрыл. Формально это та самая смена метрики, про которую выше сказано «новая рядом со старой», но у гистограммы длительности потребителей больше, чем у любой другой метрики сервиса: дашборды, алерты, SLO. Как провести такой переезд без разрыва истории, я пока не знаю.
Рядом лежит OpenTelemetry. Я не уверен, где проходит граница, после которой он окупается для метрик, а не только для трейсов. Семантические конвенции закрывают спор об именах, но приносят свою модель и свой слой сбора. Если у вас есть опыт такого перехода на живых сервисах, расскажите через PR.
И вопрос из начала листа остаётся открытым. Как превратить в метрику «цены и остатки показаны правильно», я хорошего общего ответа не видел. Сверка с источником истины работает, но это уже не инструментирование сервиса, а отдельная проверка со своей надёжностью.