Tracing

Наблюдение за приложениями

Существуют три основных набора данных, которые приложения могут предоставлять для отображения своего состояния:

  • Логи
  • Метрики
  • Трассировки

Первые два типа достаточно распространены. Логи существуют почти у всех приложений. Метрики, «со скрипом» но внедряются. Во всяком случае необходимость наличия метрик понимают большинство разработчиков и администраторов. А вот, как и для чего следует использовать трассировку (tracing) понимают далеко не все.

Когда мы говорим о трассировке, мы вводим два понятия: span и trace (или distributed trace).

Span

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

Span содержит данные, описывающие этот временной диапазон:

  • Имя.
  • Данные, связанные со временем выполнения.
  • Дополнительные метаданные (attributes).
  • Структурированные логи (span events). По аналогии с обычными логами — любые сообщения, которые следует сохранить в span.

Span формируется путём вызова соответствующей функции SDK в коде приложения. При его формировании автоматически записывается время создания span.

Обычно во время формирования span в него добавляются атрибуты. В дальнейшем эти атрибуты можно использовать для поиска интересующих вас групп span.

В промежутке между началом и завершением span, в него можно добавлять span events, формирующие набор логов.

Завершение span формируется, в зависимости от языка программирования, либо непосредственным вызовом соответствующей функции библиотеки или автоматически.

Обычно span создают в начале какой-либо функции и закрывают его в конце этой функции.

Trace

Трассировка содержит в себе набор span. Когда вы формируете span, вы указываете trace_id к которому это span относится. Trace может содержать span различных функций в одном приложении или объединять span из нескольких приложений.

Таким образом мы можем получить информацию например о прохождении запроса через несколько приложений.

Open Telemetry

Open Telemetry, также сокращенно известная как OTel — это независимая от поставщика платформа наблюдения с открытым исходным кодом для инструментирования, генерации, сбора и экспорта телеметрических данных, таких как трассировки, метрики, журналы. В качестве отраслевого стандарта он изначально поддерживается рядом поставщиков.

Помимо трассировок, OTel позволяет генерировать метрики и логи. Но эти два направления могут не поддерживаться библиотеками для конкретных языков программирования. Поэтому на данным момент OTel рекомендуется использовать только для работы с трассировками.

Текущее состояние поддержки OTel различных языков программирования.

OTel collector

В рамках проекта OTel разработан collector, позволяющий принимать трассировки от приложений и передавать их в различные базы данных, для дальнейшего хранения и обработки.

Для приёма данных используются различные receivers.

После получения данных их можно обработать при помощи processors.

И отправить в различные системы хранения, обработки — exporters.

Jaeger

Jaeger — это система для работы с трассировками, позволяющая: получать трассировки, сохранять их в различных базах данных, показывать и анализировать трассировки.

В состав приложения входят:

  • jaeger-agent
  • jaeger-collector
  • jaeger-query
  • jaeger-ingester

Ранее в проекте был набор клиентских библиотек для различных языков программирования. Но на данный момент рекомендуется использовать библиотеки проекта OTel.

Agent

Демон, принимающий span от клиентов по протоколу UDP и пересылающий их на агрегирующие коллекторы.

Предполагается, что на каждом хосту, где будут работать приложения, запускается по агенту. Приложения по UDP скидывают на агенты span-ы. Таким образом в приложениях нет задержки по отправке span в систему трассировки.

В случае kubernetes, агент можно добавлять непосредственно в под приложения, как дополнительный контейнер.

В дальнейшем агент отправляет полученные span на коллекторы по протоколу TCP.

Клиенты для взаимодействия с агентом используют специальный протокол — Thrift.

Collector

Принимает span от агентов или непосредственно от приложений. Поддерживает только TCP соединения.

  • HTTP — jaeger.thrift
  • OTLP gRPC
  • OTLP HTTP

Отсылает span в различные системы хранения. Например: Cassandra, Elastic Search, Open Search.

Query

Jaeger query — это сервис, который предоставляет API для извлечения трассировок из хранилища и предоставляет веб-интерфейс для поиска и анализа трассировок.

Ingester

Jaeger ingester — это сервис, который считывает трассировки из Kafka и записывает их в серверную часть хранилища. По сути, это урезанная версия Jaeger collector, которая поддерживает Kafka в качестве единственного протокола ввода.

Итого

В дальнейших примерах в качестве обработчика трейсинга будет использоваться Jaeger. Данные трейсинга будут сохраняться в OpenSearch.

Примеры приложений будут написаны на Python с использованием библиотеки opentelemetry-python.

Разработчикам

Следующая часть предназначена для разработчиков приложений. Хотя, админам тоже рекомендуется её почитать, для понимания, что можно ожидать от разработчиков :).

Админам и DevOps-ам

Добавлю чуть позднее.