Справка Business Studio
Переход на сайт нейросети Perplexity AI для поиска информации о Business Studio. Подробнее о возможности см. по ссылке

Содержание справки



Мониторинг работы приложения через OpenTelemetry

Когда приложение работает на сервере, снаружи не видно, что в нём происходит: почему медленно отвечает API, где «теряется» запрос и какой компонент стал причиной сбоя. OpenTelemetry (OTel) решает эту проблему — это открытый стандарт и набор библиотек для сбора трейсов, метрик и логов о работе приложения.

OTel подключается к приложению, фиксирует его работу — часто автоматически — и отправляет данные в систему хранения. При этом он не привязывает вас к конкретному вендору: данные можно экспортировать в Prometheus, OpenSearch и другие backend-системы, а анализировать и визуализировать их в Grafana.

Вы один раз внедряете мониторинг — и получаете понятную картину работы сервиса, быстрее находите узкие места и разбираете инциденты без привязки к одной платформе мониторинга.

Что показывают метрики, exemplars и логи

Для мониторинга Приложения (bs-backend) используется два основных вида данных: метрики и логи.

1. Метрики: сколько запросов в секунду обрабатывается, как долго они выполняются, сколько в них ошибок, сколько памяти и процессора занято. Они показывают, что происходит в целом.

2. Логи: текстовые записи о событиях. В каждую запись добавляется trace_id запроса.

Вместе с метриками передаются образцы (exemplars): отдельные реальные запросы, попавшие в данный интервал времени. Образец отображается на графике точкой, и чем выше точка, тем дольше выполнялся запрос. В нём есть trace_id, по которому в логах можно найти конкретный запрос, «испортивший» график.

Как данные проходят через систему:

1. Приложение с подключённым OTel SDK само отправляет метрики в Prometheus (push-модель, в отличие от привычной схемы, где Prometheus сам опрашивает приложение) и пишет логи с trace_id.

2. Prometheus хранит метрики вместе с образцами.

3. Fluentd собирает логи приложения и пересылает их в OpenSearch.

4. OpenSearch хранит и индексирует логи, по trace_id находятся все записи одного запроса.

5. Grafana показывает метрики из Prometheus и связанные с ними exemplars. По образцу можно перейти к поиску в OpenSearch по trace_id. Сами логи просматриваются в OpenSearch, а Grafana обеспечивает переход к ним с графика.

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

Что нужно для подключения

1. Запущенный Prometheus с двумя флагами запуска:

command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--web.enable-otlp-receiver'          # приём метрик по OTLP/HTTP  
- '--enable-feature=exemplar-storage'   # хранение TraceId (Exemplars)

2. Сетевой доступ к Prometheus (соединение инициирует стенд).

3. Grafana с подключённым источником данных Prometheus (см. раздел Настройка Grafana).

Настройка отправки метрик в Prometheus

1. Настройка Endpoint

Для отправки метрик необходимо настроить Endpoint одним из следующих способов:

  • Через переменные окружения (рекомендуется)

Этот вариант рекомендуется для Docker-развёртываний, поскольку позволяет задавать параметры подключения отдельно для каждого стенда, не изменяя конфигурацию приложения и не пересобирая образ. Например, для тестового и рабочего окружений можно указать разные адреса Prometheus через файл .env.

В .env файле укажите:

# Полный адрес приёмника метрик Prometheus (вместе с путём)
OTEL_EXPORTER_OTLP_ENDPOINT=http://<адрес_prometheus>:<порт>/api/v1/otlp/v1/metrics
# Для Prometheus всегда http/protobuf
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
# Как часто отправлять метрики, мс (по умолчанию минута, рекомендуем 15 секунд, т.е. 15000 мс)
OTEL_METRIC_EXPORT_INTERVAL=15000
# Имя службы, по нему метрики различаются в Grafana
OTEL_SERVICE_NAME=bs-backend

В docker-compose.yml в блок environment сервиса передайте эти переменные.

    environment:
      - OTEL_SERVICE_NAME=${OTEL_SERVICE_NAME}
      - OTEL_EXPORTER_OTLP_ENDPOINT=${OTEL_EXPORTER_OTLP_ENDPOINT}
      - OTEL_EXPORTER_OTLP_PROTOCOL=${OTEL_EXPORTER_OTLP_PROTOCOL}
      - OTEL_METRIC_EXPORT_INTERVAL=${OTEL_METRIC_EXPORT_INTERVAL}
  • Через appsettings.json (альтернатива)

Этот вариант подойдёт, если в используемом процессе развёртывания настройки приложения принято хранить в appsettings.json и удобнее управлять ими непосредственно в конфигурационном файле. Например, если конфигурация уже поддерживается в таком виде и не требуется переопределять параметры для разных окружений через переменные среды.

"OpenTelemetry": {
  "ServiceName": "bs-backend",
  "Otlp": {
    "Endpoint": "http://<адрес_prometheus>:<порт>/api/v1/otlp/v1/metrics",
    "Protocol": "HttpProtobuf"
  }
}

Переменные окружения имеют приоритет над appsettings. Интервал отправки (OTEL_METRIC_EXPORT_INTERVAL) задаётся только переменной окружения.

2. Настройка работы с несколькими экземплярами

Можно добавить настройки для работы с несколькими экземплярами, если это требуется (например, bs-backend-1 и bs-backend-2).

Такая дополнительная настройка необходима, если:

  • Требуется различать метрики нескольких экземпляров одного сервиса, использующих общий Prometheus.
  • Требуется различать метрики нескольких стендов, использующих общий Prometheus.

Примечание! Если на стенде работает по одному экземпляру каждого сервиса и Prometheus используется только для него, то дополнительная настройка не требуется.

Задайте каждому свой OTEL_SERVICE_NAME, иначе метрики разных экземпляров сольются в один ряд. Если это реплики одной службы, оставьте одинаковое имя и различайте их так:

OTEL_RESOURCE_ATTRIBUTES=service.instance.id=bs-backend-1

Если Prometheus общий для нескольких стендов, добавьте окружение:

OTEL_RESOURCE_ATTRIBUTES=deployment.environment=stage

3. Перезапуск стенда для применения изменений

Перезапустите стенд с помощью скрипта bs_menu.sh. Проверьте, что переменные попали в контейнер:

docker exec <контейнер> printenv | grep OTEL

4. Проверка, что метрики начали считываться

Сделайте несколько запросов к приложению, подождите 15-60 секунд и откройте Prometheus (http://<адрес_prometheus>:<порт>), вкладка Graph:

http_server_request_duration_seconds_count

Должны появиться ряды с лейблом service_name="bs-backend".

Образцы можно проверить через API:

http://<адрес_prometheus>:<порт>/api/v1/query_exemplars?query=http_server_request_duration_seconds_bucket

В ответе должны быть объекты с trace_id. Образцы появляются только у запросов, для которых была создана трассировка, поэтому на малом числе запросов их может быть мало.

Настройка Grafana

Источник данных: Connections - Data sources - Add new data source - Prometheus.

  • URL: адрес Prometheus.
  • В разделе Exemplars нажмите Add: Label name = trace_id. Если логи находятся в Loki или Tempo, выберите его как Internal link. Если нет, укажите URL поиска по TraceId в вашей системе логов, подставив ${__value.raw} на место идентификатора.
  • Нажмите Save & test.

Панель: Dashboards - New - Add visualization - выберите источник Prometheus, вставьте запрос и включите переключатель Exemplars в параметрах запроса. Без него точки на графике не появятся.

Какие графики полезно строить и как их читать

В документации OpenTelemetry, Prometheus и Grafana, а также в каталогах готовых дашбордов (например, Grafana Dashboards) можно найти множество графиков, построенных на метриках OpenTelemetry. Большинство из них рассчитаны на общие случаи и содержат много лишнего. Ниже приведены только самые полезные для мониторинга Business Studio: нагрузка, время ответа, ошибки и самые медленные маршруты. Для каждого графика указан запрос и описано, как читать результат.

Нагрузка: запросов в секунду (RPS)

sum by (service_name) (rate(http_server_request_duration_seconds_count[5m]))

Показывает, сколько запросов обрабатывает приложение.

Как читать: Резкий рост означает всплеск нагрузки, падение до нуля означает, что запросы не приходят или приложение недоступно. Смотрите вместе с графиком задержки: рост RPS и рост времени ответа вместе означает, что система упирается в ресурсы.

Время ответа (задержка): p50 / p95 / p99

histogram_quantile(0.95, sum by (le, service_name) (rate(http_server_request_duration_seconds_bucket[5m])))

Замените 0.95 на 0.50 (медиана) или 0.99 (самые медленные).

Как читать:

  • p50 показывает, как работает приложение для обычного запроса.
  • p95 / p99 показывают «хвост», то есть насколько плохо бывает самым неудачным запросам. Именно по ним пользователи замечают тормоза.
  • Если p50 в норме, а p99 высокий, то тормозят отдельные запросы или операции, и в этом помогают образцы.
  • Постепенный рост всех линий означает деградацию (нагрузка, рост данных, утечки).
  • При малом трафике p95 и особенно p99 ненадёжны, потому что нужно хотя бы пара сотен запросов в окне, при меньшем количестве запросов значения могут заметно колебаться от одного интервала к другому, а отдельные медленные запросы — непропорционально сильно влиять на результат. В итоге график не всегда отражает реальную картину производительности сервиса. .

Образцы (Exemplars)

Дополнительная функция графика задержек - точечные маркеры поверх основного графика. Каждая точка соответствует реальному запросу из соответствующей корзины гистограммы. Чем выше точка, тем дольше он выполнялся.

Как пользоваться:

  1. Найдите на графике всплеск задержки.
  2. Наведите курсор на точку рядом с ним и скопируйте trace_id.
  3. Найдите этот TraceId в логах OpenSearch (либо по ссылке из точки, если она настроена). В логах будут все записи именно этого запроса, и видно, на каком шаге он замедлился.
  4. После изучения истории запроса расширьте поиск на временной диапазон вокруг него на том же bs-backend.Это поможет увидеть, какие ещё события происходили в этот момент и могли повлиять на время обработки запроса: ошибки, таймауты, задержки других запросов или проблемы зависимых сервисов.

Доля ответов с кодом ошибки

Доля ответов с кодом 5xx:

sum by (service_name) (rate(http_server_request_duration_seconds_count{http_response_status_code=~"5.."}[5m])) / sum by (service_name) (rate(http_server_request_duration_seconds_count[5m]))

Как читать: в норме линия около нуля. Любая устойчивая доля 5xx означает ошибки на стороне сервера, при этом нужно искать их в логах. Рост 4xx ("4..") чаще означает проблемы на стороне клиентов или авторизации. Код 499 (клиент оборвал соединение) лучше исключать из расчётов: http_response_status_code!="499"

Самые медленные маршруты

topk(5, histogram_quantile(0.95, sum by (le, http_route) (rate(http_server_request_duration_seconds_bucket[5m]))))

Показывает, какие именно методы API медленнее остальных (по лейблу http_route).

Типовые проблемы

Симптом Что проверить
В Prometheus нет метрик Задан ли Endpoint (docker exec <контейнер> printenv | grep OTEL). Правильный ли адрес и порт. Есть ли сеть от стенда до Prometheus (nc -zv -w3 <адрес> <порт>)
Запрос к Endpoint возвращает 404 В Prometheus не включён флаг –web.enable-otlp-receiver (для проверки: ответ 405 на GET означает, что приёмник включён)
Метрики есть, образцов нет Нет флага –enable-feature=exemplar-storage, не включён переключатель Exemplars в запросе Grafana, или не настроен trace_id в источнике данных
Значения двух экземпляров суммируются и отображаются единой линией У экземпляров одинаковые OTEL_SERVICE_NAME и нет различающего service.instance.id
Ошибка compose unexpected type map Смешаны форматы в environment (список и словарь). Пишите все строки как - KEY=value
Данные появляются с большой задержкой Не задан OTEL_METRIC_EXPORT_INTERVAL, по умолчанию метрики отправляются раз в минуту
Таблица 1. Симптомы проблемы и способы их решения

Если Prometheus недоступен, приложение продолжает работать нормально: экспорт метрик просто пишет ошибки отправки в лог и повторяет попытки. Когда связь восстановится, передача данных восстановится автоматически.