ОтелПрометеусЧитательМетрик
Prometheus-читатель метрик — переводит метрики OTel в Prometheus text format.
Описание
ОтелПрометеусЧитательМетрик реализует pull-модель сбора метрик для Prometheus. Метрики собираются по запросу и переводятся в семейства Prometheus, а текст в формате Prometheus text exposition 0.0.4 формирует библиотека prometheus — зависимость пакета.
Всегда использует кумулятивную временную агрегацию (Cumulative).
Формат выдачи
СобратьВТексте выдаёт text format 0.0.4 (text/plain; version=0.0.4; charset=utf-8), имена экранируются по схеме underscores. Строк # UNIT, времени создания серий _created и exemplars в text format нет. Семейства читателя содержат их для OpenMetrics: если читатель зарегистрирован в реестре библиотеки prometheus (см. Collect), формат выдачи реестра выбирает библиотека.
Имена метрик
Перевод имён OTel в имена Prometheus выполняется только в этом читателе: имена и единицы инструментов, а также OTLP-экспорт не меняются. По спецификации Prometheus and OpenMetrics Compatibility (стратегия UnderscoreEscapingWithSuffixes, других стратегий трансляции нет):
- недопустимые символы имени заменяются на
_:http.server.requests→http_server_requests; - единица UCUM переводится в слово Prometheus и добавляется суффиксом перед суффиксом типа:
s→_seconds,By→_bytes,%→_percent(полная таблица — в спецификации); - части единицы в фигурных скобках отбрасываются (
{request}суффикса не даёт), скоростьX/YстановитсяX_per_Y(By/s→_bytes_per_second), безразмерная1суффикса не даёт; - суффикс не добавляется, если имя уже оканчивается на эту единицу;
- к монотонной сумме (Counter) добавляется
_total, если имя им ещё не оканчивается; имя, которое уже оканчивается на_total, не меняется (requests_total_totalтак и выводится). Строки# HELPи# TYPEсчётчика в text format относятся к имени сэмпла (# TYPE http_requests_total counter), в OpenMetrics — к имени без_total(# TYPE http_requests counter).
| Инструмент OTel | Имя сэмпла Prometheus |
|---|---|
Гистограмма http.server.request.duration, s | http_server_request_duration_seconds_bucket / _sum / _count |
Счётчик net.io, By | net_io_bytes_total |
Счётчик http.requests, {request} | http_requests_total |
Датчик cpu.utilization, 1 | cpu_utilization |
Одноимённые метрики одного типа объединяются в одно семейство. Метрика другого типа пропускается целиком, в том числе когда совпадает только имя в строке # TYPE text format: счётчик foo с единицей By (# TYPE foo_bytes_total counter) и датчик foo_bytes_total, info-метрика x и датчик x_info. Точка отбрасывается, если сэмпл с тем же именем и набором лейблов уже есть в выдаче, в том числе в другом семействе. Например, так бывает у метрик a.b и a_b одной области, у счётчика foo с единицей By (сэмпл foo_bytes_total) и датчика foo_bytes_total или у счётчика foo (сэмпл foo_created в OpenMetrics) и датчика foo_created. В обоих случаях в лог пишется предупреждение.
Лейблы атрибутов
Атрибуты точек становятся лейблами (спецификация, раздел Metric Attributes):
- в имени лейбла символы вне
[a-zA-Z0-9_], включая:, заменяются на_:http:method→http_method; - строковое значение выводится как есть, двоичные данные — в base64, пустое значение (
Неопределено) — пустой строкой, остальные — в JSON:true/false,2.5,["x","y"], отображение — JSON-объектом{"nested":true}(спецификация, раздел Common / AnyValue representation for non-OTLP protocols); - если ключи совпали после замены символов (
a.bиa_b), значения склеиваются через;в порядке исходных ключей:a_b="first;second". Так же склеиваются атрибут точки и лейбл области (otel.scope.nameиotel_scope_name:otel_scope_name="user;lib") или скопированный атрибут ресурса; при равных ключах первым идёт значение атрибута точки.
Лейблы области
На каждый сэмпл добавляются лейблы области инструментирования (спецификация, раздел Instrumentation Scope):
| Лейбл | Значение |
|---|---|
otel_scope_name | имя области |
otel_scope_version | версия области |
otel_scope_schema_url | адрес схемы области |
otel_scope_<атрибут> | атрибуты области, имя лейбла нормализуется как у атрибутов точек |
Пустые имя, версия и адрес схемы лейбла не дают. Атрибут области, который после префикса совпадает с otel_scope_name, otel_scope_version или otel_scope_schema_url, отбрасывается. Поэтому серии метров с одинаковыми именем и версией, но разными адресами схемы или атрибутами не склеиваются.
Атрибуты ресурса
Ресурс отдельной метрикой (target_info) не выводится: этот раздел спецификации (Resource Attributes) в статусе Development. По умолчанию атрибуты ресурса в лейблы метрик не копируются; УстановитьАтрибутыРесурсаВЛейблах копирует выбранные атрибуты.
Подсказка типа датчика
Датчик и немонотонная сумма выводятся по подсказке prometheus.type из метаданных метрики (ОтелДанныеМетрики.Метаданные(), спецификация, раздел Gauges). Метаданные задаёт источник данных, например производитель метрик, переносящий метрики Prometheus. Типы unknown, info и stateset есть только в OpenMetrics, в text format они выводятся так, как предписывает спецификация для форматов без этих типов:
prometheus.type | Text format | OpenMetrics |
|---|---|---|
нет, gauge, другое значение | gauge | gauge |
unknown (и unkown) | untyped | unknown |
info | gauge <имя>_info, значение 1 | info <имя>, сэмпл <имя>_info, значение 1 |
stateset | gauge | stateset |
Единица и время создания серий
В OpenMetrics слово единицы, добавленное к имени, выводится строкой # UNIT (спецификация, раздел Metric Metadata), кроме info и stateset. У семейства одна строка # UNIT — первой метрики; отличающаяся единица одноимённой метрики отбрасывается с предупреждением, точки метрики остаются.
Время старта точки выводится временем создания серии <имя>_created (секунды): у счётчика после значения, у гистограммы и сводки после _count. У датчика времени создания нет.
# TYPE http_duration_seconds histogram
# UNIT http_duration_seconds seconds
http_duration_seconds_bucket{le="0.005"} 0
...
http_duration_seconds_sum 0.2
http_duration_seconds_count 1
http_duration_seconds_created 1700000000.5Гистограммы
Гистограмма выводится Prometheus histogram (спецификация, раздел Histograms as Prometheus Histograms): бакеты _bucket по возрастанию границы le с накопленным количеством, последний — +Inf, затем _sum и _count. Если у точки нет суммы, _sum не выводится. Так бывает у реверсивного счётчика и датчика с View гистограммы — SDK не собирает сумму, если инструмент записывает отрицательные значения, — и у точки продюсера метрик: в OTLP сумма гистограммы необязательна.
# TYPE queue histogram
queue_bucket{le="0"} 1
queue_bucket{le="10"} 2
queue_bucket{le="+Inf"} 2
queue_count 2Сводки (Summary)
Сводка (ОтелТипМетрики.Сводка, обычно от продюсера метрик) выводится Prometheus summary (спецификация, раздел Summaries): квантили — сэмплами с лейблом quantile по возрастанию квантиля, затем _sum и _count. Exemplars сводки не выводятся.
# TYPE rpc_duration_seconds summary
rpc_duration_seconds{quantile="0.5"} 0.2
rpc_duration_seconds{quantile="0.99"} 0.9
rpc_duration_seconds_sum 5.5
rpc_duration_seconds_count 12Exemplars
Exemplars выводятся только в OpenMetrics (спецификация, разделы Sums, Histograms и Exemplar Conversion); в text format их нет:
- у счётчика — последний exemplar точки, у каждого бакета гистограммы — последний из попавших в бакет (граница бакета — верхняя, значение на границе попадает в этот бакет);
- ID трассировки и спана выводятся лейблами
trace_idиspan_id, они приоритетнее одноимённых атрибутов; время exemplar выводится в секундах; - отфильтрованные атрибуты (
filteredAttributes) выводятся лейблами, если вместе сtrace_idиspan_idне превышают лимит OpenMetrics 1.0 — 128 символов в именах и значениях лейблов; иначе exemplar выводится без них; - exemplars датчика, немонотонной суммы и сводки не выводятся.
# TYPE jobs counter
jobs_total 5 # {span_id="b7ad6b7169203331",trace_id="0af7651916cd43dd8448eb211c80319c"} 0.7 1700000003
jobs_created 1700000000.5
# EOFОтброшенные данные
О любой отброшенной метрике, точке или метаданных в лог пишется предупреждение: конфликт TYPE, повторный сэмпл, экспоненциальная гистограмма (text format и OpenMetrics её не поддерживают), сумма или гистограмма с временной агрегацией Дельта, ошибка перевода метрики, описание или единица метрики, отличные от # HELP или # UNIT семейства, в которое она добавлена.
Отдача по HTTP
HTTP-сервера в читателе нет: метрики отдаёт приложение. Из своего HTTP-обработчика /metrics (например, контроллера Winow) верните СобратьВТексте с заголовком Content-Type из ContentType. Либо зарегистрируйте читатель в реестре библиотеки prometheus (Collect) и отдавайте реестр, например, через prometheus-metrics.
Конструктор
Без параметров. Создаётся через ОтелПостроительПровайдераМетрик.
Методы
ДобавитьМетр
Регистрирует метр в читателе.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
Метр | ОтелМетр | — | Метр для регистрации |
ДобавитьПродюсер
Регистрирует продюсер внешних метрик (MetricProducer): его метрики, например сводки (Summary) из мостов к другим библиотекам, выдаются вместе с метриками метров. Читатель вызывает Произвести(Ресурс, ТаймаутМс) с ресурсом провайдера, у которого зарегистрирован (без провайдера — с ресурсом по умолчанию), и таймаутом 0: сбор по запросу срока не имеет. Сумма или гистограмма продюсера с временной агрегацией Дельта пропускается с предупреждением: Prometheus принимает только кумулятивные данные. Сбой продюсера (исключение или статус ошибки) логируется, делает результат сбора ошибкой и не лишает выдачу остальных метрик.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
Продюсер | ИнтерфейсПродюсерМетрик | — | Продюсер метрик |
СобратьВТексте
Собирает все метрики и возвращает их в text format 0.0.4 (см. Формат выдачи): семейства СобратьСемейства, сериализованные библиотекой prometheus (Prometheus.СериализоватьВТекст). Сбой сбора одного метра или инструмента логируется и не лишает выдачу метрик остальных; о сбое сообщает РезультатСбора. Если метрик нет или читатель закрыт, возвращает пустую строку. Одновременные запросы собирают метрики по очереди: callback-и инструментов одного сбора завершаются до начала следующего.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
РезультатСбора | ОтелРезультатЭкспорта | Неопределено | Выходной параметр: ошибка, если сбор метра, инструмента, callback-а или продюсера завершился сбоем (их метрики не попадают в выдачу) или читатель закрыт; таймаут, если callback или продюсер не уложился в таймаут; иначе успех |
Возвращает: Строка — метрики в text format 0.0.4
ContentType
Возвращает значение заголовка Content-Type ответа СобратьВТексте.
Возвращает: Строка — "text/plain; version=0.0.4; charset=utf-8"
ПолучитьВременнуюАгрегацию
Возвращает тип временной агрегации для инструмента.
Всегда возвращает Кумулятивная независимо от типа инструмента.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
ТипИнструмента | Строка | — | Тип инструмента |
Возвращает: ОтелВременнаяАгрегация.Кумулятивная()
СобратьСемейства
Собирает все метрики как семейства в промежуточном формате библиотеки prometheus: Соответствие с ключами Имя, Тип, Справка, Единица, Сэмплы.
Тип— вид метрики Prometheus:counter,gauge,histogram,summary,unknown,infoилиstateset; в text format библиотека выводитunknownкакuntyped,infoиstateset— какgauge.Единица— слово единицы для строки# UNITв OpenMetrics.- У сэмпла —
ИмяСэмпла,Лейблы,Значение; у квантиля сводки ещёКвантиль(уровень квантиля: по нему библиотека упорядочивает квантили серии). - У сэмпла счётчика и бакета гистограммы —
Экземпляр(exemplar:Лейблы,Значение,Времяв секундах), у сэмпла счётчика и_countгистограммы и сводки —Создано(время старта точки в секундах).
Имя — имя метрики в строках # HELP и # TYPE text format. У счётчика оно совпадает с именем сэмпла (http_requests_total при стратегии с суффиксами), у info-метрики — с суффиксом _info, у гистограммы это имя без _bucket, _sum и _count. Для OpenMetrics библиотека отрезает суффиксы _total и _info. Результат можно передать в Prometheus.СериализоватьВТекст: в text format 0.0.4 текст будет тот же, что у СобратьВТексте. После Закрыть возвращает пустой массив.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
РезультатСбора | ОтелРезультатЭкспорта | Неопределено | Выходной параметр: ошибка, если сбор метра, инструмента, callback-а или продюсера завершился сбоем (их метрики не попадают в выдачу) или читатель закрыт; таймаут, если callback или продюсер не уложился в таймаут; иначе успех |
Возвращает: Массив — массив семейств метрик Prometheus
Collect
Возвращает семейства метрик (СобратьСемейства) для реестра библиотеки prometheus: читатель регистрируется в CollectorRegistry как custom Collector и выдаётся вместе с метриками библиотеки. Формат выдачи реестра (text format или OpenMetrics) выбирает библиотека. Чтобы обращаться к реестру из своего кода, подключите библиотеку (#Использовать prometheus).
Реестр = Prometheus.РеестрПоУмолчанию();
Реестр.Register(ПрометеусЧитатель);
Текст = Prometheus.СериализоватьВТекст(Prometheus.СобратьМетрики(Реестр));Возвращает: Массив — массив семейств метрик Prometheus
УстановитьАтрибутыРесурсаВЛейблах
Включает копирование атрибутов ресурса в лейблы метрик (resource_constant_labels). По умолчанию атрибуты ресурса не копируются. Значения атрибута точки и атрибута ресурса с тем же именем лейбла склеиваются через ; в порядке исходных ключей, при равных ключах первым идёт значение точки.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
Включаемые | Массив, Неопределено | — | Шаблоны ключей включаемых атрибутов: * — любые символы, ? — один символ; Неопределено — все атрибуты |
Исключаемые | Массив, Неопределено | Неопределено | Шаблоны ключей исключаемых атрибутов, приоритетнее включаемых |
Включаемые = Новый Массив();
Включаемые.Добавить("service.*");
Исключаемые = Новый Массив();
Исключаемые.Добавить("service.instance.id");
ПрометеусЧитатель.УстановитьАтрибутыРесурсаВЛейблах(Включаемые, Исключаемые);СброситьБуфер / СброситьБуферБезОчистки
Совместимость с MetricReader: выгружать нечего (pull-модель).
Возвращает: ОтелРезультатЭкспорта — успех; после Закрыть — ошибка
Закрыть
Очищает зарегистрированные метры и продюсеры. После закрытия сбор возвращает пустой результат с ошибкой, сброс буфера — ошибку.
Возвращает: ОтелРезультатЗакрытия — успех; повторный вызов — ошибка «Reader закрыт»
ЛимитМощности
Возвращает лимит мощности (cardinality limit) читателя по умолчанию для всех видов инструментов. У каждого читателя свои потоки метрик, поэтому лимит действует только на данные этого читателя.
Возвращает: Число — 2000 (значение по умолчанию из спецификации)
ЛимитМощностиДляВида
Возвращает лимит мощности читателя для вида инструмента: заданный УстановитьЛимитМощностиДляВида или общий ЛимитМощности(). Применяется к потокам, для которых View не задал лимит.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
ВидИнструмента | Строка | — | Counter, Histogram, ObservableGauge, ... |
Возвращает: Число
УстановитьЛимитМощностиДляВида
Задаёт лимит мощности читателя для вида инструмента. Действует для инструментов, созданных после вызова.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
ВидИнструмента | Строка | — | Вид инструмента |
Лимит | Число | — | Лимит мощности |
АгрегацияПоУмолчанию
Возвращает агрегацию читателя по умолчанию для вида инструмента (агрегация по умолчанию настраивается функцией вида инструмента). Применяется к потокам, для которых View не задал агрегацию.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
ВидИнструмента | Строка | — | Вид инструмента |
Возвращает: Строка, Соответствие — заданная агрегация; "default" — агрегация спецификации для вида
УстановитьАгрегациюПоУмолчанию
Задаёт агрегацию читателя по умолчанию для вида инструмента. Действует для инструментов, созданных после вызова.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
ВидИнструмента | Строка | — | Вид инструмента |
Агрегация | Строка, Соответствие | — | Агрегация (ОтелАгрегация.Сумма(), "drop", ...) |
ПрометеусЧитатель = Новый ОтелПрометеусЧитательМетрик();
ПрометеусЧитатель.УстановитьАгрегациюПоУмолчанию("UpDownCounter", "drop");АгрегацияГистограммПоУмолчанию
Возвращает агрегацию гистограмм по умолчанию для этого читателя.
Возвращает: Строка, Соответствие — заданная для вида Histogram через УстановитьАгрегациюПоУмолчанию или "explicit_bucket_histogram"
ВременнаяАгрегацияДляВида
Возвращает временную агрегацию потоков читателя: Prometheus принимает только кумулятивные данные.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
ВидИнструмента | Строка | — | Вид инструмента |
Возвращает: ОтелВременнаяАгрегация.Кумулятивная()
Внутренние методы
Экспортированы для вызова из других модулей SDK и для совместимости с интерфейсом читателя (в OneScript нет внутренней видимости), приложению вызывать их не нужно:
Запустить— ничего не делает: у ОтелПериодическийЧитательМетрик метод запускает фоновый сбор, а pull-читателю запускать нечего — метрики собираются по запросу;ЗарегистрироватьУПровайдера— регистрирует читатель у провайдера при его создании и запоминает ресурс провайдера для продюсеров метрик. Читатель регистрируется только у одного провайдера: повторный вызов пишет ошибку в лог и возвращаетЛожь, и провайдер такой читатель не добавляет.
Пример
// Настройка Prometheus-читателя
ПрометеусЧитатель = Новый ОтелПрометеусЧитательМетрик();
Построитель = Новый ОтелПостроительПровайдераМетрик();
Построитель.ЗарегистрироватьЧитатель(ПрометеусЧитатель);
Провайдер = Построитель.Построить();
// В HTTP-обработчике /metrics
ТелоОтвета = ПрометеусЧитатель.СобратьВТексте();
ТипКонтента = ПрометеусЧитатель.ContentType(); // "text/plain; version=0.0.4; charset=utf-8"