本文提供有关如何使用 Azure Monitor Application Insights 为应用程序添加和修改 OpenTelemetry 的指导。
若要详细了解 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
- Servlet
- Spring 计划
注意
Servlet 和 Netty 自动检测涵盖大多数 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 client
- Jetty HttpClient
- JMS
- Kafka
- Netty 客户端
- OkHttp
- RabbitMQ
依赖项(无下游分布式跟踪传播)
- Cassandra
- JDBC
- MongoDB(异步和同步)
- Redis(Lettuce 和 Jedis)
指标
- Micrometer 指标,包括 Spring Boot Actuator 指标
- JMX 指标
日志
- Logback (包括 MDC 属性) ¹³
- Log4j (包括 MDC/线程上下文属性) ¹³
- JBoss 日志记录(包括 MDC 属性) ¹³
- java.util.logging ¹ ³
默认集合
默认情况下,自动收集以下 Azure SDK 发出的遥测数据:
[//]: # "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 原生应用程序的日志
有关 Quartz 原生应用程序,请参阅 Quarkus 文档。
以下 OpenTelemetry 检测库作为 Azure Monitor Application Insights 发行版的一部分包含在内。 有关详细信息,请参阅 Azure SDK for 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 SDK 发出的遥测数据。
脚注
- ¹:支持未经处理的/未捕获的异常的自动报告
- ²:支持 OpenTelemetry 指标
- ³:默认情况下,日志记录仅在 INFO 级别或更高级别收集。 若要更改此设置,请参阅配置选项。
- ⁴:默认情况下,仅当在 WARNING 级别或更高级别执行日志记录时,才会收集日志记录。
提示
所有 OpenTelemetry 指标,无论是从检测库自动收集的还是从自动编码中收集收集的,现在都被认为是用于计费目的的 Application Insights“自定义指标”。 了解详细信息。
从 OpenTelemetry 社区包含检测库时,可以自动收集更多数据。
注意
我们不支持也不保证社区检测库的质量。 要为我们的分发版推荐一个检测库,请在反馈社区中发帖或投票。 请注意,某些检测库基于实验性 OpenTelemetry 规范,可能会在将来引入中断性变更。
若要添加社区库,请在为库添加 NuGet 包后使用 ConfigureOpenTelemetryMeterProvider
或 ConfigureOpenTelemetryTracerProvider
方法。
以下示例演示如何添加运行时检测以收集额外指标:
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 检测,可以使用 ApplicationInsightsClient 中的 TraceHandler 添加它们:
// 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 发行版未正式支持/未随附在内),你可以直接使用检测功能进行检测。 可在此处找到社区检测库的列表。
注意
建议不要将 instrument()
和 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
- 特定于语言的日志记录/指标库
- Application Insights Classic API
下表显示了目前支持的自定义遥测类型:
语言 |
自定义事件 |
自定义指标 |
依赖项 |
异常 |
页面视图 |
请求 |
跟踪 |
ASP.NET Core |
|
|
|
|
|
|
|
OpenTelemetry API |
|
是 |
是 |
是 |
|
是 |
|
ILogger API |
|
|
|
|
|
|
是 |
AI Classic API |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Java |
|
|
|
|
|
|
|
OpenTelemetry API |
|
是 |
是 |
是 |
|
是 |
|
Logback,Log4j ,JUL |
|
|
|
是 |
|
|
是 |
Micrometer 指标 |
|
是 |
|
|
|
|
|
AI Classic API |
是 |
是 |
是 |
是 |
是 |
是 |
是 |
|
|
|
|
|
|
|
|
Node.js |
|
|
|
|
|
|
|
OpenTelemetry API |
|
是 |
是 |
是 |
|
是 |
|
|
|
|
|
|
|
|
|
Python |
|
|
|
|
|
|
|
OpenTelemetry API |
|
是 |
是 |
是 |
|
是 |
|
Python 日志记录模块 |
|
|
|
|
|
|
是 |
事件扩展 |
是 |
|
|
|
|
|
是 |
注意
Application Insights Java 3.x 会侦听发送到 Application Insights Classic API 的遥测数据。 类似地,Application Insights Node.js 3.x 会收集使用 Application Insights Classic API 创建的事件。 在所有自定义遥测类型都通过 OpenTelemetry API 得到支持之前,这可以简化升级,并填补自定义遥测支持中的空白。
添加自定义指标
在这种情况下,自定义指标这个术语是指收集检测代码,以收集 OpenTelemetry 检测库没有自动收集的额外指标。
OpenTelemetry API 提供六种指标“检测”来涵盖各种指标方案,在指标资源管理器中可视化指标时,需要选取正确的“聚合类型”。 使用 OpenTelemetry 指标 API 发送指标和使用检测库时,此要求是正确的。
下表显示了每个 OpenTelemetry 指标检测的建议聚合类型。
OpenTelemetry 检测 |
Azure Monitor 聚合类型 |
计数器 |
Sum |
异步计数器 |
Sum |
直方图 |
Min、Max、Average、Sum 和 Count |
异步仪表 |
平均值 |
UpDownCounter |
Sum |
异步 UpDownCounter |
Sum |
OpenTelemetry 规范介绍了这些检测,并提供了何时可以使用每种检测的示例。
提示
直方图是最通用的,也与 Application Insights GetMetric Classic API 最接近。 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 的异常。
但是,你可能想要手动报告检测库报告的异常之外的异常。
例如,通常不会报告代码捕获的异常。 你可能希望报告这些异常,以便在相关体验中引起注意,包括故障部分和端到端事务视图。
要使用 Activity 记录异常:
// 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 记录异常:
// 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);
这些手动记录的基于跨度的异常只有在远程、内部跨度的子跨度上记录时或者在顶级跨度上记录时,Node.js SDK 才会将其导出到 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);
}
OpenTelemetry Python SDK 的实现方式使得引发的异常会被自动捕获和记录。 有关此行为的示例,请参阅以下代码示例:
# 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)
...
添加自定义范围
你可能想要在两种情况下添加自定义跨度。 首先,当存在检测库尚未收集的依赖项请求时。 其次,当你希望在端到端事务视图上将应用程序进程建模为跨度时。
注意
System.Diagnostics
命名空间中的 Activity
和 ActivitySource
类分别代表 Span
和 Tracer
的 OpenTelemetry 概念。 可以通过使用其构造函数而不是使用 TracerProvider
来直接创建 ActivitySource
。 每个 ActivitySource
类都必须使用 AddSource()
显式连接到 TracerProvider
。 这是因为 OpenTelemetry 跟踪 API 的某些部分会直接合并到 .NET 运行时中。 若要了解详细信息,请参阅 OpenTelemetry .NET 跟踪 API 简介。
// 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
。
注意
System.Diagnostics
命名空间中的 Activity
和 ActivitySource
类分别代表 Span
和 Tracer
的 OpenTelemetry 概念。 可以通过使用其构造函数而不是使用 TracerProvider
来直接创建 ActivitySource
。 每个 ActivitySource
类都必须使用 AddSource()
显式连接到 TracerProvider
。 这是因为 OpenTelemetry 跟踪 API 的某些部分会直接合并到 .NET 运行时中。 若要了解详细信息,请参阅 OpenTelemetry .NET 跟踪 API 简介。
// 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
注释。
范围会填充 Application Insights 中的 requests
和 dependencies
表。
将 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
批注,以确保它们会显示在 Application Insights requests
表中。
使用 OpenTelemetry API
如果上述 OpenTelemetry @WithSpan
注释不能满足你的需求,可使用 OpenTelemetry API 添加范围。
将 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();
OpenTelemetry API 可用于添加你自己的跨度,它们会显示在 Application Insights 的 requests
和 dependencies
表中。
代码示例演示如何使用 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.
...
使用 Application Insights Classic API 发送自定义遥测数据
建议尽可能使用 OpenTelemetry API,但在某些情况下,可能必须使用 Application Insights Classic API。
事件
向应用程序添加 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);
}
无法使用 Java Native 中的 Application Insights 经典 API 发送自定义遥测数据。
如果要添加自定义事件或访问 Application Insights API,请将 @azure/monitor-opentelemetry 包替换为 applicationinsights
v3 Beta 包。 它提供相同的方法和接口,并且@azure/monitor-opentelemetry的所有示例代码都适用于 v3 Beta 包。
需要使用 Application Insights Classic API 发送自定义遥测数据,请使用applicationinsights
v3 Beta 版包。 (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 没有 Application Insights SDK。 可以使用 Azure Monitor OpenTelemetry 发行版满足所有监视需求,但发送customEvents
除外。 在 OpenTelemetry 事件 API 稳定之前,请将Azure Monitor 事件扩展与 Azure Monitor OpenTelemetry 发行版结合使用,以将customEvents
发送到 Application Insights。
安装发行版和扩展:
pip install azure-monitor-opentelemetry
pip install azure-monitor-events-extension
使用扩展中提供的 track_event
API 发送 customEvents:
...
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。
将自定义属性添加到范围
你添加到范围的任何属性都将导出为自定义属性。 它们将填充请求、依赖项、跟踪或异常表中的 customDimensions 字段。
若要添加范围属性,请使用以下两种方法之一:
许多检测库都提供扩充选项。 有关指南,请参阅各个检测库的自述文件:
使用自定义处理器:
提示
添加 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。 他们可以从中选择任何内容并将其存储为属性。
许多检测库都提供扩充选项。 有关指南,请参阅各个检测库的自述文件:
使用自定义处理器:
提示
在使用 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
向范围中添加属性。
添加一个或多个范围属性会填充 requests
、dependencies
、traces
或 exceptions
表中的 customDimensions
字段。
将 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>");
使用自定义属性示例,但替换以下代码行:
...
// 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>"
设置用户 ID 或经过身份验证的用户 ID
可以使用以下指导填充请求的 user_Id 或 user_AuthenticatedId 字段。 用户 ID 是匿名用户标识符。 经过身份验证的用户 ID 是已知的用户标识符。
重要
在设置经过身份验证的用户 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>");
使用自定义属性示例:
// Add the user ID to the activity as a tag, but only if the activity is not null.
activity?.SetTag("enduser.id", "<User Id>");
填充 requests
、dependencies
或 exceptions
表中的 user ID
字段。
将 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");
填充 requests
、dependencies
或 exceptions
表中的 user ID
字段。
在代码中设置 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 使用 .NET 的 ILogger
。
可以使用消息模板将自定义维度附加到日志。
OpenTelemetry 使用 .NET 的 ILogger
。
可以使用消息模板将自定义维度附加到日志。
会自动检测 Logback、Log4j 和 java.util.logging。 可通过以下方式将自定义维度附加到日志:
对于 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');
Python 日志记录库是自动检测的。 通过将字典传递到日志的 extra
参数,可以将自定义维度附加到日志:
...
# Create a warning log message with the properties "key1" and "value1".
logger.warning("WARNING: Warning log with properties", extra={"key1": "value1"})
...
获取跟踪 ID 或范围 ID
可以使用以下步骤获取当前处于活动状态的范围的 Trace ID
和 Span ID
。
注意
System.Diagnostics
命名空间中的 Activity
和 ActivitySource
类分别代表 Span
和 Tracer
的 OpenTelemetry 概念。 这是因为 OpenTelemetry 跟踪 API 的某些部分会直接合并到 .NET 运行时中。 若要了解详细信息,请参阅 OpenTelemetry .NET 跟踪 API 简介。
// 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();
注意
System.Diagnostics
命名空间中的 Activity
和 ActivitySource
类分别代表 Span
和 Tracer
的 OpenTelemetry 概念。 这是因为 OpenTelemetry 跟踪 API 的某些部分会直接合并到 .NET 运行时中。 若要了解详细信息,请参阅 OpenTelemetry .NET 跟踪 API 简介。
// 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
获取跟踪 ID 或范围 ID。
将 opentelemetry-api-1.0.0.jar
(或更高版本)添加到应用程序:
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.0.0</version>
</dependency>
在代码中获取请求跟踪 ID 和范围 ID:
import io.opentelemetry.api.trace.Span;
Span span = Span.current();
String traceId = span.getSpanContext().getTraceId();
String spanId = span.getSpanContext().getSpanId();
在代码中获取请求跟踪 ID 和范围 ID:
import io.opentelemetry.api.trace.Span;
Span span = Span.current();
String traceId = span.getSpanContext().getTraceId();
String spanId = span.getSpanContext().getSpanId();
在代码中获取请求跟踪 ID 和范围 ID:
// 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;
在代码中获取请求跟踪 ID 和范围 ID:
# 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
后续步骤