20 сентября 2024
Блог
Как Open Telemetry влияет на качество сервисов
Не будем вас томить: Open Telemetry позволяет повысить observability (наблюдаемость) ваших сервисов, что положительно влияет на качество. А что такое observability и причем здесь OpenTelemetry – рассказываем в новой статье.
В программных системах наблюдаемость (Observability) — это возможность собирать данные о выполнении программы, внутренних состояниях модулей и взаимодействии между компонентами. Чтобы улучшить наблюдаемость, программисты используют широкий спектр методов и инструментов.
Она помогает нам понять систему снаружи, позволяя нам задавать вопросы об этой системе, не зная ее внутреннего устройства. Это обеспечение прозрачности процесса работы системы.
Наблюдаемость основывается на данных телеметрии, которые можно разделить на 3 категории: логирование, метрики и трассировка.
Давайте рассмотрим каждую категорию данных поближе.
Логирование
Когда в системе происходит некоторое событие мы записываем его в журнал и при необходимости можем открыть этот журнал и посмотреть, что же происходило в системе. Такие журналы могут быть очень большими, но количество данных можно контролировать при помощи различных уровней и правил.
В качестве хранилища для журнала может выступать все что угодно. Логи можно выводить в консоль, хранить в файле, базе данных или другой системе. Можно отправлять логи сразу в несколько мест. Информация в логах также зависит от того, что туда решил положить разработчик.
Большинство разработчиков стараются придерживаться общих правил написания логов. К примеру, практически любой лог имеет:
- системную информацию (время и дата события, ID события и другая служебная информация);
- уровень лога;
- текст сообщения (например, сообщения об ошибке);
- контекст (дополнительная информация).
Они бывают структурированные и неструктурированные. Неструктурированные логи представляют собой обычные текстовые сообщения, записанные построчно. Структурированные логи пишутся в виде json или xml. Они машиночитаемые и легко могут быть загружены в различные системы для хранения, быстрого поиска и анализа. У нас в качестве такой системы используется Elastic и Kibana.
Метрики
Сравнение чисел всегда был наиболее простым способом что-либо оценить. И метрики как раз позволяют нам провести такую оценку.
Метрика — это количественное измерение какого-то свойства системы в определенный момент ее работы, т.е. метрики отвечают на вопросы «когда?» и «сколько?».
Условно разделить метрики можно на следующие категории:
- Системные метрики - показывают количество потребляемых системных ресурсов, например, процессорное время или оперативная память. Такие метрики обычно предоставляются операционной системой.
- Метрики приложения — это набор неких стандартных метрик, которые можно собирать с инфраструктурных компонентов вашего приложения, например, сборщик мусора или веб-фреймворка.
- А вот Бизнес метрики сами собой не появятся. Они уже зависят от бизнес логики вашего приложения, и только вы сами или бизнес решает, что необходимо считать.
Системные метрики и метрики приложения помогают оценить производительность и доступность системы или спрогнозировать и предупредить о возникновении проблем. Бизнес метрики помогают понять, как те или иные решения влияют на пользователя и бизнес.
Трассировка
Простым языком – это пошаговое выполнение программы.
Каждый день разработчики пользуются трассировкой во время отладки или профилирования. Но для этого приложение собирается в debug-режиме, и разработчик вмешивается в работу приложения. На проде мы так сделать не можем. Для сбора трассировок во время работы приложения их нужно явно создавать, точно так же, как это делается с логами.
Когда мы говорим о трассировке, мы вводим два понятия: span и trace. Span представляет собой логическую единицу работы, которая имеет название операции, время начала операции и продолжительность.
Span могут быть вложенными, упорядоченными для моделирования причинно-следственных связей. В спане так же можно указать набор произвольных данных в виде атрибутов. Обычно span создают в начале какой-либо функции и закрывают его в конце этой функции.
Trace – совокупность всех span в рамках одной операции, например, запроса. Фактически трейс — это спан без «родителя» или верхнеуровневый спан.
Но наибольший интерес для нас представляет распределенная трассировка.
С ростом популярности облачных вычислений и микросервисной архитектуры появилась необходимость и в такого вида трассировке. Она позволяет проследить весь путь выполнения сетевых запросов при прохождении через множество различных компонентов: микросервисов, брокеров, баз данных.
Для выполнения этой задачи нужно связать спан, из которого был сделан удаленный вызов, со спаном который этот вызов принял. Для этого в сетевом запросе передается контекст трассировки, в котором как минимум указывается идентификатор трейса и «родительского» спана.
Существует несколько стандартов передачи контекста трассировки.
- B3 propagation от Zipkin, все еще популярный стандарт
- x-cloud-trace-context от GCP
- В 2018 году консорциум W3C начал работу над своим стандартом, который так и назвался W3C Trace Context. В конце 2021 года стандарт получил статус рекомендации.
Инструменты трассировки
Теперь давайте проследим историю развития инструментов распределенной трассировки.
В 2010 году Google опубликовал статью об инфраструктуре высоко-масштабируемой системы распределенных трассировок Dapper. Саму систему Google в течении нескольких лет использовал для внутренних нужд и в итоге признал полезность для команд разработчиков и эксплуатации. Со временем система обрастала новым функционалам? который изначально не был предусмотрен командой разработки, а сама система не вышла за пределы Google.
2012 год. Вдохновленные идеями Dapper Twitter выпускают свою систему под названием Zipkin с открытым исходным кодом. Zipkin также собирал информацию о времени выполнения и помогал решать проблемы с задержками запросов.
В 2014 году много всего происходило в мире: в Сочи была Олимпиада, а в мире IT появился Kubernetes. kubernetes не является инструментом трассировки, но мир облачных технологий с этого момента точно изменился. Тренд на оркестрацию контейнерами и микросервисную архитектуру стал набирать обороты.
В 2015, через 3 года после появления Zipkin, Uber выкатил свою систему распределенных трассировок под названием Jaeger. Система использовалась для мониторинга, профилирования и решения проблема в микросервисах. Проект так же вошел в Cloud Native Computing Foundation’s и в 2019 году получил статус зрелого проекта.
Также в 2015 к Cloud Native Computing Foundation’s присоединился проект OpenTracing, который предоставлял для микросервисов вендоронезависимое API для распределенной трассировки и проброса контекста.
В 2017 году Google выкатил проект OpenCensus, который так же предоставлял набор различных библиотек для разных языков и позволял собирать метрики, трейсы и экспортировать данные во внешнюю систему в режиме реального времени.
И, наконец, в 2019 году OpenTracing и OpenCensus решили объединиться и сконцентрировать свои силы над общим проектом под названием OpenTelemetry. Взяли, так сказать, все самое лучшее из обоих проектов. OpenTelemetry не ставит целью решение проблем, которые не решали бы OpenTracing и OpenCensus. Основная цель проекта - дать единый стандарт, вместо постоянного соревнования двух стандартов и инструментов.
К концу 2021 года была предоставлена первая общедоступная версия с поддержкой трейсинга.
OpenTelemetry (OTel)
OpenTelemetry — это фреймворк и набор инструментов для создания и управления данными телеметрии. Важным аспектом фреймворка является то, что он вендоронезависимый и инструментонезависимый, его можно использовать со множеством различных Observability бекендов. А еще он бесплатный и опенсорсный.
OpenTelemtry — это в первую очередь четкая спецификация и документация для всех компонентов, включая свой собственный протокол передачи данных. У каждого вида телеметрии есть возможность передавать произвольный набор атрибутов. Проект вводит семантические соглашения для различных категорий библиотек.
API и SDK – два основных модуля фреймворка. Имеются реализации для всех популярных языков программирования. API содержит набор базовых типов и операций для генерации и корреляции данных телеметрии. Можно подключать и использовать во всех библиотеках.
SDK в свою очередь отвечает за настройку, процессинг и экспорт данных. API без SDK не должен влиять на производительность вашего кода. SDK подключается к конечному приложению.
OpenTelemtry также предоставляет готовые компоненты и утилиты, которые позволяют начать собирать телеметрию без необходимости писать какой-либо код или пересобирать приложение.
Одним из компонентов является OpenTelemtry Collector. По факту это прокси для получения, обработки и экспорта данных. Так же есть Kubernetes-операторы, helm- чарты и другие инструменты.
Все данные телеметрии нужно как-то записывать. Этот процесс в спецификации OpenTelemetry называется инструментированием.
OTel выделяет 2 подхода:
- Ручное инструментирование (code-based) - наиболее гибкий подход и возможности.
- Второй подход - автоматическое инструментирование (zero-code). Это самый простой и быстрый способ чтобы начать собирать телеметрию, без необходимости модифицировать приложение.
Количество собираемых данных трассировки может сказаться на производительности приложения. При помощи Sampling-а можно контролировать спаны, отправляемые на бэкенд, т.е объем данных.
SDK поддерживает различные стратегии семплирования, которые можно разделить на две категории:
- Head Sampling стратегии принимают решение о сохранении трейса в момент его создания. Наиболее простой подход.
- Tail Sampling стратегии напротив – принимают решение после сбора всех данных трейса. Например, в случае если были ошибки или большие задержки. Эти стратегии могут применяться на конечном бекенде или на уровне коллектора.
Head Sampling и Tail Sampling стратегии также можно комбинировать.
Open Telemetry в .NET
Реализация OpenTelemetry API в .NET немного отличается от других платформ, так как .NET предоставляет свое API ведения журнала, метрик и трейсов в платформе. Это означает, что OTel не должен предоставлять API-интерфейсы для использования авторами библиотеки.
Реализация OTel .NET использует существующие API платформы для инструментирования:
- Microsoft.Extensions.Logging.ILogger для логирования
- System.Diagnostics.Metrics.Meter для метрик
- System.Diagnostics.ActivitySource и System.Diagnostics.Activity для распределенной трассировки
OTel собирает данные телеметрии из этих API и других источников (через библиотеки инструментирования), а затем экспортирует их в систему мониторинга производительности приложений (APM) для хранения и анализа.
В конце небольшой обзор того, что происходило в мире .NET за последнее время, касательно OpenTelemetry.
Постепенно поддержка OpenTelemetry появляется во всех значимых библиотеках. Serilog с версии 3.1 записывает TraceId и SpanId в лог при его создании. К сожалению, библиотека которой мы пользуемся для экспорта логов в Elastic еще не поддержала эти изменения, но можно использовать готовый пакет Serilog.Enrichers.Span.
MassTransit с 8 версии поддерживает OpenTelemtry. Начать собирать трейсы и метрики стало еще проще. Достаточно подписаться на ActivitySource с нужным именем, как я показал ранее.
А проброс контекста трассировки в MassTransit работает уже давно, передается через хедер MT-Activity-Id.
С версии 1.35 Jaeger поддерживает протокол OTLP. Больше нет необходимости использовать специальный экспортер для ягеря, который уже помечен как deprecated/
Подведем итоги
- OpenTelemetry – стандартизированное и достаточно зрелое решение, которое будет и дальше развиваться
- Экосистема OpenTelemetry постоянно расширяется
- Трейсинг и метрики облегчают дальнейшую поддержку решений
Повышайте Observability своих проектов, используйте OpenTelemetry!