Поделиться через


Добавление и изменение Azure Monitor OpenTelemetry для приложений .NET, Java, Node.js и Python

В этом руководстве приведены инструкции по интеграции и настройке инструментирования OpenTelemetry (OTel) в Azure Monitor Application Insights.

Дополнительные сведения о концепциях OpenTelemetry см. в статье Обзор OpenTelemetry или Вопросы и ответы по OpenTelemetry.

Автоматический сбор данных

Дистрибутивы автоматически собирают данные путем объединения библиотек инструментирования OpenTelemetry.

Включенные библиотеки инструментирования

Запросы

Зависимости

Ведение журнала

  • ILogger

Дополнительные сведения см. в ILogger, а также в разделе «Ведение журнала в C# и .NET» и примерах кода.

Сноски

  • Поддерживает автоматическую отчетность необработанных/неперехваченных исключений.
  • 2. Поддерживает метрики OpenTelemetry
  • По умолчанию логи собираются только на уровне INFO или выше. Чтобы изменить этот параметр, см. раздел параметры конфигурации.
  • ⁴. По умолчанию данные логирования собираются только при выполнении записи на уровне ПРЕДУПРЕЖДЕНИЯ или выше.

Примечание.

Дистрибутивы OpenTelemetry Azure Monitor включают настраиваемое сопоставление и логику для автоматического выдачи стандартных метрик Application Insights.

Совет

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

Добавьте библиотеку инструментирования сообщества

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

Внимание

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

Чтобы добавить библиотеку сообщества, используйте ConfigureOpenTelemetryMeterProviderConfigureOpenTelemetryTracerProvider методы после добавления пакета NuGet для библиотеки.

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

dotnet add package OpenTelemetry.Instrumentation.Runtime 
// Create a new ASP.NET Core web application builder.
var builder = WebApplication.CreateBuilder(args);

// Configure the OpenTelemetry meter provider to add runtime instrumentation.
builder.Services.ConfigureOpenTelemetryMeterProvider((sp, builder) => builder.AddRuntimeInstrumentation());

// Add the Azure Monitor telemetry service to the application.
// This service will collect and send telemetry data to Azure Monitor.
builder.Services.AddOpenTelemetry().UseAzureMonitor();

// Build the ASP.NET Core web application.
var app = builder.Build();

// Start the ASP.NET Core web application.
app.Run();

Сбор настраиваемой телеметрии

В этом разделе объясняется, как собирать пользовательские данные телеметрии из приложения.

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

  • OpenTelemetry API
  • Библиотеки логирования и метрик для конкретных языков программирования
  • Классический API Application Insights

В следующей таблице представлены поддерживаемые в настоящее время пользовательские типы телеметрии:

Язык Пользовательские события Пользовательские метрики Зависимости Исключения Просмотры страницы Запросы Следы
ASP.NET Core
   OpenTelemetry API Да Да Да Да
   API ILogger Да
   Классический API ИИ
Java
   OpenTelemetry API Да Да Да Да
   Logback, Log4j, JUL Да Да
   Метрики микрометра Да
   Классический API ИИ Да Да Да Да Да Да Да
Node.js
   OpenTelemetry API Да Да Да Да
Python
   OpenTelemetry API Да Да Да Да
   Модуль ведения журнала Python Да
   Расширение событий Да Да

Примечание.

Application Insights Java 3.x прослушивает данные телеметрии, отправляемые в классический API Application Insights. Аналогичным образом Application Insights Node.js 3.x собирает события, созданные с помощью классического API Application Insights. Это упрощает обновление и заполняет пробел в нашей пользовательской поддержке телеметрии до тех пор, пока все пользовательские типы телеметрии не будут поддерживаться через API OpenTelemetry.

Добавление пользовательских метрик

В этом контексте термин пользовательских метрик относится к ручному инструментированию кода для сбора дополнительных метрик за пределами того, что библиотеки инструментирования OpenTelemetry автоматически собирают.

API OpenTelemetry предлагает шесть инструментов для покрытия различных сценариев метрик и необходимо выбрать правильный тип агрегирования при визуализации метрик в обозревателе метрик. Это требование верно при использовании API метрик OpenTelemetry для отправки метрик и при использовании библиотеки инструментирования.

В следующей таблице показаны рекомендуемые типы агрегирования для каждого из инструментов метрик OpenTelemetry.

Инструмент OpenTelemetry Тип агрегации в службе Azure Monitor
Счетчик Сумма
Асинхронный счетчик Сумма
Гистограмма Мин, Макс, Среднее, Сумма и Количество
Асинхронный датчик Среднее
UpDownCounter Сумма
Асинхронный счётчик вверх-вниз Сумма

Внимание

Типы агрегирования за пределами того, что показано в таблице, обычно не являются значимыми.

Спецификация OpenTelemetry описывает инструменты и приводит примеры использования каждого из них.

Совет

Гистограмма является самым универсальным и наиболее близким эквивалентом классическому API Application Insights GetMetric. Azure Monitor в настоящее время преобразует инструмент гистограммы в наши пять поддерживаемых типов агрегирования, и поддержка перцентилей в разработке. Хотя и менее универсальный, другие инструменты OpenTelemetry оказывают меньшее влияние на производительность вашего приложения.

Пример гистограммы

Запуск приложения должен подписаться на счетчик по имени:

// Create a new ASP.NET Core web application builder.
var builder = WebApplication.CreateBuilder(args);

// Configure the OpenTelemetry meter provider to add a meter named "OTel.AzureMonitor.Demo".
builder.Services.ConfigureOpenTelemetryMeterProvider((sp, builder) => builder.AddMeter("OTel.AzureMonitor.Demo"));

// Add the Azure Monitor telemetry service to the application.
// This service will collect and send telemetry data to Azure Monitor.
builder.Services.AddOpenTelemetry().UseAzureMonitor();

// Build the ASP.NET Core web application.
var app = builder.Build();

// Start the ASP.NET Core web application.
app.Run();

Meter должен быть инициализирован с помощью этого же имени.

// Create a new meter named "OTel.AzureMonitor.Demo".
var meter = new Meter("OTel.AzureMonitor.Demo");

// Create a new histogram metric named "FruitSalePrice".
Histogram<long> myFruitSalePrice = meter.CreateHistogram<long>("FruitSalePrice");

// Create a new Random object.
var rand = new Random();

// Record a few random sale prices for apples and lemons, with different colors.
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "apple"), new("color", "red"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "lemon"), new("color", "yellow"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "lemon"), new("color", "yellow"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "apple"), new("color", "green"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "apple"), new("color", "red"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "lemon"), new("color", "yellow"));

Контрпример

При запуске приложения необходимо подписаться на счетчик по имени:

// Create a new ASP.NET Core web application builder.
var builder = WebApplication.CreateBuilder(args);

// Configure the OpenTelemetry meter provider to add a meter named "OTel.AzureMonitor.Demo".
builder.Services.ConfigureOpenTelemetryMeterProvider((sp, builder) => builder.AddMeter("OTel.AzureMonitor.Demo"));

// Add the Azure Monitor telemetry service to the application.
// This service will collect and send telemetry data to Azure Monitor.
builder.Services.AddOpenTelemetry().UseAzureMonitor();

// Build the ASP.NET Core web application.
var app = builder.Build();

// Start the ASP.NET Core web application.
app.Run();

Элемент Meter должно быть инициализировано, используя это же имя:

// Create a new meter named "OTel.AzureMonitor.Demo".
var meter = new Meter("OTel.AzureMonitor.Demo");

// Create a new counter metric named "MyFruitCounter".
Counter<long> myFruitCounter = meter.CreateCounter<long>("MyFruitCounter");

// Record the number of fruits sold, grouped by name and color.
myFruitCounter.Add(1, new("name", "apple"), new("color", "red"));
myFruitCounter.Add(2, new("name", "lemon"), new("color", "yellow"));
myFruitCounter.Add(1, new("name", "lemon"), new("color", "yellow"));
myFruitCounter.Add(2, new("name", "apple"), new("color", "green"));
myFruitCounter.Add(5, new("name", "apple"), new("color", "red"));
myFruitCounter.Add(4, new("name", "lemon"), new("color", "yellow"));

Пример датчика

Запуск приложения должен подключиться к счетчику по имени.

// Create a new ASP.NET Core web application builder.
var builder = WebApplication.CreateBuilder(args);

// Configure the OpenTelemetry meter provider to add a meter named "OTel.AzureMonitor.Demo".
builder.Services.ConfigureOpenTelemetryMeterProvider((sp, builder) => builder.AddMeter("OTel.AzureMonitor.Demo"));

// Add the Azure Monitor telemetry service to the application.
// This service will collect and send telemetry data to Azure Monitor.
builder.Services.AddOpenTelemetry().UseAzureMonitor();

// Build the ASP.NET Core web application.
var app = builder.Build();

// Start the ASP.NET Core web application.
app.Run();

Meter должно быть инициализировано с использованием этого же имени.

// Get the current process.
var process = Process.GetCurrentProcess();

// Create a new meter named "OTel.AzureMonitor.Demo".
var meter = new Meter("OTel.AzureMonitor.Demo");

// Create a new observable gauge metric named "Thread.State".
// This metric will track the state of each thread in the current process.
ObservableGauge<int> myObservableGauge = meter.CreateObservableGauge("Thread.State", () => GetThreadState(process));

private static IEnumerable<Measurement<int>> GetThreadState(Process process)
{
    // Iterate over all threads in the current process.
    foreach (ProcessThread thread in process.Threads)
    {
        // Create a measurement for each thread, including the thread state, process ID, and thread ID.
        yield return new((int)thread.ThreadState, new("ProcessId", process.Id), new("ThreadId", thread.Id));
    }
}

Добавление настраиваемых исключений

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

  • Чтобы записать исключение с помощью действия:

    // Start a new activity named "ExceptionExample".
    using (var activity = activitySource.StartActivity("ExceptionExample"))
    {
        // Try to execute some code.
        try
        {
            throw new Exception("Test exception");
        }
        // If an exception is thrown, catch it and set the activity status to "Error".
        catch (Exception ex)
        {
            activity?.SetStatus(ActivityStatusCode.Error);
            activity?.RecordException(ex);
        }
    }
    
  • Регистрация исключения с помощью ILogger:

    // Create a logger using the logger factory. The logger category name is used to filter and route log messages.
    var logger = loggerFactory.CreateLogger(logCategoryName);
    
    // Try to execute some code.
    try
    {
        throw new Exception("Test Exception");
    }
    catch (Exception ex)
    {
        // Log an error message with the exception. The log level is set to "Error" and the event ID is set to 0.
        // The log message includes a template and a parameter. The template will be replaced with the value of the parameter when the log message is written.
        logger.Log(
            logLevel: LogLevel.Error,
            eventId: 0,
            exception: ex,
            message: "Hello {name}.",
            args: new object[] { "World" });
    }
    

Добавление настраиваемых диапазонов

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

Примечание.

Классы Activity и ActivitySource из пространства имен System.Diagnostics представляют собой концепции OpenTelemetry Span и Tracer соответственно. Вы создаете ActivitySource непосредственно с помощью конструктора, а не с помощью TracerProvider. Каждый класс ActivitySource должен быть явно подключен к TracerProvider с помощью AddSource(). Это обусловлено тем, что части API трассировки OpenTelemetry включены непосредственно в среду выполнения .NET. Дополнительные сведения см. в разделе Введение в API трассировки .NET для OpenTelemetry.

// Define an activity source named "ActivitySourceName". This activity source will be used to create activities for all requests to the application.
internal static readonly ActivitySource activitySource = new("ActivitySourceName");

// Create an ASP.NET Core application builder.
var builder = WebApplication.CreateBuilder(args);

// Configure the OpenTelemetry tracer provider to add a source named "ActivitySourceName". This will ensure that all activities created by the activity source are traced.
builder.Services.ConfigureOpenTelemetryTracerProvider((sp, builder) => builder.AddSource("ActivitySourceName"));

// Add the Azure Monitor telemetry service to the application. This service will collect and send telemetry data to Azure Monitor.
builder.Services.AddOpenTelemetry().UseAzureMonitor();

// Build the ASP.NET Core application.
var app = builder.Build();

// Map a GET request to the root path ("/") to the specified action.
app.MapGet("/", () =>
{
    // Start a new activity named "CustomActivity". This activity will be traced and the trace data will be sent to Azure Monitor.
    using (var activity = activitySource.StartActivity("CustomActivity"))
    {
        // your code here
    }

    // Return a response message.
    return $"Hello World!";
});

// Start the ASP.NET Core application.
app.Run();

StartActivity значение ActivityKind.Internalпо умолчанию, но можно указать любое другое ActivityKind. ActivityKind.Client, ActivityKind.Producerи ActivityKind.Internal сопоставляются с Application Insights dependencies. ActivityKind.Server и ActivityKind.Consumer сопоставляются с Application Insights requests.

Отправка пользовательской телеметрии с помощью классического API Application Insights

Мы рекомендуем использовать API OpenTelemetry по возможности, но некоторые сценарии могут возникнуть при использовании классического API Application Insights.

События

  1. Добавьте Microsoft.ApplicationInsights в свое приложение.

  2. Создайте экземпляр TelemetryClient:

    Примечание.

    Важно создать только один экземпляр TelemetryClient для каждого приложения.

    var telemetryConfiguration = new TelemetryConfiguration { ConnectionString = "" };
    var telemetryClient = new TelemetryClient(telemetryConfiguration);
    
  3. Используйте клиент для отправки пользовательской телеметрии:

    telemetryClient.TrackEvent("testEvent");
    

Изменение телеметрии

В этом разделе описано, как изменить телеметрию.

Добавление атрибутов диапазона

Эти атрибуты могут включать в себя добавление пользовательского свойства в данные телеметрии. Можно также использовать атрибуты для задания необязательных полей в схеме Application Insights, например "IP-адрес клиента".

Добавьте настраиваемое свойство в Span

Все атрибуты, добавляемые в диапазоны, экспортируются как пользовательские свойства. Они заполняют поле customDimensions в таблице запросов, зависимостей, трассировок или исключений.

Чтобы добавить атрибуты диапазона, используйте один из следующих двух способов:

Совет

Преимущество использования параметров, предоставляемых библиотеками инструментирования, когда они доступны, заключается в том, что доступен весь контекст. В результате пользователи могут добавить или отфильтровать дополнительные атрибуты. Например, параметр обогащения в библиотеке инструментирования HttpClient предоставляет пользователям доступ к HttpRequestMessage и самому HttpResponseMessage. Они могут выбрать что-нибудь из него и сохранить его как атрибут.

  1. Многие библиотеки инструментов предоставляют опцию расширения. Для получения инструкции см. файлы README отдельных библиотек инструментирования.

  2. Использование пользовательского процессора:

    Совет

    Добавьте процессор, показанный здесь перед добавлением Azure Monitor.

    // Create an ASP.NET Core application builder.
    var builder = WebApplication.CreateBuilder(args);
    
    // Configure the OpenTelemetry tracer provider to add a new processor named ActivityEnrichingProcessor.
    builder.Services.ConfigureOpenTelemetryTracerProvider((sp, builder) => builder.AddProcessor(new ActivityEnrichingProcessor()));
    
    // Add the Azure Monitor telemetry service to the application. This service will collect and send telemetry data to Azure Monitor.
    builder.Services.AddOpenTelemetry().UseAzureMonitor();
    
    // Build the ASP.NET Core application.
    var app = builder.Build();
    
    // Start the ASP.NET Core application.
    app.Run();
    

    Добавьте ActivityEnrichingProcessor.cs в проект, используя следующий код:

    public class ActivityEnrichingProcessor : BaseProcessor<Activity>
    {
        public override void OnEnd(Activity activity)
        {
            // The updated activity will be available to all processors which are called after this processor.
            activity.DisplayName = "Updated-" + activity.DisplayName;
            activity.SetTag("CustomDimension1", "Value1");
            activity.SetTag("CustomDimension2", "Value2");
        }
    }
    

Установить IP-адрес пользователя

Поле client_IP для запросов можно заполнить, задав атрибут в диапазоне. Application Insights использует IP-адрес для создания атрибутов расположения пользователей, а затем по умолчанию отменяет его.

Используйте пример пользовательского свойства, но замените следующие строки кода вActivityEnrichingProcessor.cs:

// Add the client IP address to the activity as a tag.
// only applicable in case of activity.Kind == Server
activity.SetTag("client.address", "<IP Address>");

Установка идентификатора пользователя или идентификатора пользователя, прошедшего проверку подлинности

Вы можете заполнить поле user_Id или user_AuthenticatedId для запросов с помощью следующего руководства. Идентификатор пользователя — это анонимный идентификатор пользователя. Идентификатор пользователя, прошедший проверку подлинности, является известным идентификатором пользователя.

Внимание

Перед настройкой идентификатора пользователя с проверкой подлинности обратитесь к применимым законам о конфиденциальности.

Используйте пример пользовательского свойства:

// Add the user ID to the activity as a tag, but only if the activity is not null.
activity?.SetTag("enduser.id", "<User Id>");

Добавление атрибутов журнала

OpenTelemetry использует ILogger .NET. Добавление пользовательских атрибутов к логам можно осуществить с помощью шаблона для сообщения.

Получение идентификатора трассировки или идентификатора диапазона

Вы можете получить Trace ID и Span ID для текущего активного промежутка, выполнив следующие действия.

Примечание.

Классы Activity и ActivitySource из пространства имен System.Diagnostics представляют собой концепции OpenTelemetry Span и Tracer соответственно. Это обусловлено тем, что части API трассировки OpenTelemetry включены непосредственно в среду выполнения .NET. Дополнительные сведения см. в разделе Введение в API трассировки .NET для OpenTelemetry.

// Get the current activity.
Activity activity = Activity.Current;
// Get the trace ID of the activity.
string traceId = activity?.TraceId.ToHexString();
// Get the span ID of the activity.
string spanId = activity?.SpanId.ToHexString();

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