- PVSM.RU - https://www.pvsm.ru -
Внедрял SIEM-системы и системы комплексного мониторинга. Подключал и парсил источники, нормализировал события различных доменов данных. Сейчас занимаюсь анализом данных, разработкой контентных модулей для решения задач мониторинга и информационной безопасности в компании VolgaBlob.
Ознакомившись с опытом использования трассировок для мониторинга микросервисных архитектур от сообщества и крупных игроков в области Observability (DataDog [1]):
Как мы делаем трейсинг в условиях тысяч сервисов и миллионов спанов в секунду [2]
Как мы в Авито анализируем 5 миллионов трейсов и проводим архитектурный надзор [3]
Мы решили реализовать инструменты анализа трассировок на нашем продукте Smart Monitor, чтобы оценить правильность выбранного направления в разработке функциональных модулей и возможности системы.
Стандарт хорошо задокументирован, включая основные компоненты и способы интеграции. Поэтому подробно останавливаться на этом не буду. Вот полезные ссылки:
Немного про сам продукт. Smart Monitor [8] является платформой сбора и анализа данных. Ключевые возможности:
Движок pipeline like запросов
Набор компонентов и модулей для IT-мониторинга (РСМ, инвентаризация [9]) и SIEM систем (UBA [10], Менеджер инцидентов [11])
Дашборды, задачи по расписанию
Подробнее описано на сайте [12]. Под капотом хранилище OpenSearch, плюс возможность использовать ClickHouse (нативно), либо подключать иные базы данных через jdbc.
Вдохновившись докладом Как мы в Авито анализируем 5 миллионов трейсов и проводим архитектурный надзор [3], было принято решение на базе платформы Smart Monitor решить следующие задачи:
Сделать удобные визуальные инструменты анализа трассировок и сервисов — решается дашбордами и поисковым движком.
Построить карту инфраструктуры (провести инвентаризацию сервисов и операций, построить модель зависимостей) — решается модулем инвентаризации.
Сформировать инструмент поиска первопричин проблем — решается формированием ресурсно-сервисной модели микросервисов.
Предоставить возможность создания и управления жизненным циклом инцидентов — решается поисковым движком и модулем Менеджер инцидентов.
В результате, задачи архитектурного надзора хорошо соотносились с реализованными модулями, поэтому решения сводились к корректной трансформации данных для имеющихся модулей.
Здесь ничего нового не было изобретено. Использовался базовый механизм сбора данных в OpenSearch [13], предполагающий использование Otel Collector [14] в связке с Data Prepper [15] для формирования документов трассировок и их отправки в кластер OpenSearch. В дальнейшем мы планируем отказаться от Data Prepper в пользу собственного сервиса трансформации данных. Однако для первой версии модуля трассировок этого компонента достаточно.
Для быстрого старта нам нужен был продукт, построенный на микросервисной архитектуре. Мы взяли демо-приложение [16], предоставляемое OpenTelemetry. Сервис является магазином телескопического оборудования, который состоит из 19 сервисов. Сервисы разворачиваются в докере.
В модуле использовалась два домена данных:
спаны трассировок
записи связей сервисов
{
"_index": "otel-v1-apm-span-000001",
"_type": "internal:otel-v1-apm-span:",
"_id": "efcf79b98104f430",
"_score": 0,
"_source": {
"droppedLinksCount": 0,
"traceId": "3371e97cd5b83f8e0619c919e39cda6a",
"instrumentationScope": {
"name": "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc",
"version": "0.60.0"
},
"resource": {
"attributes": {
"process@runtime@name": "go",
"host@name": "1ad5865b3c7d",
"os@description": "Alpine Linux 3.21.3 (Linux 1ad5865b3c7d 6.10.14-linuxkit #1 SMP Sat May 17 08:28:57 UTC 2025 aarch64)",
"service@name": "product-catalog",
"telemetry@sdk@version": "1.35.0",
"process@executable@name": "product-catalog",
"telemetry@sdk@name": "opentelemetry",
"docker@cli@cobra@command_path": "docker compose",
"process@command_args": "["./product-catalog"]",
"process@pid": 1,
"process@executable@path": "/usr/src/app/product-catalog",
"process@runtime@description": "go version go1.22.12 linux/arm64",
"os@type": "linux",
"telemetry@sdk@language": "go",
"process@owner": "root",
"process@runtime@version": "go1.22.12"
}
},
"kind": "SPAN_KIND_SERVER",
"traceGroupFields": {
"endTime": "2025-07-22T10:49:41.200Z",
"durationInNanos": 24000000,
"statusCode": 0
},
"droppedEventsCount": 0,
"traceGroup": "HTTP GET",
"serviceName": "product-catalog",
"parentSpanId": "3a803bed798334f4",
"spanId": "efcf79b98104f430",
"traceState": "",
"name": "oteldemo.ProductCatalogService/GetProduct",
"startTime": "2025-07-22T10:49:41.197253796Z",
"links": [],
"droppedAttributesCount": 0,
"durationInNanos": 57583,
"endTime": "2025-07-22T10:49:41.197311379Z",
"events": [
{
"name": "feature_flag",
"attributes": {
"feature_flag@variant": "on",
"feature_flag@key": "productCatalogFailure",
"feature_flag@provider_name": "flagd"
},
"time": "2025-07-22T10:49:41.197286712Z",
"droppedAttributesCount": 0
},
{
"name": "Error: Product Catalog Fail Feature Flag Enabled",
"attributes": {},
"time": "2025-07-22T10:49:41.197289962Z",
"droppedAttributesCount": 0
}
],
"status": {
"code": 2,
"message": "Error: Product Catalog Fail Feature Flag Enabled"
},
"span": {
"attributes": {
"rpc@method": "GetProduct",
"rpc@service": "oteldemo.ProductCatalogService",
"app@product@id": "OLJCESPC7Z",
"rpc@grpc@status_code": 13,
"rpc@system": "grpc"
}
}
}
}
{
"_index": "otel-v1-apm-service-map",
"_type": "internal:otel-v1-apm-service-map:",
"_id": "KXDQMdubpQ73lmXPjpx3vA==",
"_score": 1,
"_source": {
"kind": "SPAN_KIND_CLIENT",
"traceGroupName": "HTTP GET",
"destination": {
"resource": "Currency/Convert",
"domain": "currency"
},
"serviceName": "frontend",
"hashId": "KXDQMdubpQ73lmXPjpx3vA==",
"target": null
}
}
События карты сервисов формируются компонентом Data Prepper и являются результатом ETL-процесса трансформации данных трассировок. Сущность связи интерпретируется вот так:
сервис
frontendвызывает ресурсCurrency/Convertу сервисаcurrency.
Первый этап — формирование дашбордов мониторинга и анализа трассировок и сервисов. Структура дашбордов и переходов между ними построена по логике от общего к частному.
Результаты разработки дашбордов на скриншотах, я не буду останавливаться подробно на каждом из них, только подсвечу интересные моменты.
На дашборде детализации трассировки есть пара интересных моментов:
Диаграмму вызовов мы позаимствовали у OpenSearch Dashboards, реализацию собственной диаграммы отложили на следующий релиз модуля.
Граф вызовов очень приятный (написали сами) и визуализирует маршруты с ошибками в контексте трассировки.
Остальные дашборды.
Визуализации строятся на движке поиска, который использует pipeline like язык.
$service$ и $resource$ — это токены, значения для которых формируются из фильтров на дашборде.
Механизм инвентаризации простой:
Из otel-v1-apm-service-map формируем измерения (сервисы, ресурсы) и связи.
Используем измерения и связи в модуле инвентаризации.
В результате имеем два типа актива, связанные между собой.
Это позволяет построить маршруты между сервисами через ресурсы.

И получить полную карту маршрутов.

Модель здоровья строиться на трех основных показателях сервисов:
Количество операций в единицу времени — деградирует при отсутствии операций.
Количество ошибок операций — деградирует при росте ошибок.
Продолжительность операций — деградирует при увеличении задержек.
Вручную формировать модель здоровья для продукта, в котором более 1000 сервисов, невозможно. Поэтому формирование модели выполняется скриптом, который использует:
Шаблоны метрик (для каждого сервиса всегда доступны три метрики).
Сформированные связи между сервисами в рамках инвентаризации.
{
"title": "Ошибки операций",
"description": "Количество спанов, выполненных с ошибкой",
"source": {
"search": {
"query": "source otel-v1-apm-spann| search serviceName="{{ service }}"n| peval is_error_span = if(status.code > 1, 1, 0)n| aggs sum(is_error_span) as errors by name",
"time_field": "startTime",
"earliest": "now-4m",
"latest": "now"
},
"schedule": {
"cron": {
"expression": "* * * * *",
"timezone": "Europe/Moscow",
"schedule_delay": 0
}
},
"lock_duration_seconds": 10,
"calculation_field_name": "errors"
},
"type": "NUMBER",
"units": "ед",
"drilldown": null,
"thresholds": {
"static": {
"base_severity": "NORMAL",
"ranges": [
{
"above": 0,
"severity": "NORMAL"
},
{
"above": 2,
"severity": "HIGH"
}
]
}
},
"split_by_entity_params": {
"enabled": true,
"entity_key_field_name": "name",
"aggregation_function": "MAX",
"entity_thresholds": [
{
"entity_pattern": "*",
"thresholds": {
"static": {
"base_severity": "MEDIUM",
"ranges": [
{
"above": 0,
"severity": "NORMAL"
},
{
"above": 2,
"severity": "HIGH"
}
]
}
}
}
]
}
}
Скрипт запускается по расписанию и не является частью системы. Он использует API для создания сервисов и метрик в нотации РСМ и запускается отдельной службой.
В результате, мы получаем модель здоровья.
Помимо прямой зависимости от собственных метрик, на состояние сервиса влияет состояние дочерних сервисов.

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

Итак, мы решили задачу прикладного применения современных стандартов мониторинга в нашей платформе и упаковали объекты знаний и конфигурации в контентный модуль. Компоненты продукта решают задачи построения системы мониторинга состояния микросервисов на базе трассировок OpenTelementry. Но сделана только база, адаптировать решение придется на каждой инсталляции. Помимо этого остается ряд вопросов, которые необходимо решить:
Операции агрегации спанов трассировок на OpenSearch выполняются медленно при больших объемах данных. Возможности для оптимизации такого рода появились только в 3.0. В частности — Star-tree index [17]. Но, кажется, вариант использовать ClickHouse для процессинга трассировок выглядит более удачным. Такие задачи уже решались и не раз [18]. Поэтому смотрим в эту сторону.
Ввиду количества микросервисов в продуктах и значимой разнице в профилях нагрузки (количество запросов, длительность обработки, сложность операций), метрики должны рассчитываться адаптивно. Использования заданных порогов для метрик приведет только к большому количеству false-positive состояний. Доверия к такой системе не будет.
Веса между сервисами в рамках ресурсно-сервисной модели должны рассчитываться динамически, используя коэффициент GB (Graceful Degradation).
От использования Data Prepper и визуализации OpenSearch Dashboards нужно отказываться. Качество этих open-source решений не соответствует качеству продукта.
Большие инсталляции содержат очень много сервисов (тысячи), строить модели и инвентаризировать такие инсталляции нужно с применением дополнительных логических фильтров. Делать множество моделей по доменам продукта, критичности для бизнеса и пользователей.
На этом все, если у вас есть опыт работы с трассировками и альтернативными решениями для их анализа — буду рад обменяться опытом в комментариях.
Автор: timofey_melnikov
Источник [19]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/monitoring/426990
Ссылки в тексте:
[1] DataDog: https://www.datadoghq.com/product/apm/
[2] Как мы делаем трейсинг в условиях тысяч сервисов и миллионов спанов в секунду: https://highload.ru/moscow/2023/abstracts/11229
[3] Как мы в Авито анализируем 5 миллионов трейсов и проводим архитектурный надзор: https://highload.ru/moscow/2024/abstracts/13640
[4] APM Terms and Concepts: https://docs.datadoghq.com/tracing/glossary/
[5] Observability primer: https://opentelemetry.io/docs/concepts/observability-primer/
[6] Мониторинг бизнес-процессов с помощью OpenTelemetry: https://habr.com/ru/companies/oleg-bunin/articles/865690/
[7] Наблюдаемость “по-взрослому”: опыт внедрения OpenTelemetry: https://habr.com/ru/articles/919214/
[8] Smart Monitor: https://smartmonitor.ru/ru/
[9] инвентаризация: https://smartmonitor.ru/ru/smstore/inv
[10] UBA: https://smartmonitor.ru/ru/smstore/uba
[11] Менеджер инцидентов: https://smartmonitor.ru/ru/smstore/im
[12] на сайте: https://smartmonitor.ru/ru/smstore/core
[13] OpenSearch: https://docs.opensearch.org/docs/latest/observing-your-data/trace/getting-started/
[14] Otel Collector: https://opentelemetry.io/docs/collector/
[15] Data Prepper: https://docs.opensearch.org/docs/latest/data-prepper/
[16] демо-приложение: https://opentelemetry.io/docs/demo/architecture/
[17] Star-tree index: https://docs.opensearch.org/docs/latest/field-types/supported-field-types/star-tree/
[18] раз: https://clickhouse.com/blog/how-we-used-clickhouse-to-store-opentelemetry-traces
[19] Источник: https://habr.com/ru/articles/933512/?utm_source=habrahabr&utm_medium=rss&utm_campaign=933512
Нажмите здесь для печати.