Добавить в корзинуПозвонить
Найти в Дзене

Как реализовать получение метрик из Grafana для мониторинга системы?

В микросервисной архитектуре нужно точно знать, как работает ваша система.
Мониторинг помогает не только обнаружить проблемы, но и понять бизнес-метрики: сколько заказов обработано, какие внешние системы тормозят и тд. OpenTelemetry или Prometheus.Client Библиотеки реализованы для большинства популярных языков, в том числе для C#/.NET. Метрики могут быть как автоматические (время обработки запросов), так и ваши собственные (количество обработанных заказов). .NET Для добавления собственных метрик можно использовать классы Meter и Counter (или интерфейс IMetricFactory), более подробнее можно изучить в документации - https://learn.microsoft.com/ru-ru/dotnet/core/diagnostics/metrics-collection - Pull-модель: При использовании выше перечисленных библиотек добавляется HTTP метод /metrics, который будет отдавать текущее состояние метрик вашего сервиса, чтобы какой-то другой сервис периодически его опрашивал и сохранял к себе изменения.
Такая модель взаимодействия называется Pull-моделью.
ht
Оглавление

В микросервисной архитектуре нужно точно знать, как работает ваша система.
Мониторинг помогает не только обнаружить проблемы, но и понять бизнес-метрики: сколько заказов обработано, какие внешние системы тормозят и тд.

1) Подключение библиотеки сбора метрик

OpenTelemetry или Prometheus.Client

Библиотеки реализованы для большинства популярных языков, в том числе для C#/.NET.

Метрики могут быть как автоматические (время обработки запросов), так и ваши собственные (количество обработанных заказов).

.NET

Для добавления собственных метрик можно использовать классы Meter и Counter (или интерфейс IMetricFactory), более подробнее можно изучить в документации - https://learn.microsoft.com/ru-ru/dotnet/core/diagnostics/metrics-collection

2) Получение метрик из сервиса

- Pull-модель:

При использовании выше перечисленных библиотек добавляется HTTP метод /metrics, который будет отдавать текущее состояние метрик вашего сервиса, чтобы какой-то другой сервис периодически его опрашивал и сохранял к себе изменения.
Такая модель взаимодействия называется Pull-моделью.
https://learn.microsoft.com/ru-ru/dotnet/core/diagnostics/metrics-collection#view-metrics-in-grafana-with-opentelemetry-and-prometheus

Пример отображаемых данных в /metrics:

# HELP http_requests_total Total number of HTTP requests
# TYPE http_requests_total counter
http_requests_total{method="POST",endpoint="/api/order",status="200"} 1024

- Push-модель:

Также можно использовать OTLP (OpenTelemetry Protocol), когда наше приложение само отправляет данные в заданный сервис сбора метрик.

3) Использование Prometheus (самая популярная система мониторинга)

Данный компонент занимается сбором и агрегацией метрик, опрашивая сервисы на основе Pull-модели (вызывая метод /metrics).

Он записывает метрики в свою БД (Time-series DB) в виде снепшота с временной точкой.
На подобии:

  • 10:10 -> count = 2
  • 10:11 -> count = 5
  • 10:12 -> count = 10

Если развернуто несколько копий одного приложения, то Prometheus будет опрашивать каждую ноду отдельно и это можно реализовать с помощью Service Discovery, который знает сколько копий приложений развернуто и где они находятся (их IP).
Prometheus можно настроить на использование Service Discovery, вместо того чтобы указывать конкретные адреса каждой копии приложения (автоматическое обнаружение подов в k8s).

Также к метрикам можно добавлять дополнительную информацию, которые называются метками (Labels).

Метки – это пары "ключ-значение", добавляющие контекста метрикам.
Например, метрика - количество обработанных запросов, а метки – тип HTTP метода (method="POST"), а также статус код (status ="200").
Получается у нас
метрика становится не плоской, а многомерной, храня в себе “разновидность”.

Временной ряд – это комбинация метрики и всех ее меток.
Каждая комбинация хранит собственную историю изменений (снепшоты).
И важно понимать, что при изменении любой метки создается новый временной ряд!

Есть так же такое понятие как КАРДИНАЛЬНОСТЬ.

Каждая уникальная комбинация меток создает новый временной ряд.
Например, если захотите использовать user_id="3232" в качестве метки, то вы можете создать миллионы временных рядов, что положит ваш Prometheus.
Поэтому не используйте метки со значениями, которые могут принимать тысячи разных вариантов.

Высокая кардинальность убивает производительность Prometheus.

4) Grafana для просмотра метрик

Сначала добавляем Prometheus в качестве источника данных, а для “рисования” графиков на основе метрик необходимо будет использовать язык PromQL.

Примеры запросов:

  • Отобразить количество ошибок в аутбоксе у сервиса "orders" за последние 3 минуты (если их больше 0):
    sum(increase(outbox_sharded_events_states_total{service="orders",state="Failed"}[3m])) by (state, external_service, service) > 0
  • Вычислить 99 перцентиль времени выполнения запроса получения ассортимента:
    clamp_max(histogram_quantile(0.99, sum(rate(get_bundle_assortment_time_bucket{assortment_limit_count=~"50"}[$__rate_interval])) by (le)), 5000)

Кстати для каждой копии вашего приложения Prometheus создает отдельный временной ряд (добавляются метки instance и pod), поэтому sum нам поможет объединить в один график данные от всех копий сервиса.

Итог:

После такой реализации можно будет добавлять дашборды для мониторинга ваших сервисов (системы) и бизнес функционала, а также создавать алерты для оповещения о появившихся проблемах на основе изменяющихся метрик.