Невозможно точно узнать, что происходит внутри удаленной или распределенной системы, даже если они запущены на локальном ПК. Именно телеметрия предоставляет всю информацию о ходе внутренних процессов. Эти данные могут быть в виде логов, метрик или Distributed Trace.
В блоге поговорим отдельно о каждом из этих форматов, а также рассмотрим, чем полезен протокол OpenTelemetry и как вы можете гибко настроить телеметрию.
Большая IT-система и даже некоторые виды бизнеса не могут существовать без телеметрии. Поэтому этот процесс следует поддерживать и внедрять в проекты, если его нет.
Простейший тип данных в телеметрии. Логи бывают двух типов:
Обычно логовать все данные не нужно. Оцените систему, найдите (если этого не сделали) наиболее уязвимые и ценные части системы. Скорее всего, там нужно добавить логов. Иногда вам нужно будет использовать логориентированное программирование. В моей практике был проект десктопного приложения на WPW, плохо работавший с потоками. Единственный шанс увидеть, что происходило – логовать каждый шаг.
Более сложные данные по сравнению с логами. Могут быть ценны и для команды разработки, и для бизнеса. Метрики также выделяют автоматические и мануальные:
Эти данные необходимы для работы с распределенными системами, находящимися не на одном инстансе. То есть, мы не знаем, какой инстанс и какого сервиса обрабатывает тот или иной реквест в определенный промежуток времени. Все зависит от построения системы. Здесь возможны следующие варианты:
На первой схеме слева клиент посылает реквест в BFF, а тот – отдельным трем сервисам. В центре показана ситуация, когда реквест поступает в первый сервис, отправляющий его во второй, а тот уже в третий. Схема справа отображает, как сервис посылает реквесты в Message Broker. Далее он распределяет их между вторым и третьим сервисами.
Думаю, вы сталкивались с подобными системами, и примеров можно привести множество. Эти схемы сильно отличаются от монолитов. В системах с одним инстансом нам известен стек вызовов от контроллера к базе данных. Поэтому можно относительно легко обнаружить, где и что произошло в течение определенного API call. Скорее всего, эту информацию предоставляет фреймворк.
Но в распределенных системах невозможно увидеть весь флоу. Каждый сервис имеет отдельную систему логирования. При отправке реквеста на BFF мы видим, что произошло внутри, но не знаем, что происходило в сервисах 1, 2 и 3. Именно для такой ситуации придумали Distributed Trace. Вот пример работы:
Разберем подробно. Здесь User Action идет на API Gateway, затем – на сервис А, далее – на сервис В. В результате создается вызов в базу данных. При их отправке в систему на выходе получим сходную с приведенной схему.
Здесь хорошо видна продолжительность каждого процесса: от User Action до Database. К примеру, видим, что вызовы шли один за другим. Время между вызовом API Gateway и Service A пришлось скорее на этап HTTP-соединения. Время между вызовом Service B и Database понадобилось на сэтап в базу данных и обработку данных. Так что можно оценить, где и сколько времени потрачено на каждую операцию. Это возможно благодаря механизму Correlation ID.
В чем суть? Обычно в монолитных приложениях при логовании система привязывает логи и экшены к process ID или thread ID. Здесь механизм тот же, но мы его искусственно добавляем к реквестам. Посмотрим на пример:
При старте в Web Application экшена Order Service он видит добавленный Correlation ID. Так сервис понимает, что он является частью цепочки, и передает маркер дальше следующим сервисам. Они, со своей стороны, понимают себя как часть большого процесса. В результате каждый элемент будет логовать данные так, чтобы система видела все происходящее в течение многоэтапного экшена.
Передача Correlation ID может происходить по-разному. Например, в HTTP эти данные чаще всего передаются как один из параметров хедеров. В сервисах Message Broker обычно записывается внутри месседжа. Хотя, возможно, в каждой платформе есть SDK или библиотеки, которые помогут реализовать этот функционал.
Часто формат телеметрии старой системы не поддерживается в новой. Это приводит ко многим проблемам при переходе с одной системы в другую. Например, так было с AppInsight и CloudWatch. Данные не группируются, а значит, что-то работает не так.
OpenTelemetry позволит обойти следующие проблемы. Это протокол передачи данных посредством объединенных библиотек OpenCensus и OpenTracing. Первую создавали разработчики Google для сбора метрик и трейсов, вторую – специалисты Uber только для трейсов. В какой-то момент компании поняли, что работают фактически над одной задачей. Потому решили объединить усилия и сделать универсальный формат отображения данных.
Благодаря протоколу OTLP логи, метрики и трейсы посылаются в едином формате. Согласно репозиторию OpenTelemetry, сегодня известные IT-гиганты контрибьютят этот проект. Он пользуется спросом в продуктах, собирающих и отображающих данные (например, Datadog и New Relic). Также он помогает в системах, которым нужна телеметрия (Facebook, Atlassian, Netflix и другие).
Есть много SDK для популярных языков программирования. Однако все они имеют разные возможности. Обратите внимание на таблицу. Трейсинг имеет стабильные версии повсеместно, кроме PHP и JS SDK. А вот с метриками и логами до сих пор не очень хорошо во многих языках. Где-то есть только альфа-версии, где-то экспериментальные, иногда вообще не реализована имплементация протокола. По собственному опыту скажу, что на сервисах на .NET все работает нормально. Здесь и простое подключение, и надежность логования.
Коллектор состоит из четырех компонентов:
health_check
. С его помощью можно посылать реквест на эндпоинт и понять, работает ли коллектор. Экстеншены показывают многое: сколько ресиверсов и экспортеров в системе, как они работают и т.д.На этой схеме есть два типа данных — метрики и логи (обозначенные разными цветами). Логи идут через свой процессор в Jaeger. Метрики следуют через другой процессор, имеют свой фильтр и отправляются в два источника данных: OTLP и Prometheus. Это дает гибкие возможности анализа данных. Ведь разный софт имеет разные способы демонстрации телеметрии.
Интересный момент: данные можно принимать из OpenTelemetry и отправлять их туда же. То есть в определенных случаях одинаковые данные вы можете отправлять в один и тот же коллектор.
Есть много способов, как построить систему сбора телеметрии. Одна из самых простых схем изображена на иллюстрации ниже. Здесь есть один .NET-сервис, который посылает OpenTelemetry сразу в New Relic:
При необходимости схему можно дополнить агентом. Он может выступать в качестве хост-сервиса или бэкграунд-процесса внутри сервиса, собирать данные и отправлять их в New Relic:
Идем дальше – добавляем в схему еще одно приложение (например, на Node JS). Оно будет передавать данные напрямую в коллектор. А первое будет делать это через собственного агента с помощью OTLP. Коллектор будет отправлять данные уже в две системы. Например, метрики будут идти в New Relic, а логи — в Datadog:
Сюда можно добавить Prometheus как источник данных. К примеру, когда в команде появился человек, который любит этот инструмент и хочет использовать его. Здесь данные все равно будут собираться в New Relic и Datadog:
Систему телеметрии можно усложнять до бесконечности, адаптируя ее под свой проект. Вот еще один пример:
Здесь есть несколько коллекторов, каждый из которых собирает данные по-своему. Агент в .NET-приложении отправляет данные в New Relic и в коллектор. При этом один коллектор может отправлять информацию в другой, так как OTLP посылается другому источнику данных. Он может делать с ними что угодно. В результате первый коллектор отфильтровывает нужные данные и передает следующему. Последний – распределяет логи, метрики и трейсы между New Relic, Datadog и Azure Monitor. Благодаря этому механизму анализировать телеметрию можно так, как удобно вам.
Прежде всего, это гибкость. Рассмотрим данное свойство на практике. Для этого тестирования я сделал проект по приведенной схеме:
Все начинается с Angular-приложения, которое отправляет HTTP-реквесты в Python-приложение. Тот со своей стороны посылает реквесты в приложения на .NET и Node JS. Они работают по своим сценариям. Приложение на .NET отправляет в Azure Service Bus реквесты и хендлит их в Report Service.
Затем посылает метрики о том, сколько реквестов он обработал. Дополнительно .NET отправляет реквесты в MS SQL. Реквести Node JS идут в Azure Blob Queue и Google. То есть система эмулирует какую-нибудь работу. Во всех приложениях используются автоматические системы отправки трейсов в коллектор.
Начнём с разбора docker-compose файла.
Здесь собран этап нескольких сервисов BFF. Среди закоменченых – Jaeger, помогающий смотреть трейсы.
Предусмотрен еще один софт для просмотра трейсов – это Zipkin.
Также есть MS SQL и собственно коллектор. В последнем указан config-файл и много портов, на которые можно что-то отправлять.
Сonfig-файл содержит набор главных топиков: recievers
, exporters
, processors
, extensions
. Завершает все service
. Он выступает как конструктор всего этого.
Ресивер один. Это otlp
, то есть именно Open Telemetry Protocol. Хотя можно подключать и другие ресиверы (например, Prometheus). Ресивер можно конфигурировать. Предположим, сетить allowed_origins
, как в моем примере.
Следующий элемент – экспортеры. С ними можно отправлять метрики в Prometheus.
health_check
. Он является эндпойнтом, проверяющим активность коллектора.
pipelines
, traces
, metrics
. С ними понятно, какой тип данных откуда берется, чем он обрабатывается, куда отправляется. В этом примере трейсы из ресивера отправляются для логования на два бекенда, а для метрик используется Prometheus.
Разберем, как это работает в действительности. Фронтенд посылает реквесты в бэкенд, а бэкенд использует BFF для отправки реквестов. Создаем круг и видим результаты. Среди них, например, есть некоторые реквесты со статусом 500.
BFF
вызвал BILLINGSERVICE
. В нем работают middleware, посылается реквест в Azure и есть http.post
, который отправлялся в Azure. В результате получен статус CREATED
. Далее система сетапила и отправляла реквест в Google.
POSTALSERVICE
, в котором упал один реквест. Посмотрим на него внимательнее и увидим описание ошибки: ServiceBusSender has already been closed…
Поэтому в следующий раз нужно быть осторожным с ServiceBusSender
. Также здесь можно увидеть отправку нескольких запросов на MS SQL.
А еще вспомним о health_check
. Он покажет, работает ли наш коллектор вообще.
Поэтому преимущества использования OpenTelemetry Protocol очевидны. Это гибкая система сбора, обработки и отправки телеметрии. Особенно удобно в сочетании с Docker, который я использовал при создании этого демо.
Однако всегда помните об ограничениях OTLP. В случае с трейсами все достаточно хорошо. А целесообразность использования этого протокола для метрик и логов зависит от готовности библиотек и SDK конкретной системы.
В благословенные офисные времена, когда не было большой войны и коронавируса, люди гораздо больше общались…
Вот две истории из собственного опыта, с тех пор, когда только начинал делать свою карьеру…
«Ты же программист». За свою жизнь я много раз слышал эту фразу. От всех. Кто…
Отличные новости! Если вы пропустили, GitHub Copilot — это уже не отдельный продукт, а набор…
Несколько месяцев назад мы с командой Promodo (агентство инвестировало в продукт более $100 000) запустили…
Пару дней назад прочитал сообщение о том, что хорошие курсы могут стать альтернативой классическому образованию.…