Как спроектировать метрику
Подумайте, как и для чего вы будете пользоваться метрикой. Узнайте, как реализовать эти требования в StatsHouse:
Затем создайте метрику и начинайте отправлять данные.
Что представляют собой метрики в StatsHouse?
Под "мониторин гом" мы понимаем получение статистических данных. Метрика — это минимальная единица настройки, сбора и просмотра статистики.
Структура метрики в StatsHouse выглядит так:
Здесь counter
, value
и unique
— это основные типы метрик.
StatsHouse не хранит точное значение метрики за каждый момент времени. Вместо этого в системе хранятся агрегаты, относящиеся к временным интервалам.
Типы метрик
Одно и то же можно измерить по-разному. Разные способы измерений — это и есть типы метрик.
Определения и примеры можно посмотреть в таблице:
Тип метрики | Что она измеряет? | Примеры |
---|---|---|
counter | Подсчитывает, сколько раз произошло то или иное событие. | Количество вызовов методов API Количество запросов к серверу Количество ошибок, полученных при отправке сообщений |
value | Измеряет величину какого-либо параметра. Также подсчитывается количество измерений. | Как долго сервис генерирует ленту новостей? Какова загрузка процессора на этом хосте? Каков размер ответа (в байтах)? |
unique | Подсчитывает количество уникальных событий. Также подсчитывается общее количество событий. | Количество уникальных пользователей, отправивших пакеты в сервис |
Тип метрики влияет на то, какие описательные статистики доступны и имеют смысл для метрики. Например, перцентили доступны только для value-м етрик. А накопленные значения нельзя посмотреть для типа unique.
Узнайте, как включить запись перцентилей и настроить отображение описательных статистик в интерфейсе.
Не путайте типы метрик с типами данных в языках программирования.
Детали реализации
Метрики типа counter
(счётчик) и value
(значение) являются числами типа float64
. Для counter
и
value
StatsHouse обрезает всё, что выходит за пределы диапазона [-max(float32)..max(float32)]
.
Это сделано для того, чтобы при суммировании и других операциях над ними, в том числе внутри базы данных, никогда
не получать значения, равные бесконечности.
Счётчики (тип counter
)
Представьте себе гипотетический продукт. Для него нам нужно получить количество принятых пакетов в секунду. Пакеты могут иметь различные форматы и статусы.
Когда приложение получает пакет, оно отправляет событие в StatsHouse:
{"metrics":[ {"name": "toy_packets_count",
"tags":{"format": "JSON", "status": "ok"},
"counter": 1}] }
или
{"metrics":[ {"name": "toy_packets_count",
"tags":{"format": "TL", "status": "error_too_short"},
"counter": 1} ]}
Представим событие в виде ряда в обычной базе данных. При посекундной агрегации мы получим таблицу, которая показана ниже. Для каждой полученной комбинации значений тегов в ней появится ряд с соответствующим счётчиком:
timestamp | metric | format | status | counter |
---|---|---|---|---|
13:45:05 | toy_packets_count | JSON | ok | 100 |
13:45:05 | toy_packets_count | TL | ok | 200 |
13:45:05 | toy_packets_count | TL | error_too_short | 5 |
Количество рядов в такой таблице - это кардинальность метрики.
Значения (тип value
)
Предположим, нам нужно знать размер полученных пакетов. Вот как может выглядеть наша метрика:
{"metrics":[ {"name": "toy_packets_size",
"tags":{"format": "JSON", "status": "ok"},
"value": [150]} ]}
или
{"metrics":[ {"name": "toy_packets_size",
"tags":{"format": "JSON", "status": "error_too_short"},
"value": [0]} ]}
Для метрик с типом value
помимо счётчика StatsHouse вычисляет агрегат:
sum, min, max.
timestamp | metric | format | status | counter | sum | min | max |
---|---|---|---|---|---|---|---|
13:45:05 | toy_packets_size | JSON | ok | 100 | 13000 | 20 | 1200 |
13:45:05 | toy_packets_size | TL | ok | 200 | 7000 | 4 | 800 |
13:45:05 | toy_packets_size | TL | error_too_short | 5 | 10 | 0 | 8 |
Метрика этого типа является массивом, так что можно отправлять несколько значений одновременно.
Приём регулярных значений
Для случаев, когда требуется записывать значение в секунду (т. е. отслеживать "уровень" какого-то по казателя), клиентские библиотеки StatsHouse стараются отправлять каждое значение в середине календарной секунды. Агенты определяют секунду в соответствии с календарной секундой. StatsHouse не гарантирует, что каждая секунда содержит ровно одно измерение, но старается сделать вероятность этого максимальной. Если вы хотите отправлять значения именно так, укажите метку времени явным образом.
Счётчики уникальных значений (тип unique
)
Этот тип метрики позволяет оценить число разных уникальных целых значений. Для строковых значений используется хеш строк.
Предположим: мы получаем пакеты, содержащие идентификаторы отправителей. Мы можем подсчитать, сколько существует разных отправителей:
{"metrics":[ {"name": "toy_packets_user",
"tags":{"format": "JSON", "status": "ok"},
"unique": [17]} ]}
Метрика этого типа является массивом, так что можно отправлять несколько значений одновременно.
timestamp | metric | format | status | counter | unique |
---|---|---|---|---|---|
13:45:05 | toy_packets_user | JSON | ok | 100 | uniq(17, 19, 13, 15) |
13:45:05 | toy_packets_user | TL | ok | 200 | uniq(17, 19, 13, 15, 11) |
13:45:05 | toy_packets_user | TL | error_too_short | 5 | uniq(51) |
Множества хранятся в сжатом виде. StatsHouse исп ользует функцию наподобие HyperLogLog: сами значения недоступны, поэтому можно узнать только оценку кардинальности множеств.
Для счётчиков уникальных значений StatsHouse хранит агрегаты: sum, min, max (те же, что и для метрик-значений,
интерпретированных как int64
и округленных до float64
). Знание диапазона значений бывает полезно для отладки.
Детали реализации
Счётчики уникальных значений имеют тип int64
, который интерпретируется как 64 бита. Этот тип выбран вместо uint64
потому, что в некоторых языках нет uint64
. Эти значения рассматриваются как хеши.
При оценке кардинальности множеств, составленных из этих значений, StatsHouse проверяет их на равенство и неравенство.
При записи агрегатов (sum
, min
, max
) StatsHouse сначала интерпретирует эти значения как int64
и затем
конвертирует их в тип float64
— они пишутся в те же колонки, что и агрегаты обычных значени й.
Как сочетаются типы метрик
В таблице показано, как значения разных типов сочетаются в рамках одной метрики:
Что вы отправите | Что вы получите |
---|---|
"counter":100 | counter |
"value":[1, 2, 3] | counter (размер массива), value (sum , min , max ) |
"unique":[17, 25, 37] | counter (размер массива), value (sum , min , max ), unique |
"counter":6, "value":[1, 2, 3] | Пользовательское семплирование |
"value":100,"unique":100 |
Если вы меняете тип существующей метрики, данные могут стать непонятными или неинформативными.
Рекомендуем отправлять в метрику данные одного и того же типа.
Счётчики для метрик с типом value
и unique
Если вы отправляете массив данных типа value
или unique
, размер этого массива становится счётчиком для этой
метрики. Вам не нужно отдельно создавать счётчик для метрик типа value
или unique
.
Вы можете указать такой счётчик вручную, чтобы реализовать
пользовательское семплирование.
Теги
Теги помогают учитывать дополнительные характеристики данных, влияющие факторы или контекст.
С помощью тегов можно фильтровать и группировать данные. Иногда их называют лейблами
или ключами
.
Теги — это пары имя—значение.
Представьте, что вы проводите A/B-тест: кнопки с каким сочетанием цвета и текста будут работать эффективнее? Чтобы ответить на этот вопрос, можно измерить количество нажатий на кнопку и использовать такие теги:
Метрики с тегами помогают проверять гипотезы о данных. Можно задавать, например, такие вопросы:
"Различается ли количество ошибок для разных платформ?"
или
"Из какого региона приходит наибольшее количество запросов? Различно ли оно для разных окружений?"
Чтобы ответить на эти вопросы, можно создать следующие метрики (используется клиентская библиотека для Python):
statshouse.value("error_rate", {"platform": "web"}, 42.5)
↑ ↑ ↑ ↑
metric name ↑ ↑ measurement
tag name ↑
tag value
или
statshouse.value("request_rate", {"env": "production", "region": "moscow"}, 42.5)
↑ ↑ ↑ ↑ ↑ ↑
metric name ↑ ↑ ↑ ↑ measurement
tag name ↑ tag name ↑
tag value tag value
Затем можно отфильтровать или сгруппировать данные с помощью тегов. По умолчанию в UI группировка отключена.
Сколько тегов можно использовать?
Для каждой метрики можно использовать 16 тегов:
- тег
0
обычно обозначаетenvironment
(см., как настроить этот тег), - теги
1...15
— для любых других характеристик.
Тег String top (Топ строк) дополнительный, он ведёт себя не так, как другие:
- тег
__s
.
"А если мне нужно больше тегов?"
К сожалению, пока увеличить количество тегов нельзя. Мы планируем добавить такую возможность позже.
Имена тегов
При отправке данных можно использовать системные имена тегов (0..15
). Для удобства можно использовать
алиасы (пользовательские имена).
Допускаются следующие символы:
- латинский алфавит,
- целые числа,
- подчёркивание.
Не начинайте имена тегов с подчёркиваний. Они предназначены для служебных метрик StatsHouse.
Одни и те же имена тегов можно использовать для разных метрик.
В интерфейсе StatsHouse можно редактировать имена тегов и добавлять к ним описания.
Значения тегов
Значения тегов обычно являются строками. Чтобы работать с ними быстрее, StatsHouse отображает их в значения int32
.
Этот огромный маппинг string
↔int32
общий для всех метрик. Чтобы не допустить его неконтролируемого увеличения,
бюджет на создание значений тегов ограничен. При превышении этого бюджета возникает ошибка типа Mapping flood.
Длина и символы
Значения тегов должны содержать только печатаемые символы UTF-8. Все непечатаемые символы заменяются дорожным знаком.
Максимальная длина значения тега — 128 байтов (остальное обрезается). Также выполнется нормализация: с обеих сторон делается TRIM, все последовательности Unicode-пробелов внутри значения тега заменяются на один ASCII пробел.