В этом руководстве приведены инструкции по интеграции и настройке инструментирования OpenTelemetry (OTel) в Azure Monitor Application Insights.
Дополнительные сведения о концепциях OpenTelemetry см. в статье Обзор OpenTelemetry или Вопросы и ответы по OpenTelemetry.
Автоматический сбор данных
Дистрибутивы автоматически собирают данные путем объединения библиотек инструментирования OpenTelemetry.
Включенные библиотеки инструментирования
Экспортер Azure Monitor не включает библиотеки инструментирования.
Вы можете собирать зависимости из Azure SDK, используя следующий пример кода, чтобы подписаться на источник вручную.
// Create an OpenTelemetry tracer provider builder.
// It is important to keep the TracerProvider instance active throughout the process lifetime.
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
// The following line subscribes to dependencies emitted from Azure SDKs
.AddSource("Azure.*")
.AddAzureMonitorTraceExporter()
.AddHttpClientInstrumentation(o => o.FilterHttpRequestMessage = (_) =>
{
// Azure SDKs create their own client span before calling the service using HttpClient
// In this case, we would see two spans corresponding to the same operation
// 1) created by Azure SDK 2) created by HttpClient
// To prevent this duplication we are filtering the span from HttpClient
// as span from Azure SDK contains all relevant information needed.
var parentActivity = Activity.Current?.Parent;
if (parentActivity != null && parentActivity.Source.Name.Equals("Azure.Core.Http"))
{
return false;
}
return true;
})
.Build();
Запросы
- Потребители JMS
- Потребители Kafka
- Netty;
- Quartz
- RabbitMQ
- Сервлеты
- Планирование в Spring
Примечание.
Servlet и Netty autoinstrumentation охватывают большинство служб Java HTTP, включая Java EE, Jakarta EE, Spring Boot, Quarkus и Micronaut.
Зависимости (плюс последующее распространение распределенной трассировки)
- Apache HttpClient
- Apache HttpAsyncClient
- AsyncHttpClient
- Google HttpClient
- gRPC
- java.net.HttpURLConnection
- Java 11 HttpClient
- Клиент JAX-RS
- Jetty HttpClient
- JMS;
- Kafka
- Клиент Netty
- OkHttp;
- RabbitMQ
Зависимости (без распространения трассировки на последующих этапах)
- Cassandra
- JDBC
- MongoDB (асинхронный и синхронный)
- Redis (Lettuce и Jedis)
Метрики
- Метрики микрометра, включая метрики Spring Boot Actuator
- Метрики JMX
Логи
- Logback (включая свойства MDC¹ ³)
- Log4j (включая свойства контекста MDC/Thread) NO MWARE
- Ведение журнала JBoss (включая свойства MDC)
- java.util.logging ¹ ³
Коллекция по умолчанию
Данные телеметрии, создаваемые следующими пакетами SDK Azure, автоматически собираются по умолчанию:
[//]: # "Azure Cosmos DB 4.22.0+ due to https://github.com/Azure/azure-sdk-for-java/pull/25571"
[//]: # "the remaining above names and links scraped from https://azure.github.io/azure-sdk/releases/latest/java.html"
[//]: # "and version synched manually against the oldest version in maven central built on azure-core 1.14.0"
[//]: # ""
[//]: # "var table = document.querySelector('#tg-sb-content > div > table')"
[//]: # "var str = ''"
[//]: # "for (var i = 1, row; row = table.rows[i]; i++) {"
[//]: # " var name = row.cells[0].getElementsByTagName('div')[0].textContent.trim()"
[//]: # " var stableRow = row.cells[1]"
[//]: # " var versionBadge = stableRow.querySelector('.badge')"
[//]: # " if (!versionBadge) {"
[//]: # " continue"
[//]: # " }"
[//]: # " var version = versionBadge.textContent.trim()"
[//]: # " var link = stableRow.querySelectorAll('a')[2].href"
[//]: # " str += '* [' + name + '](' + link + ') ' + version + '\n'"
[//]: # "}"
[//]: # "console.log(str)"
Запросы для собственных приложений Spring Boot
- Spring Web
- Spring Web MVC
- Spring WebFlux
Зависимости для собственных приложений Spring Boot
Метрики
Журналы для нативных приложений Spring Boot
Для собственных приложений Кварц ознакомьтесь с документацией Quarkus.
Следующие библиотеки инструментирования OpenTelemetry включены в состав дистрибутива Azure Monitor Application Insights. Дополнительную информацию см. в Azure SDK для JavaScript.
Запросы
Зависимости
Логи
Инструментирование можно настроить с помощью AzureMonitorOpenTelemetryOptions
:
// Import Azure Monitor OpenTelemetry
const { useAzureMonitor, AzureMonitorOpenTelemetryOptions } = require("@azure/monitor-opentelemetry");
// Import OpenTelemetry HTTP Instrumentation to get config type
const { HttpInstrumentationConfig } = require("@azure/monitor-opentelemetry");
// Import HTTP to get type
const { IncomingMessage } = require("http");
// Specific Instrumentation configs could be added
const httpInstrumentationConfig: HttpInstrumentationConfig = {
ignoreIncomingRequestHook: (request: IncomingMessage) => {
return false; //Return true if you want to ignore a specific request
},
enabled: true
};
// Instrumentations configuration
const options: AzureMonitorOpenTelemetryOptions = {
instrumentationOptions: {
http: httpInstrumentationConfig,
azureSdk: { enabled: true },
mongoDb: { enabled: true },
mySql: { enabled: true },
postgreSql: { enabled: true },
redis: { enabled: true },
redis4: { enabled: true },
}
};
// Enable Azure Monitor integration
useAzureMonitor(options);
Запросы
Зависимости
Логи
Примеры использования библиотеки ведения журнала Python можно найти на сайте GitHub.
Данные телеметрии, испускаемые Azure SDKS, автоматически собираются по умолчанию.
Сноски
- Поддерживает автоматическую отчетность необработанных/неперехваченных исключений.
- 2. Поддерживает метрики OpenTelemetry
- По умолчанию логи собираются только на уровне INFO или выше. Чтобы изменить этот параметр, см. раздел параметры конфигурации.
- ⁴. По умолчанию данные логирования собираются только при выполнении записи на уровне ПРЕДУПРЕЖДЕНИЯ или выше.
Примечание.
Дистрибутивы OpenTelemetry Azure Monitor включают настраиваемое сопоставление и логику для автоматического выдачи стандартных метрик Application Insights.
Совет
Все метрики OpenTelemetry, собираемые автоматически из библиотек инструментирования или вручную собранные из пользовательского кода, в настоящее время считаются Application Insights "пользовательскими метриками" для выставления счетов.
Подробнее.
Вы можете автоматически собирать дополнительные данные при включении библиотек инструментирования из сообщества OpenTelemetry.
Внимание
Мы не поддерживаем и не гарантируем качество библиотек инструментов от сообщества. Чтобы предложить один для нашего дистрибутива, опубликуйте сообщение или проголосуйте в нашем сообществе обратной связи. Имейте в виду, что некоторые из них основаны на экспериментальных спецификациях OpenTelemetry и могут вызвать критические изменения в будущем.
Чтобы добавить библиотеку сообщества, используйте ConfigureOpenTelemetryMeterProvider
ConfigureOpenTelemetryTracerProvider
методы после добавления пакета 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();
В следующем примере показано, как инструментирование среды выполнения может быть добавлено для сбора дополнительных метрик:
// Create a new OpenTelemetry meter provider and add runtime instrumentation and the Azure Monitor metric exporter.
// It is important to keep the MetricsProvider instance active throughout the process lifetime.
var metricsProvider = Sdk.CreateMeterProviderBuilder()
.AddRuntimeInstrumentation()
.AddAzureMonitorMetricExporter();
Вы не можете расширить дистрибутив Java с помощью библиотек инструментирования сообщества. Чтобы запросить включение другой библиотеки инструментирования, откройте проблему на странице GitHub. Ссылку на страницу GitHub можно найти на следующей странице.
Вы не можете использовать библиотеки инструментирования сообщества с собственными приложениями GraalVM Java.
Другие инструменты OpenTelemetry доступны здесь и можно добавить с помощью TraceHandler в ApplicationInsightsClient.
// Import the Azure Monitor OpenTelemetry plugin and OpenTelemetry API
const { useAzureMonitor } = require("@azure/monitor-opentelemetry");
const { metrics, trace, ProxyTracerProvider } = require("@opentelemetry/api");
// Import the OpenTelemetry instrumentation registration function and Express instrumentation
const { registerInstrumentations } = require( "@opentelemetry/instrumentation");
const { ExpressInstrumentation } = require('@opentelemetry/instrumentation-express');
// Get the OpenTelemetry tracer provider and meter provider
const tracerProvider = (trace.getTracerProvider() as ProxyTracerProvider).getDelegate();
const meterProvider = metrics.getMeterProvider();
// Enable Azure Monitor integration
useAzureMonitor();
// Register the Express instrumentation
registerInstrumentations({
// List of instrumentations to register
instrumentations: [
new ExpressInstrumentation(), // Express instrumentation
],
// OpenTelemetry tracer provider
tracerProvider: tracerProvider,
// OpenTelemetry meter provider
meterProvider: meterProvider
});
Чтобы добавить неофициально поддерживаемую библиотеку инструментирования сообщества, не включенную в дистрибутив Azure Monitor, можно использовать инструментирование напрямую. Список библиотек инструментирования сообщества можно найти здесь.
Примечание.
Не рекомендуется вручную инструментировать поддерживаемую библиотеку инструментирования совместно с дистрибутивом configure_azure_monitor()
. Это не поддерживаемый сценарий, и вы можете получить нежелательное поведение для телеметрии.
# Import the `configure_azure_monitor()`, `SQLAlchemyInstrumentor`, `create_engine`, and `text` functions from the appropriate packages.
from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
from sqlalchemy import create_engine, text
# Configure OpenTelemetry to use Azure Monitor.
configure_azure_monitor()
# Create a SQLAlchemy engine.
engine = create_engine("sqlite:///:memory:")
# SQLAlchemy instrumentation is not officially supported by this package, however, you can use the OpenTelemetry `instrument()` method manually in conjunction with `configure_azure_monitor()`.
SQLAlchemyInstrumentor().instrument(
engine=engine,
)
# Database calls using the SQLAlchemy library will be automatically captured.
with engine.connect() as conn:
result = conn.execute(text("select 'hello world'"))
print(result.all())
Сбор настраиваемой телеметрии
В этом разделе объясняется, как собирать пользовательские данные телеметрии из приложения.
В зависимости от языка и типа сигнала существуют различные способы сбора пользовательских данных телеметрии, в том числе:
- 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"));
public class Program
{
// Create a static readonly Meter object named "OTel.AzureMonitor.Demo".
// This meter will be used to track metrics about the application.
private static readonly Meter meter = new("OTel.AzureMonitor.Demo");
public static void Main()
{
// Create a new MeterProvider object using the OpenTelemetry SDK.
// The MeterProvider object is responsible for managing meters and sending
// metric data to exporters.
// It is important to keep the MetricsProvider instance active
// throughout the process lifetime.
//
// The MeterProviderBuilder is configured to add a meter named
// "OTel.AzureMonitor.Demo" and an Azure Monitor metric exporter.
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddMeter("OTel.AzureMonitor.Demo")
.AddAzureMonitorMetricExporter()
.Build();
// Create a new Histogram metric named "FruitSalePrice".
// This metric will track the distribution of fruit sale prices.
Histogram<long> myFruitSalePrice = meter.CreateHistogram<long>("FruitSalePrice");
// Create a new Random object. This object will be used to generate random sale prices.
var rand = new Random();
// Record a few random sale prices for apples and lemons, with different colors.
// Each record includes a timestamp, a value, and a set of attributes.
// The attributes can be used to filter and analyze the metric data.
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"));
// Display a message to the user and wait for them to press Enter.
// This allows the user to see the message and the console before the
// application exits.
System.Console.WriteLine("Press Enter key to exit.");
System.Console.ReadLine();
}
}
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.metrics.DoubleHistogram;
import io.opentelemetry.api.metrics.Meter;
public class Program {
public static void main(String[] args) {
Meter meter = GlobalOpenTelemetry.getMeter("OTEL.AzureMonitor.Demo");
DoubleHistogram histogram = meter.histogramBuilder("histogram").build();
histogram.record(1.0);
histogram.record(100.0);
histogram.record(30.0);
}
}
Внедрение OpenTelemetry
:
Создайте гистограмму:
import io.opentelemetry.api.metrics.DoubleHistogram;
import io.opentelemetry.api.metrics.Meter;
Meter meter = openTelemetry.getMeter("OTEL.AzureMonitor.Demo");
DoubleHistogram histogram = meter.histogramBuilder("histogram").build();
histogram.record(1.0);
histogram.record(100.0);
histogram.record(30.0);
// Import the Azure Monitor OpenTelemetry plugin and OpenTelemetry API
const { useAzureMonitor } = require("@azure/monitor-opentelemetry");
const { metrics } = require("@opentelemetry/api");
// Enable Azure Monitor integration
useAzureMonitor();
// Get the meter for the "testMeter" namespace
const meter = metrics.getMeter("testMeter");
// Create a histogram metric
let histogram = meter.createHistogram("histogram");
// Record values to the histogram metric with different tags
histogram.record(1, { "testKey": "testValue" });
histogram.record(30, { "testKey": "testValue2" });
histogram.record(100, { "testKey2": "testValue" });
# Import the `configure_azure_monitor()` and `metrics` functions from the appropriate packages.
from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry import metrics
import os
# Configure OpenTelemetry to use Azure Monitor with the specified connection string.
# Replace `<your-connection-string>` with the connection string to your Azure Monitor Application Insights resource.
configure_azure_monitor(
connection_string="<your-connection-string>",
)
# Opt in to allow grouping of your metrics via a custom metrics namespace in app insights metrics explorer.
# Specify the namespace name using get_meter("namespace-name")
os.environ["APPLICATIONINSIGHTS_METRIC_NAMESPACE_OPT_IN"] = "true"
# Get a meter provider and a meter with the name "otel_azure_monitor_histogram_demo".
meter = metrics.get_meter_provider().get_meter("otel_azure_monitor_histogram_demo")
# Record three values to the histogram.
histogram = meter.create_histogram("histogram")
histogram.record(1.0, {"test_key": "test_value"})
histogram.record(100.0, {"test_key2": "test_value"})
histogram.record(30.0, {"test_key": "test_value2"})
# Wait for background execution.
input()
Контрпример
При запуске приложения необходимо подписаться на счетчик по имени:
// 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"));
public class Program
{
// Create a static readonly Meter object named "OTel.AzureMonitor.Demo".
// This meter will be used to track metrics about the application.
private static readonly Meter meter = new("OTel.AzureMonitor.Demo");
public static void Main()
{
// Create a new MeterProvider object using the OpenTelemetry SDK.
// The MeterProvider object is responsible for managing meters and sending
// metric data to exporters.
// It is important to keep the MetricsProvider instance active
// throughout the process lifetime.
//
// The MeterProviderBuilder is configured to add a meter named
// "OTel.AzureMonitor.Demo" and an Azure Monitor metric exporter.
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddMeter("OTel.AzureMonitor.Demo")
.AddAzureMonitorMetricExporter()
.Build();
// Create a new counter metric named "MyFruitCounter".
// This metric will track the number of fruits sold.
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"));
// Display a message to the user and wait for them to press Enter.
// This allows the user to see the message and the console before the
// application exits.
System.Console.WriteLine("Press Enter key to exit.");
System.Console.ReadLine();
}
}
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.metrics.Meter;
public class Program {
public static void main(String[] args) {
Meter meter = GlobalOpenTelemetry.getMeter("OTEL.AzureMonitor.Demo");
LongCounter myFruitCounter = meter
.counterBuilder("MyFruitCounter")
.build();
myFruitCounter.add(1, Attributes.of(AttributeKey.stringKey("name"), "apple", AttributeKey.stringKey("color"), "red"));
myFruitCounter.add(2, Attributes.of(AttributeKey.stringKey("name"), "lemon", AttributeKey.stringKey("color"), "yellow"));
myFruitCounter.add(1, Attributes.of(AttributeKey.stringKey("name"), "lemon", AttributeKey.stringKey("color"), "yellow"));
myFruitCounter.add(2, Attributes.of(AttributeKey.stringKey("name"), "apple", AttributeKey.stringKey("color"), "green"));
myFruitCounter.add(5, Attributes.of(AttributeKey.stringKey("name"), "apple", AttributeKey.stringKey("color"), "red"));
myFruitCounter.add(4, Attributes.of(AttributeKey.stringKey("name"), "lemon", AttributeKey.stringKey("color"), "yellow"));
}
}
Внедрение OpenTelemetry
:
Создайте счетчик:
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.metrics.Meter;
Meter meter = openTelemetry.getMeter("OTEL.AzureMonitor.Demo");
LongCounter myFruitCounter = meter.counterBuilder("MyFruitCounter")
.build();
myFruitCounter.add(1, Attributes.of(AttributeKey.stringKey("name"), "apple", AttributeKey.stringKey("color"), "red"));
myFruitCounter.add(2, Attributes.of(AttributeKey.stringKey("name"), "lemon", AttributeKey.stringKey("color"), "yellow"));
myFruitCounter.add(1, Attributes.of(AttributeKey.stringKey("name"), "lemon", AttributeKey.stringKey("color"), "yellow"));
myFruitCounter.add(2, Attributes.of(AttributeKey.stringKey("name"), "apple", AttributeKey.stringKey("color"), "green"));
myFruitCounter.add(5, Attributes.of(AttributeKey.stringKey("name"), "apple", AttributeKey.stringKey("color"), "red"));
myFruitCounter.add(4, Attributes.of(AttributeKey.stringKey("name"), "lemon", AttributeKey.stringKey("color"), "yellow"));
// Import the Azure Monitor OpenTelemetry plugin and OpenTelemetry API
const { useAzureMonitor } = require("@azure/monitor-opentelemetry");
const { metrics } = require("@opentelemetry/api");
// Enable Azure Monitor integration
useAzureMonitor();
// Get the meter for the "testMeter" namespace
const meter = metrics.getMeter("testMeter");
// Create a counter metric
let counter = meter.createCounter("counter");
// Add values to the counter metric with different tags
counter.add(1, { "testKey": "testValue" });
counter.add(5, { "testKey2": "testValue" });
counter.add(3, { "testKey": "testValue2" });
# Import the `configure_azure_monitor()` and `metrics` functions from the appropriate packages.
from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry import metrics
import os
# Configure OpenTelemetry to use Azure Monitor with the specified connection string.
# Replace `<your-connection-string>` with the connection string to your Azure Monitor Application Insights resource.
configure_azure_monitor(
connection_string="<your-connection-string>",
)
# Opt in to allow grouping of your metrics via a custom metrics namespace in app insights metrics explorer.
# Specify the namespace name using get_meter("namespace-name")
os.environ["APPLICATIONINSIGHTS_METRIC_NAMESPACE_OPT_IN"] = "true"
# Get a meter provider and a meter with the name "otel_azure_monitor_counter_demo".
meter = metrics.get_meter_provider().get_meter("otel_azure_monitor_counter_demo")
# Create a counter metric with the name "counter".
counter = meter.create_counter("counter")
# Add three values to the counter.
# The first argument to the `add()` method is the value to add.
# The second argument is a dictionary of dimensions.
# Dimensions are used to group related metrics together.
counter.add(1.0, {"test_key": "test_value"})
counter.add(5.0, {"test_key2": "test_value"})
counter.add(3.0, {"test_key": "test_value2"})
# Wait for background execution.
input()
Пример датчика
Запуск приложения должен подключиться к счетчику по имени.
// 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));
}
}
public class Program
{
// Create a static readonly Meter object named "OTel.AzureMonitor.Demo".
// This meter will be used to track metrics about the application.
private static readonly Meter meter = new("OTel.AzureMonitor.Demo");
public static void Main()
{
// Create a new MeterProvider object using the OpenTelemetry SDK.
// The MeterProvider object is responsible for managing meters and sending
// metric data to exporters.
// It is important to keep the MetricsProvider instance active
// throughout the process lifetime.
//
// The MeterProviderBuilder is configured to add a meter named
// "OTel.AzureMonitor.Demo" and an Azure Monitor metric exporter.
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddMeter("OTel.AzureMonitor.Demo")
.AddAzureMonitorMetricExporter()
.Build();
// Get the current process.
var process = Process.GetCurrentProcess();
// 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));
// Display a message to the user and wait for them to press Enter.
// This allows the user to see the message and the console before the
// application exits.
System.Console.WriteLine("Press Enter key to exit.");
System.Console.ReadLine();
}
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));
}
}
}
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.Meter;
public class Program {
public static void main(String[] args) {
Meter meter = GlobalOpenTelemetry.getMeter("OTEL.AzureMonitor.Demo");
meter.gaugeBuilder("gauge")
.buildWithCallback(
observableMeasurement -> {
double randomNumber = Math.floor(Math.random() * 100);
observableMeasurement.record(randomNumber, Attributes.of(AttributeKey.stringKey("testKey"), "testValue"));
});
}
}
Внедрение OpenTelemetry
:
Создание датчика:
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.Meter;
Meter meter = openTelemetry.getMeter("OTEL.AzureMonitor.Demo");
meter.gaugeBuilder("gauge")
.buildWithCallback(
observableMeasurement -> {
double randomNumber = Math.floor(Math.random() * 100);
observableMeasurement.record(randomNumber, Attributes.of(AttributeKey.stringKey("testKey"), "testValue"));
});
// Import the useAzureMonitor function and the metrics module from the @azure/monitor-opentelemetry and @opentelemetry/api packages, respectively.
const { useAzureMonitor } = require("@azure/monitor-opentelemetry");
const { metrics } = require("@opentelemetry/api");
// Enable Azure Monitor integration.
useAzureMonitor();
// Get the meter for the "testMeter" meter name.
const meter = metrics.getMeter("testMeter");
// Create an observable gauge metric with the name "gauge".
let gauge = meter.createObservableGauge("gauge");
// Add a callback to the gauge metric. The callback will be invoked periodically to generate a new value for the gauge metric.
gauge.addCallback((observableResult: ObservableResult) => {
// Generate a random number between 0 and 99.
let randomNumber = Math.floor(Math.random() * 100);
// Set the value of the gauge metric to the random number.
observableResult.observe(randomNumber, {"testKey": "testValue"});
});
# Import the necessary packages.
from typing import Iterable
import os
from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry import metrics
from opentelemetry.metrics import CallbackOptions, Observation
# Configure OpenTelemetry to use Azure Monitor with the specified connection string.
# Replace `<your-connection-string>` with the connection string to your Azure Monitor Application Insights resource.
configure_azure_monitor(
connection_string="<your-connection-string>",
)
# Opt in to allow grouping of your metrics via a custom metrics namespace in app insights metrics explorer.
# Specify the namespace name using get_meter("namespace-name")
os.environ["APPLICATIONINSIGHTS_METRIC_NAMESPACE_OPT_IN"] = "true"
# Get a meter provider and a meter with the name "otel_azure_monitor_gauge_demo".
meter = metrics.get_meter_provider().get_meter("otel_azure_monitor_gauge_demo")
# Define two observable gauge generators.
# The first generator yields a single observation with the value 9.
# The second generator yields a sequence of 10 observations with the value 9 and a different dimension value for each observation.
def observable_gauge_generator(options: CallbackOptions) -> Iterable[Observation]:
yield Observation(9, {"test_key": "test_value"})
def observable_gauge_sequence(options: CallbackOptions) -> Iterable[Observation]:
observations = []
for i in range(10):
observations.append(
Observation(9, {"test_key": i})
)
return observations
# Create two observable gauges using the defined generators.
gauge = meter.create_observable_gauge("gauge", [observable_gauge_generator])
gauge2 = meter.create_observable_gauge("gauge2", [observable_gauge_sequence])
# Wait for background execution.
input()
Добавление настраиваемых исключений
Библиотеки инструментирования автоматически сообщают об исключениях в 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" });
}
Чтобы зафиксировать исключение с использованием активности:
// 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("ExceptionExample");
try
{
// Try to execute some code.
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" });
}
Можно использовать opentelemetry-api
для обновления состояния диапазона и записи исключений.
Добавьте opentelemetry-api-1.0.0.jar
(или более позднюю версию) в ваше приложение.
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.0.0</version>
</dependency>
Задайте состояние error
и запишите исключение в коде:
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
Span span = Span.current();
span.setStatus(StatusCode.ERROR, "errorMessage");
span.recordException(e);
Задайте состояние error
и запишите исключение в коде:
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
Span span = Span.current();
span.setStatus(StatusCode.ERROR, "errorMessage");
span.recordException(e);
Пакет SDK Node.js экспортирует только эти исключения, основанные на вручную записанных спанах, в Application Insights в качестве исключений, если они записываются на дочерних элементах удалённых или внутренних спанов или если исключение записывается на спане верхнего уровня.
// Import the Azure Monitor OpenTelemetry plugin and OpenTelemetry API
const { useAzureMonitor } = require("@azure/monitor-opentelemetry");
const { trace } = require("@opentelemetry/api");
// Enable Azure Monitor integration
useAzureMonitor();
// Get the tracer for the "testTracer" namespace
const tracer = trace.getTracer("testTracer");
// Start a span with the name "hello"
let span = tracer.startSpan("hello");
// Try to throw an error
try {
throw new Error("Test Error");
}
// Catch the error and record it to the span
catch(error){
span.recordException(error);
}
SDK OpenTelemetry для Python реализован таким образом, чтобы исключения автоматически фиксировались и записывались. Пример этого поведения см. в следующем примере кода:
# Import the necessary packages.
from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry import trace
# Configure OpenTelemetry to use Azure Monitor with the specified connection string.
# Replace `<your-connection-string>` with the connection string to your Azure Monitor Application Insights resource.
configure_azure_monitor(
connection_string="<your-connection-string>",
)
# Get a tracer for the current module.
tracer = trace.get_tracer("otel_azure_monitor_exception_demo")
# Exception events
try:
# Start a new span with the name "hello".
with tracer.start_as_current_span("hello") as span:
# This exception will be automatically recorded
raise Exception("Custom exception message.")
except Exception:
print("Exception raised")
Если вы хотите записать исключения вручную, можно отключить этот параметр в диспетчере контекстов и использовать record_exception()
непосредственно, как показано в следующем примере:
...
# Start a new span with the name "hello" and disable exception recording.
with tracer.start_as_current_span("hello", record_exception=False) as span:
try:
# Raise an exception.
raise Exception("Custom exception message.")
except Exception as ex:
# Manually record exception
span.record_exception(ex)
...
Добавление настраиваемых диапазонов
Может потребоваться добавить настроенный диапазон в двух сценариях. Во-первых, когда запрос на зависимость еще не обработан инструментальной библиотекой. Во-вторых, когда вы хотите моделировать процесс приложения в виде отрезка в сквозном обзоре транзакций.
Примечание.
Классы 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
.
Примечание.
Классы Activity
и ActivitySource
из пространства имен System.Diagnostics
представляют собой концепции OpenTelemetry Span
и Tracer
соответственно. Вы создаете ActivitySource
непосредственно с помощью конструктора, а не с помощью TracerProvider
. Каждый класс ActivitySource
должен быть явно подключен к TracerProvider
с помощью AddSource()
. Это обусловлено тем, что части API трассировки OpenTelemetry включены непосредственно в среду выполнения .NET. Дополнительные сведения см. в разделе Введение в API трассировки .NET для OpenTelemetry.
// Create an OpenTelemetry tracer provider builder.
// It is important to keep the TracerProvider instance active throughout the process lifetime.
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource("ActivitySourceName")
.AddAzureMonitorTraceExporter()
.Build();
// Create an activity source named "ActivitySourceName".
var activitySource = new ActivitySource("ActivitySourceName");
// 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
}
StartActivity
установлено по умолчанию как ActivityKind.Internal
, но можно указать любое другое ActivityKind
.
ActivityKind.Client
, ActivityKind.Producer
и ActivityKind.Internal
сопоставляются с Application Insights dependencies
.
ActivityKind.Server
и ActivityKind.Consumer
сопоставляются с Application Insights requests
.
Используйте аннотацию OpenTelemetry
Самый простой способ добавить собственные диапазоны — использовать аннотацию OpenTelemetry @WithSpan
.
Диапазоны заполняют таблицы requests
и dependencies
в Application Insights.
Добавьте opentelemetry-instrumentation-annotations-1.32.0.jar
(или более поздней версии) в приложение:
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-instrumentation-annotations</artifactId>
<version>1.32.0</version>
</dependency>
Используйте заметку @WithSpan
, чтобы создавать интервал при каждом выполнении метода:
import io.opentelemetry.instrumentation.annotations.WithSpan;
@WithSpan(value = "your span name")
public void yourMethod() {
}
По умолчанию диапазон оказывается в таблице с типом зависимости dependencies
InProc
.
Для методов, представляющих фоновую задачу, не охватываемую автоинструментацией, рекомендуется применять атрибут kind = SpanKind.SERVER
к аннотации @WithSpan
, чтобы убедиться, что они отображаются в таблице requests
Application Insights.
Использование API OpenTelemetry
Если предыдущая заметка OpenTelemetry @WithSpan
не соответствует вашим потребностям, можно добавить диапазоны с помощью API OpenTelemetry.
Добавьте opentelemetry-api-1.0.0.jar
(или более позднюю версию) в ваше приложение.
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.0.0</version>
</dependency>
Используйте класс GlobalOpenTelemetry
для создания Tracer
.
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Tracer;
static final Tracer tracer = GlobalOpenTelemetry.getTracer("com.example");
Создайте диапазон, сделайте его текущим, а затем завершите его:
Span span = tracer.spanBuilder("my first span").startSpan();
try (Scope ignored = span.makeCurrent()) {
// do stuff within the context of this
} catch (Throwable t) {
span.recordException(t);
} finally {
span.end();
}
Внедрение OpenTelemetry
:
Tracer
Создайте:
import io.opentelemetry.api.trace.Tracer;
static final Tracer tracer = openTelemetry.getTracer("com.example");
Создайте диапазон, сделайте его текущим, а затем завершите его:
Span span = tracer.spanBuilder("my first span").startSpan();
try (Scope ignored = span.makeCurrent()) {
// do stuff within the context of this
} catch (Throwable t) {
span.recordException(t);
} finally {
span.end();
}
// Import the Azure Monitor OpenTelemetry plugin and OpenTelemetry API
const { useAzureMonitor } = require("@azure/monitor-opentelemetry");
const { trace } = require("@opentelemetry/api");
// Enable Azure Monitor integration
useAzureMonitor();
// Get the tracer for the "testTracer" namespace
const tracer = trace.getTracer("testTracer");
// Start a span with the name "hello"
let span = tracer.startSpan("hello");
// End the span
span.end();
API OpenTelemetry можно использовать для добавления собственных спанов, которые отображаются в таблицах requests
и dependencies
в Application Insights.
В примере кода показано, как использовать tracer.start_as_current_span()
метод для запуска, сделать диапазон текущим и завершить диапазон в его контексте.
...
# Import the necessary packages.
from opentelemetry import trace
# Get a tracer for the current module.
tracer = trace.get_tracer(__name__)
# Start a new span with the name "my first span" and make it the current span.
# The "with" context manager starts, makes the span current, and ends the span within it's context
with tracer.start_as_current_span("my first span") as span:
try:
# Do stuff within the context of this span.
# All telemetry generated within this scope will be attributed to this span.
except Exception as ex:
# Record the exception on the span.
span.record_exception(ex)
...
По умолчанию диапазон находится в dependencies
таблице с типом InProc
зависимостей.
Если метод представляет фоновое задание, которое еще не записано автоинструментацией, рекомендуется задать атрибут kind = SpanKind.SERVER
, чтобы он отображался в таблице Application Insights requests
.
...
# Import the necessary packages.
from opentelemetry import trace
from opentelemetry.trace import SpanKind
# Get a tracer for the current module.
tracer = trace.get_tracer(__name__)
# Start a new span with the name "my request span" and the kind set to SpanKind.SERVER.
with tracer.start_as_current_span("my request span", kind=SpanKind.SERVER) as span:
# Do stuff within the context of this span.
...
Отправка пользовательской телеметрии с помощью классического API Application Insights
Мы рекомендуем использовать API OpenTelemetry по возможности, но некоторые сценарии могут возникнуть при использовании классического API Application Insights.
События
Добавьте Microsoft.ApplicationInsights
в свое приложение.
Создайте экземпляр TelemetryClient
:
Примечание.
Важно создать только один экземпляр TelemetryClient для каждого приложения.
var telemetryConfiguration = new TelemetryConfiguration { ConnectionString = "" };
var telemetryClient = new TelemetryClient(telemetryConfiguration);
Используйте клиент для отправки пользовательской телеметрии:
telemetryClient.TrackEvent("testEvent");
События
Добавьте Microsoft.ApplicationInsights
в свое приложение.
Создайте экземпляр TelemetryClient
:
Примечание.
Важно создать только один экземпляр TelemetryClient для каждого приложения.
var telemetryConfiguration = new TelemetryConfiguration { ConnectionString = "" };
var telemetryClient = new TelemetryClient(telemetryConfiguration);
Используйте клиент для отправки пользовательской телеметрии:
telemetryClient.TrackEvent("testEvent");
Добавьте applicationinsights-core
в свое приложение:
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>applicationinsights-core</artifactId>
<version>3.4.18</version>
</dependency>
Создайте экземпляр TelemetryClient
:
static final TelemetryClient telemetryClient = new TelemetryClient();
Используйте клиент для отправки пользовательской телеметрии:
События
telemetryClient.trackEvent("WinGame");
Логи
telemetryClient.trackTrace(message, SeverityLevel.Warning, properties);
Метрики
telemetryClient.trackMetric("queueLength", 42.0);
Зависимости
boolean success = false;
long startTime = System.currentTimeMillis();
try {
success = dependency.call();
} finally {
long endTime = System.currentTimeMillis();
RemoteDependencyTelemetry telemetry = new RemoteDependencyTelemetry();
telemetry.setSuccess(success);
telemetry.setTimestamp(new Date(startTime));
telemetry.setDuration(new Duration(endTime - startTime));
telemetryClient.trackDependency(telemetry);
}
Исключения
try {
...
} catch (Exception e) {
telemetryClient.trackException(e);
}
Невозможно отправлять пользовательские данные телеметрии с помощью классического API Application Insights в собственном коде Java.
Если вы хотите добавить пользовательские события или получить доступ к API Application Insights, замените @azure/monitor-opentelemetry пакет пакетом applicationinsights
бета-версии 3. Он предлагает те же методы и интерфейсы, и весь пример кода для @azure/monitor-opentelemetry применим к пакету Beta v3.
Для отправки пользовательских данных телеметрии с помощью классического API Application Insights необходимо использовать applicationinsights
пакет бета-версии 3. (https://www.npmjs.com/package/applicationinsights/v/beta)
// Import the TelemetryClient class from the Application Insights SDK for JavaScript.
const { TelemetryClient } = require("applicationinsights");
// Create a new TelemetryClient instance.
const telemetryClient = new TelemetryClient();
Затем используйте TelemetryClient
для отправки пользовательской телеметрии.
События
// Create an event telemetry object.
let eventTelemetry = {
name: "testEvent"
};
// Send the event telemetry object to Azure Monitor Application Insights.
telemetryClient.trackEvent(eventTelemetry);
Логи
// Create a trace telemetry object.
let traceTelemetry = {
message: "testMessage",
severity: "Information"
};
// Send the trace telemetry object to Azure Monitor Application Insights.
telemetryClient.trackTrace(traceTelemetry);
Исключения
// Try to execute a block of code.
try {
...
}
// If an error occurs, catch it and send it to Azure Monitor Application Insights as an exception telemetry item.
catch (error) {
let exceptionTelemetry = {
exception: error,
severity: "Critical"
};
telemetryClient.trackException(exceptionTelemetry);
}
В отличие от других языков, Python не имеет пакета SDK Application Insights. Вы можете удовлетворить все потребности мониторинга с помощью дистрибутива OpenTelemetry в Azure Monitor, за исключением отправки customEvents
. Пока API событий OpenTelemetry не стабилизируется, используйте расширение событий Azure Monitor с дистрибутивом OpenTelemetry Azure Monitor для отправки customEvents
в Application Insights.
Установите дистрибутив и расширение:
pip install azure-monitor-opentelemetry
pip install azure-monitor-events-extension
Используйте API, предложенный в расширении track_event
, для отправки пользовательских событий.
...
from azure.monitor.events.extension import track_event
from azure.monitor.opentelemetry import configure_azure_monitor
configure_azure_monitor()
# Use the track_event() api to send custom event telemetry
# Takes event name and custom dimensions
track_event("Test event", {"key1": "value1", "key2": "value2"})
input()
...
Изменение телеметрии
В этом разделе описано, как изменить телеметрию.
Добавление атрибутов диапазона
Эти атрибуты могут включать в себя добавление пользовательского свойства в данные телеметрии. Можно также использовать атрибуты для задания необязательных полей в схеме Application Insights, например "IP-адрес клиента".
Добавьте настраиваемое свойство в Span
Все атрибуты, добавляемые в диапазоны, экспортируются как пользовательские свойства. Они заполняют поле customDimensions в таблице запросов, зависимостей, трассировок или исключений.
Чтобы добавить атрибуты диапазона, используйте один из следующих двух способов:
Совет
Преимущество использования параметров, предоставляемых библиотеками инструментирования, когда они доступны, заключается в том, что доступен весь контекст. В результате пользователи могут добавить или отфильтровать дополнительные атрибуты. Например, параметр обогащения в библиотеке инструментирования HttpClient предоставляет пользователям доступ к HttpRequestMessage и самому HttpResponseMessage. Они могут выбрать что-нибудь из него и сохранить его как атрибут.
Многие библиотеки инструментов предоставляют опцию расширения. Для получения инструкции см. файлы README отдельных библиотек инструментирования.
Использование пользовательского процессора:
Совет
Добавьте процессор, показанный здесь перед добавлением 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");
}
}
Чтобы добавить атрибуты диапазона, используйте один из следующих двух способов:
- Используйте параметры, предоставляемые библиотеками инструментирования.
- Добавьте настраиваемый процессор диапазонов.
Совет
Преимущество использования параметров, предоставляемых библиотеками инструментирования, когда они доступны, заключается в том, что доступен весь контекст. В результате пользователи могут добавить или отфильтровать дополнительные атрибуты. Например, параметр обогащения в библиотеке инструментирования HttpClient предоставляет пользователям доступ к самому httpRequestMessage. Они могут выбрать что-нибудь из него и сохранить его как атрибут.
Многие инструментальные библиотеки предоставляют параметр расширения. См. инструкции в файлах readme отдельных библиотек инструментирования.
Использование пользовательского процессора:
Совет
Добавьте показанный здесь процессор перед экспортером Azure Monitor.
// Create an OpenTelemetry tracer provider builder.
// It is important to keep the TracerProvider instance active throughout the process lifetime.
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
// Add a source named "OTel.AzureMonitor.Demo".
.AddSource("OTel.AzureMonitor.Demo") // Add a new processor named ActivityEnrichingProcessor.
.AddProcessor(new ActivityEnrichingProcessor()) // Add the Azure Monitor trace exporter.
.AddAzureMonitorTraceExporter() // Add the Azure Monitor trace exporter.
.Build();
Добавьте ActivityEnrichingProcessor.cs
в проект, используя следующий код:
public class ActivityEnrichingProcessor : BaseProcessor<Activity>
{
// The OnEnd method is called when an activity is finished. This is the ideal place to enrich the activity with additional data.
public override void OnEnd(Activity activity)
{
// Update the activity's display name.
// The updated activity will be available to all processors which are called after this processor.
activity.DisplayName = "Updated-" + activity.DisplayName;
// Set custom tags on the activity.
activity.SetTag("CustomDimension1", "Value1");
activity.SetTag("CustomDimension2", "Value2");
}
}
Для добавления атрибутов в диапазоны можно использовать opentelemetry-api
.
Добавление одного или нескольких атрибутов диапазона заполняет customDimensions
поле в requests
, dependencies
, traces
или exceptions
таблице.
Добавьте opentelemetry-api-1.0.0.jar
(или более позднюю версию) в приложение:
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.0.0</version>
</dependency>
Добавьте настраиваемые измерения в код:
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.common.AttributeKey;
AttributeKey attributeKey = AttributeKey.stringKey("mycustomdimension");
Span.current().setAttribute(attributeKey, "myvalue1");
Добавьте настраиваемые измерения в код:
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.common.AttributeKey;
AttributeKey attributeKey = AttributeKey.stringKey("mycustomdimension");
Span.current().setAttribute(attributeKey, "myvalue1");
// Import the necessary packages.
const { useAzureMonitor } = require("@azure/monitor-opentelemetry");
const { ReadableSpan, Span, SpanProcessor } = require("@opentelemetry/sdk-trace-base");
const { SemanticAttributes } = require("@opentelemetry/semantic-conventions");
// Create a new SpanEnrichingProcessor class.
class SpanEnrichingProcessor implements SpanProcessor {
forceFlush(): Promise<void> {
return Promise.resolve();
}
shutdown(): Promise<void> {
return Promise.resolve();
}
onStart(_span: Span): void {}
onEnd(span: ReadableSpan) {
// Add custom dimensions to the span.
span.attributes["CustomDimension1"] = "value1";
span.attributes["CustomDimension2"] = "value2";
}
}
// Enable Azure Monitor integration.
const options: AzureMonitorOpenTelemetryOptions = {
// Add the SpanEnrichingProcessor
spanProcessors: [new SpanEnrichingProcessor()]
}
useAzureMonitor(options);
Использование пользовательского процессора:
...
# Import the necessary packages.
from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry import trace
# Create a SpanEnrichingProcessor instance.
span_enrich_processor = SpanEnrichingProcessor()
# Configure OpenTelemetry to use Azure Monitor with the specified connection string.
# Replace `<your-connection-string>` with the connection string to your Azure Monitor Application Insights resource.
configure_azure_monitor(
connection_string="<your-connection-string>",
# Configure the custom span processors to include span enrich processor.
span_processors=[span_enrich_processor],
)
...
Добавьте SpanEnrichingProcessor
в проект, используя следующий код:
# Import the SpanProcessor class from the opentelemetry.sdk.trace module.
from opentelemetry.sdk.trace import SpanProcessor
class SpanEnrichingProcessor(SpanProcessor):
def on_end(self, span):
# Prefix the span name with the string "Updated-".
span._name = "Updated-" + span.name
# Add the custom dimension "CustomDimension1" with the value "Value1".
span._attributes["CustomDimension1"] = "Value1"
# Add the custom dimension "CustomDimension2" with the value "Value2".
span._attributes["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>");
Используйте пример пользовательского свойства, но замените следующие строки кода в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>");
Java автоматически заполняет это поле.
Это поле заполняется автоматически.
Используйте пример пользовательского свойства, но замените следующие строки кода:
...
// Import the SemanticAttributes class from the @opentelemetry/semantic-conventions package.
const { SemanticAttributes } = require("@opentelemetry/semantic-conventions");
// Create a new SpanEnrichingProcessor class.
class SpanEnrichingProcessor implements SpanProcessor {
onEnd(span) {
// Set the HTTP_CLIENT_IP attribute on the span to the IP address of the client.
span.attributes[SemanticAttributes.HTTP_CLIENT_IP] = "<IP Address>";
}
}
Используйте пример пользовательского свойства, но замените следующие строки кода вSpanEnrichingProcessor.py
:
# Set the `http.client_ip` attribute of the span to the specified IP address.
span._attributes["http.client_ip"] = "<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>");
Используйте пример пользовательского свойства:
// Add the user ID to the activity as a tag, but only if the activity is not null.
activity?.SetTag("enduser.id", "<User Id>");
Заполните поле user ID
в таблице requests
, dependencies
или exceptions
.
Добавьте opentelemetry-api-1.0.0.jar
(или позже) в ваше приложение.
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.0.0</version>
</dependency>
Задайте user_Id
в коде:
import io.opentelemetry.api.trace.Span;
Span.current().setAttribute("enduser.id", "myuser");
Заполните поле user ID
в таблице requests
, dependencies
или exceptions
.
Задайте user_Id
в коде:
import io.opentelemetry.api.trace.Span;
Span.current().setAttribute("enduser.id", "myuser");
Используйте пример пользовательского свойства, но замените следующие строки кода:
...
// Import the SemanticAttributes class from the @opentelemetry/semantic-conventions package.
import { SemanticAttributes } from "@opentelemetry/semantic-conventions";
// Create a new SpanEnrichingProcessor class.
class SpanEnrichingProcessor implements SpanProcessor {
onEnd(span: ReadableSpan) {
// Set the ENDUSER_ID attribute on the span to the ID of the user.
span.attributes[SemanticAttributes.ENDUSER_ID] = "<User ID>";
}
}
Используйте пример пользовательского свойства, но замените следующие строки кода:
# Set the `enduser.id` attribute of the span to the specified user ID.
span._attributes["enduser.id"] = "<User ID>"
Добавление атрибутов журнала
OpenTelemetry использует ILogger
.NET.
Добавление пользовательских атрибутов к логам можно осуществить с помощью шаблона для сообщения.
OpenTelemetry использует возможности .NETILogger
.
Добавление дополнительных параметров к журналам можно выполнить с помощью шаблона сообщения.
Logback, Log4j и java.util.log автоматически используются. Присоединение пользовательских измерений к журналам можно сделать следующим образом:
Для собственных приложений Spring Boot функция Logback встроена из коробки.
const { useAzureMonitor } = require("@azure/monitor-opentelemetry");
const bunyan = require('bunyan');
// Instrumentations configuration
const options: AzureMonitorOpenTelemetryOptions = {
instrumentationOptions: {
// Instrumentations generating logs
bunyan: { enabled: true },
}
};
// Enable Azure Monitor integration
useAzureMonitor(options);
var log = bunyan.createLogger({ name: 'testApp' });
log.info({
"testAttribute1": "testValue1",
"testAttribute2": "testValue2",
"testAttribute3": "testValue3"
}, 'testEvent');
Библиотека logging в Python является автоинструментированной. Вы можете присоединить пользовательские измерения к журналам, передав словарь в extra
аргумент журналов:
...
# Create a warning log message with the properties "key1" and "value1".
logger.warning("WARNING: Warning log with properties", extra={"key1": "value1"})
...
Получение идентификатора трассировки или идентификатора диапазона
Вы можете получить 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();
Примечание.
Классы 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();
Для получения идентификатора трассировки или идентификатора диапазона можно использовать opentelemetry-api
.
Добавьте opentelemetry-api-1.0.0.jar
(или позже) в ваше приложение.
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.0.0</version>
</dependency>
Получите идентификатор трассировки запроса и идентификатор диапазона в коде:
import io.opentelemetry.api.trace.Span;
Span span = Span.current();
String traceId = span.getSpanContext().getTraceId();
String spanId = span.getSpanContext().getSpanId();
Получите идентификатор трассировки запроса и идентификатор сегмента в коде:
import io.opentelemetry.api.trace.Span;
Span span = Span.current();
String traceId = span.getSpanContext().getTraceId();
String spanId = span.getSpanContext().getSpanId();
Получите идентификатор трассировки запроса и идентификатор отрезка в коде.
// Import the trace module from the OpenTelemetry API.
const { trace } = require("@opentelemetry/api");
// Get the span ID and trace ID of the active span.
let spanId = trace.getActiveSpan().spanContext().spanId;
let traceId = trace.getActiveSpan().spanContext().traceId;
Получите идентификатор трассировки запроса и идентификатор диапазона в коде:
# Import the necessary libraries.
from opentelemetry import trace
# Get the trace ID and span ID of the current span.
trace_id = trace.get_current_span().get_span_context().trace_id
span_id = trace.get_current_span().get_span_context().span_id
Следующие шаги