Что такое корреляция распределенной трассировки и телеметрии?

Примечание.

В следующей документации используется классический API приложения Аналитика. Долгосрочный план приложения Аналитика заключается в сборе данных с помощью OpenTelemetry. Дополнительные сведения см. в разделе "Включить Azure Monitor OpenTelemetry" для приложений .NET, Node.js, Python и Java.

Современные архитектуры облачных и микрослужб включили простые, независимо развертываемые службы, которые сокращают затраты при увеличении доступности и пропускной способности. Тем не менее, это сделало общие системы более сложными для причины и отладки. Распределенная трассировка решает эту проблему, предоставляя профилировщик производительности, который работает как стеки вызовов для архитектур облачных и микрослужб.

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

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

Включение распределенной трассировки

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

Включение через приложение Аналитика с помощью автоинструментации или пакетов SDK

Агенты и пакеты SDK Application Insights для .NET, .NET Core, Java, Node.js и JavaScript поддерживают распределенную трассировку в собственном коде. Инструкции по установке и настройке пакетов SDK Application Insights доступны для следующих технологий:

При правильном установке и настройке пакета SDK для приложений Аналитика данные трассировки автоматически собираются для популярных платформ, библиотек и технологий с помощью автоматических сборок зависимостей ПАКЕТА SDK. Полный список поддерживаемых технологий доступен в документации по автоколлекции зависимостей.

Кроме того, любую технологию можно отслеживать вручную с помощью вызова TrackDependency в TelemetryClient.

Включение через OpenTelemetry

Application Insights теперь поддерживает распределенную трассировку через OpenTelemetry. OpenTelemetry предоставляет независимое от поставщика инструментирование для отправки трассировок, метрик и журналов в Application Insights. В первую очередь сообщество OpenTelemetry занялось распределенной трассировкой. Метрики и журналы сейчас находятся на стадии разработки.

Полная история наблюдаемости включает в себя все три столпа. Проверьте состояние наших предложений на основе OpenTelemetry в Azure Monitor, чтобы просмотреть последние сведения о том, что включено, какие предложения являются общедоступными и вариантами поддержки.

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

Включение с помощью OpenCensus

Помимо пакетов SDK, Application Insights поддерживает распределенную трассировку с помощью OpenCensus. OpenCensus представляет собой единое распределение библиотек с открытым исходным кодом без учета поставщиков, обеспечивающее сбор метрик и распределенную трассировку для служб. Оно также позволяет сообществу участников проектов с открытым кодом включить распределенную трассировку с использованием популярных технологий, таких как Redis, Memcached или MongoDB. Корпорация Майкрософт в OpenCensus сотрудничает с несколькими другими партнерами по мониторингу и облакам.

Дополнительные сведения об OpenCensus для Python см. в статье Настройка Azure Monitor для приложения Python.

На веб-сайте OpenCensus представлена справочная документация по API для Python и Go, а также различные руководства по использованию OpenCensus.

Модель корреляции для данных телеметрии

Application Insights определяет модель данных для распределенной корреляции данных телеметрии. Для связывания данных телеметрии с логической операцией у каждого элемента телеметрии есть поле контекста operation_Id. Каждый элемент телеметрии в распределенной трассировке использует этот идентификатор. Поэтому даже в случае потери телеметрии из одного уровня вы по-прежнему можете связывать данные телеметрии, сообщаемые другими компонентами.

Распределенная логическая операция обычно состоит из набора меньших операций, то есть запросов, обрабатываемых одним из компонентов. Запрос телеметрии определяет эти операции. Каждый элемент телеметрии запросов имеет собственный уникальный id, который его глобально идентифицирует. И для всех элементов телеметрии (например, трассировок и исключений), связанных с этим запросом, следует задать значение operation_parentId для id запроса.

Телеметрия зависимостей представляет каждую исходящую операцию, например вызов HTTP к другому компоненту. Он также определяет свой собственный id , что глобально уникальный. Телеметрия запросов, инициированная этим вызовом зависимостей, использует id в качестве operation_parentId.

Вы можете создать представление распределенной логической операции, используя operation_Id, operation_parentId и request.id с dependency.id. Эти поля также определяют причинно-следственную связь вызовов телеметрии.

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

Если количество элементов хранилища большое, вам потребуется указание о том, где выглядеть дальше. Модель данных Application Insights определяет два поля (request.source и dependency.target) для решения этой проблемы. В первом поле определяется компонент, который инициировал запрос зависимости. Во втором поле определяется, какой компонент вернул ответ на вызов зависимости.

Сведения о запросах из нескольких разрозненных экземпляров с помощью выражения запроса app см. в статье Выражение app() в запросах Azure Monitor.

Пример

Давайте рассмотрим пример. Приложение под названием Stock Prices показывает текущую рыночную стоимость акций, при этом используется внешний интерфейс API с именем "Биржевая диаграмма". В приложении Stock Prices есть страница c именем "Биржевая диаграмма", которая открывается в браузере клиента с помощью GET /Home/Stock. Приложение запрашивает API "Биржевая диаграмма" с помощью HTTP-вызова GET /api/stock/value.

Вы можете проанализировать итоговые данные телеметрии, выполнив запрос:

(requests | union dependencies | union pageViews)
| where operation_Id == "STYz"
| project timestamp, itemType, name, id, operation_ParentId, operation_Id

В результатах все элементы телеметрии используют корневой operation_Id. При вызове AJAX, осуществляемом со страницы, телеметрии зависимостей присваивается личный идентификатор qJSXU, а в качестве operation_ParentId используется идентификатор pageView. Запрос сервера затем использует идентификатор Ajax как operation_ParentId.

itemType name Идентификатор operation_ParentId operation_Id
pageView Stock page STYz STYz
dependency GET /Home/Stock qJSXU STYz STYz
запрос GET Home/Stock KqKwlrSt9PA= qJSXU STYz
dependency GET /api/stock/value bBrf2L7mm2g= KqKwlrSt9PA= STYz

Когда к внешней службе осуществлен вызов GET /api/stock/value, требуется узнать идентификатор этого сервера, поэтому можно соответствующим образом задать поле dependency.target. Если внешняя служба не поддерживает мониторинг, то в качестве target задается имя узла службы. Например, stock-prices-api.com. Но если для идентификации службы возвращается предопределенный заголовок HTTP, то target содержит удостоверение службы, которое позволяет Application Insights создать распределенную трассировку, запросив телеметрию из этой службы.

Заголовки корреляции с использованием W3C TraceContext

Application Insights переходит к W3C Trace-Context, который определяет следующее.

  • traceparent: содержит глобальный уникальный идентификатор операции и уникальный идентификатор вызова.
  • tracestate: содержит системный контекст трассировки.

Последняя версия пакета SDK для Application Insights поддерживает протокол Trace-Context, но, возможно, потребуется ваше согласие на его использование. (Поддерживается обратная совместимость с предыдущим протоколом корреляции, поддерживаемым пакетом SDK для приложений Аналитика.)

Протокол HTTP корреляции, также называемый Request-Id, является устаревшим. Этот протокол определяет два заголовка.

  • Request-Id: содержит глобальный уникальный идентификатор вызова.
  • Correlation-Context: содержит коллекцию пар "имя — значение" свойств распределенной трассировки.

Служба Application Insights также определяет расширение для протокола HTTP корреляции. Она использует пары "имя — значение" Request-Context для распространения коллекции свойств, используемых непосредственным вызывающим или вызываемым. Пакет SDK для Application Insights использует этот заголовок, чтобы задать значения полей dependency.target и request.source.

W3C Trace-Context и модели данных Application Insights сопоставляются следующим образом.

Application Insights W3C TraceContext
Id из Request и Dependency идентификатор родительского элемента
Operation_Id идентификатор трассировки
Operation_ParentId идентификатор родительского элемента родительского диапазона этого диапазона. Это поле должно быть пустым, если это корневой диапазон.

Дополнительные сведения см. в статье Модель данных телеметрии Application Insights.

Включение поддержки распределенной трассировки W3C для приложений .NET

Распределенная трассировка на основе W3C TraceContext включена по умолчанию во всех последних пакетах SDK для NET Framework/.NET Core, наряду с обратной совместимостью с устаревшим протоколом Request-Id.

Включение поддержки распределенной трассировки консорциума W3C для приложений Java

Агент Java 3.0

Агент Java 3.0 изначально поддерживает W3C и не требует дополнительной настройки.

пакет SDK для Java

  • Входящая конфигурация

    Для приложений Java EE добавьте следующий код к тегу <TelemetryModules> в ApplicationInsights.xml:

    <Add type="com.microsoft.applicationinsights.web.extensibility.modules.WebRequestTrackingTelemetryModule>
       <Param name = "W3CEnabled" value ="true"/>
       <Param name ="enableW3CBackCompat" value = "true" />
    </Add>
    

    Для приложений Spring Boot добавьте следующие свойства.

    • azure.application-insights.web.enable-W3C=true
    • azure.application-insights.web.enable-W3C-backcompat-mode=true
  • Исходящая конфигурация

    Добавьте к файлу AI-Agent.xml следующий код:

    <Instrumentation>
      <BuiltIn enabled="true">
        <HTTP enabled="true" W3C="true" enableW3CBackCompat="true"/>
      </BuiltIn>
    </Instrumentation>
    

    Примечание.

    По умолчанию включен режим обратной совместимости, и параметр enableW3CBackCompat является необязательным. Используйте его, только если вы хотите отключить режим обратной совместимости.

    В идеале этот режим можно будет отключить, когда все ваши будут обновлены до новой версии пакетов SDK, поддерживающих протокол консорциума W3C. Мы настоятельно рекомендуем перейти к этим новым пакетам SDK как можно скорее.

Важно убедиться, что входящая и исходящая конфигурации точно совпадают.

Включение поддержки распределенной трассировки W3C для веб-приложений

Эта функция включена по умолчанию для JavaScript, а заголовки автоматически включаются, когда домен страницы размещения совпадает с доменом, в который отправляются запросы (например, страница размещения и example.com запросы Ajax отправляются в example.com). Чтобы изменить режим распределенной трассировки, используйте distributedTracingMode поле конфигурации. AI_AND_W3C предоставляется по умолчанию для обратной совместимости с любыми устаревшими службами, инструментируемыми приложением Аналитика.

Если запросы XMLHttpRequest или Fetch Ajax отправляются другому узлу домена, включая поддомены, заголовки корреляции по умолчанию не включаются. Чтобы включить эту функцию, задайте для поля конфигурации значениеtrue.enableCorsCorrelation Если задано значение enableCorsCorrelationtrue, все запросы XMLHttpRequest и Fetch Ajax включают заголовки корреляции. В результате, если приложение на сервере, который вызывается, не поддерживает traceparent заголовок, запрос может завершиться ошибкой в зависимости от того, может ли браузер или версия проверить запрос на основе того, какие заголовки принимает сервер. Можно использовать correlationHeaderExcludedDomains поле конфигурации для исключения домена сервера из внедрения заголовка корреляции между компонентами. Например, можно исключить correlationHeaderExcludedDomains: ['*.auth0.com'] заголовки корреляции из запросов, отправленных поставщику удостоверений Auth0.

Внимание

Чтобы просмотреть все конфигурации, необходимые для включения корреляции, см. документацию по корреляции JavaScript.

Корреляция телеметрии в OpenCensus Python

OpenCensus Python поддерживает W3C Trace-Context без дополнительной настройки.

Для справки можно найти модель данных OpenCensus на этой странице GitHub.

Корреляция входящих запросов

OpenCensus Python сопоставляет заголовки W3C Trace-Context из входящих запросов с диапазонами, которые генерируются из самих запросов. OpenCensus автоматически сопоставляется с интеграцией для этих популярных платформ веб-приложений: Flask, Django и Пирамида. Необходимо просто заполнить заголовки W3C Trace-Context в правильном формате и отправить их вместе с запросом.

Изучите этот пример приложения Flask. Установите Flask, OpenCensus и расширения для Flask и Azure.


pip install flask opencensus opencensus-ext-flask opencensus-ext-azure

Необходимо добавить приложение Аналитика строка подключения в переменную среды.

APPLICATIONINSIGHTS_CONNECTION_STRING=<appinsights-connection-string>

Пример приложения Flask

from flask import Flask
from opencensus.ext.azure.trace_exporter import AzureExporter
from opencensus.ext.flask.flask_middleware import FlaskMiddleware
from opencensus.trace.samplers import ProbabilitySampler

app = Flask(__name__)
middleware = FlaskMiddleware(
    app,
    exporter=AzureExporter(
        connection_string='<appinsights-connection-string>', # or set environment variable APPLICATION_INSIGHTS_CONNECTION_STRING
    ), 
    sampler=ProbabilitySampler(rate=1.0),
)

@app.route('/')
def hello():
    return 'Hello World!'

if __name__ == '__main__':
    app.run(host='localhost', port=8080, threaded=True)

Этот код запускает образец приложения Flask на вашем локальном компьютере, прослушивая порт 8080. Для корреляции контекста трассировки запрос отправляется в конечную точку. В этом примере можно использовать команду curl.

curl --header "traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01" localhost:8080

Просмотрев Формат заголовка Trace-Context, можно получить следующую информацию.

version: 00

trace-id: 4bf92f3577b34da6a3ce929d0e0e4736

parent-id/span-id: 00f067aa0ba902b7

trace-flags: 01

Если посмотреть на запись запроса, отправленную в Azure Monitor, можно увидеть поля, заполненные данными заголовка трассировки. Эти данные можно найти в разделе Журналы (аналитика) в ресурсе Azure Monitor Application Insights

Screenshot that shows Request telemetry in Logs (Analytics).

Поле id имеет формат <trace-id>.<span-id>, где trace-id берется из заголовка трассировки, который был передан в запросе, а span-id представляет собой сгенерированный 8-байтовый массив для этого диапазона.

Поле operation_ParentId имеет формат <trace-id>.<parent-id>, где trace-id и parent-id берутся из заголовка трассировки, который был передан в запросе.

Корреляция журнала

OpenCensus Python позволяет сопоставлять журналы путем добавления идентификатора трассировки, идентификатора диапазона и флага выборки в записи журнала. Эти атрибуты добавляются путем установки средства интеграции журналов OpenCensus. Следующие атрибуты добавляются в объекты Python LogRecord : traceId, spanIdи traceSampled (применимо только для средств ведения журнала, созданных после интеграции).

Настройте интеграцию ведения журнала OpenCensus:

python -m pip install opencensus-ext-logging

Пример приложения

import logging

from opencensus.trace import config_integration
from opencensus.trace.samplers import AlwaysOnSampler
from opencensus.trace.tracer import Tracer

config_integration.trace_integrations(['logging'])
logging.basicConfig(format='%(asctime)s traceId=%(traceId)s spanId=%(spanId)s %(message)s')
tracer = Tracer(sampler=AlwaysOnSampler())

logger = logging.getLogger(__name__)
logger.warning('Before the span')
with tracer.span(name='hello'):
    logger.warning('In the span')
logger.warning('After the span')

При выполнении этого кода на консоли выводятся следующие печатные строки.

2019-10-17 11:25:59,382 traceId=c54cb1d4bbbec5864bf0917c64aeacdc spanId=0000000000000000 Before the span
2019-10-17 11:25:59,384 traceId=c54cb1d4bbbec5864bf0917c64aeacdc spanId=70da28f5a4831014 In the span
2019-10-17 11:25:59,385 traceId=c54cb1d4bbbec5864bf0917c64aeacdc spanId=0000000000000000 After the span

Обратите внимание, что для сообщения журнала, находящегося в диапазоне, присутствует spanId. При этом используется тот же spanId, который относится к диапазону с именем hello.

Данные журнала можно экспортировать с помощью AzureLogHandler. Дополнительные сведения см. в статье Настройка Azure Monitor для приложения Python.

Также можно передать сведения о трассировке из одного компонента в другой для правильной корреляции. Например, рассмотрим сценарий, в котором есть два компонента: module1 и module2. Модуль 1 вызывает функции в модуле 2. Для получения журналов из module1 и module2 в одной трассировке можно использовать следующий подход:

# module1.py
import logging

from opencensus.trace import config_integration
from opencensus.trace.samplers import AlwaysOnSampler
from opencensus.trace.tracer import Tracer
from module_2 import function_1

config_integration.trace_integrations(["logging"])
logging.basicConfig(
    format="%(asctime)s traceId=%(traceId)s spanId=%(spanId)s %(message)s"
)
tracer = Tracer(sampler=AlwaysOnSampler())

logger = logging.getLogger(__name__)
logger.warning("Before the span")

with tracer.span(name="hello"):
    logger.warning("In the span")
    function_1(logger, tracer)
logger.warning("After the span")
# module_2.py
import logging

from opencensus.trace import config_integration
from opencensus.trace.samplers import AlwaysOnSampler
from opencensus.trace.tracer import Tracer

config_integration.trace_integrations(["logging"])
logging.basicConfig(
    format="%(asctime)s traceId=%(traceId)s spanId=%(spanId)s %(message)s"
)
logger = logging.getLogger(__name__)
tracer = Tracer(sampler=AlwaysOnSampler())


def function_1(logger=logger, parent_tracer=None):
    if parent_tracer is not None:
        tracer = Tracer(
            span_context=parent_tracer.span_context,
            sampler=AlwaysOnSampler(),
        )
    else:
        tracer = Tracer(sampler=AlwaysOnSampler())

    with tracer.span("function_1"):
        logger.info("In function_1")

Корреляция данных телеметрии в .NET

Корреляция выполняется по умолчанию при подключении приложения. Специальные действия не требуются.

Среда выполнения .NET поддерживает распределение с помощью Activity и DiagnosticSource

Пакет SDK для Application Insights .NET использует DiagnosticSource и Activity для сбора данных телеметрии и их сопоставления.

Корреляция данных телеметрии в Java

Агент Java поддерживает автоматическую корреляцию данных телеметрии. Он автоматически заполняет operation_id для всех данных телеметрии (таких как трассировки, исключения, пользовательские события), генерируемых в рамках запроса. Он также распространяет заголовки корреляции, которые были описаны ранее, для вызовов между службами по протоколу HTTP при наличии настроенного агента Java SDK.

Примечание.

Агент Java для Application Insights автоматически собирает запросы и зависимости для JMS, Kafka, Netty/Webflux и других. Для Java SDK функция корреляции поддерживает только вызовы, выполняемые через Apache HttpClient. Автоматическое распространение контекстной информации не поддерживается технологиями обмена сообщениями, например Kafka, RabbitMQ, Служебной шиной Azure, в пакете SDK.

Для сбора пользовательских данных телеметрии необходимо установить для приложения пакет SDK для Java 2.6.

Имена ролей

Может потребоваться настроить способ отображения названий компонентов в схеме приложений. Чтобы сделать это, можно вручную задать cloud_RoleName, выполнив одно из следующих действий.

  • Для агента Java Application Insights задайте имя облачной роли, как показано далее:

    {
      "role": {
        "name": "my cloud role name"
      }
    }
    

    Также можно задать имя облачной роли с помощью переменной среды APPLICATIONINSIGHTS_ROLE_NAME.

  • С помощью пакета SDK для Java 2.5.0 и более поздних версий Application Insights можно указать cloud_RoleName, добавив <RoleName> в файл ApplicationInsights.xml:

    Screenshot that shows Application Insights overview and connection string.

    <?xml version="1.0" encoding="utf-8"?>
    <ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings" schemaVersion="2014-05-30">
       <ConnectionString>InstrumentationKey=00000000-0000-0000-0000-000000000000</ConnectionString>
       <RoleName>** Your role name **</RoleName>
       ...
    </ApplicationInsights>
    
  • Если используется Spring Boot с начальным набором Application Insights Spring Boot, задайте пользовательское имя приложения в файле application.properties:

    spring.application.name=<name-of-app>

Кроме того, вы можете задать имя облачной роли с помощью переменной среды или системного свойства. Дополнительные сведения см. в разделе Настройка имени облачной роли.

Следующие шаги