Panduan ini memberikan instruksi tentang mengintegrasikan dan menyesuaikan instrumentasi OpenTelemetry (OTel) dalam Azure Monitor Application Insights.
Untuk mempelajari selengkapnya tentang konsep OpenTelemetry, lihat gambaran umum OpenTelemetry.
Untuk gambaran umum semua pustaka instrumentasi yang disertakan dengan distro OpenTelemetry Azure Monitor, lihat Automatic data collection and resource detectors for Azure Monitor OpenTelemetry.
Anda dapat mengumpulkan lebih banyak data secara otomatis saat menyertakan pustaka instrumentasi dari komunitas OpenTelemetry.
Perhatian
Kami tidak mendukung atau menjamin kualitas pustaka instrumentasi komunitas. Untuk menyarankan satu untuk distro kami, posting atau beri suara di komunitas feedback kami. Perlu diketahui, beberapa didasarkan pada spesifikasi OpenTelemetry eksperimental dan mungkin memperkenalkan perubahan besar di masa depan.
Untuk menambahkan pustaka komunitas, gunakan ConfigureOpenTelemetryMeterProvider metode atau ConfigureOpenTelemetryTracerProvider , setelah menambahkan paket NuGet untuk pustaka.
Contoh berikut menunjukkan cara menambahkan Instrumentasi Runtime untuk mengumpulkan metrik tambahan:
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();
Contoh berikut menunjukkan cara menambahkan Instrumentasi Runtime guna mengumpulkan metrik tambahan.
// 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();
Anda tidak dapat memperluas agen Java dengan pustaka instrumentasi komunitas. Untuk meminta pustaka instrumentasi lain disertakan, buka masalah di halaman GitHub.
Anda tidak dapat menggunakan pustaka komunitas instrumentasi dengan aplikasi asli GraalVM Java.
export class RegisterExpressInstrumentationSample {
static async run() {
// Dynamically import Azure Monitor and Express instrumentation
const { useAzureMonitor } = await import("@azure/monitor-opentelemetry");
const { registerInstrumentations } = await import("@opentelemetry/instrumentation");
const { ExpressInstrumentation } = await import("@opentelemetry/instrumentation-express");
// Initialize Azure Monitor (uses env var if set)
const monitor = useAzureMonitor();
// Register the Express instrumentation
registerInstrumentations({
instrumentations: [new ExpressInstrumentation()],
});
console.log("Express instrumentation registered");
}
}
Untuk menambahkan pustaka instrumentasi komunitas, instrumenkan langsung dengan alat tersebut. Anda dapat menemukan daftar pustaka instrumentasi komunitas di GitHub.
Catatan
Jangan menginstrumentasi librari instrumentasi yang didukung secara manual dengan menggunakan instrument() dan distro configure_azure_monitor(). Pendekatan ini tidak didukung dan dapat menyebabkan perilaku yang tidak diinginkan untuk telemetri Anda.
# 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())
Mengumpulkan telemetri kustom
Bagian ini menjelaskan cara mengumpulkan telemetri kustom dari aplikasi Anda.
Bergantung pada bahasa dan jenis sinyal Anda, ada berbagai cara untuk mengumpulkan telemetri kustom, termasuk:
- OpenTelemetry API (antarmuka pemrograman aplikasi OpenTelemetry)
- Pustaka pencatatan/metrik khusus bahasa
Tabel berikut ini mewakili jenis telemetri kustom yang saat ini didukung:
| Bahasa |
Peristiwa Kustom |
Metrik Khusus |
Dependensi |
Pengecualian |
Tampilan Halaman |
Permintaan |
Jejak |
|
ASP.NET Core |
|
|
|
|
|
|
|
| OpenTelemetry API (antarmuka pemrograman aplikasi OpenTelemetry) |
|
Ya |
Ya |
Ya |
|
Ya |
|
ILogger Antarmuka Pemrograman Aplikasi (API) |
Ya |
|
|
|
|
|
Ya |
|
|
|
|
|
|
|
|
|
Java |
|
|
|
|
|
|
|
| OpenTelemetry API (antarmuka pemrograman aplikasi OpenTelemetry) |
Ya |
Ya |
Ya |
Ya |
|
Ya |
|
Logback, Log4j, JUL |
|
|
|
Ya |
|
|
Ya |
| Metrik Mikrometer |
|
Ya |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Node.js |
|
|
|
|
|
|
|
| OpenTelemetry API (antarmuka pemrograman aplikasi OpenTelemetry) |
Ya |
Ya |
Ya |
Ya |
|
Ya |
|
|
|
|
|
|
|
|
|
|
Python |
|
|
|
|
|
|
|
| OpenTelemetry API (antarmuka pemrograman aplikasi OpenTelemetry) |
|
Ya |
Ya |
Ya |
|
Ya |
|
| Modul Pengelogan Python |
|
|
|
|
|
|
Ya |
| Ekstensi Peristiwa |
Ya |
|
|
|
|
|
Ya |
Menambahkan metrik kustom
Dalam konteks ini, istilah metrik khusus merujuk pada proses menambahkan instrumen secara manual ke dalam kode Anda untuk mengumpulkan metrik tambahan, melampaui apa yang secara otomatis dikumpulkan oleh OpenTelemetry Instrumentation Libraries. Untuk mempelajari selengkapnya tentang menggunakan metrik, lihat Metrik di Application Insights.
API OpenTelemetry menawarkan enam metrik "instrumen" untuk mencakup berbagai skenario metrik dan Anda perlu memilih "Jenis Agregasi" yang benar saat memvisualisasikan metrik di Metrics Explorer. Persyaratan ini berlaku saat menggunakan API Metrik OpenTelemetry untuk mengirim metrik dan saat menggunakan pustaka instrumentasi.
Tabel berikut menunjukkan jenis agregasi yang direkomendasikan untuk setiap Instrumen Metrik OpenTelemetry.
| Instrumen OpenTelemetry |
Jenis Agregasi Azure Monitor |
| Penghitung |
Jumlah total |
| Penghitung Asinkron |
Jumlah total |
| Histogram |
Min, Maks, Rata-rata, Jumlah, dan Hitungan |
| Pengukur Asinkron |
Tengah |
| UpDownCounter |
Jumlah total |
| PenghitungNaikTurun Asinkron |
Jumlah total |
Perhatian
Jenis agregasi lainnya tidak bermakna dalam banyak kasus.
Spesifikasi OpenTelemetry menjelaskan instrumen dan memberikan contoh kapan Anda dapat menggunakan masing-masing instrumen.
Tips
Histogram adalah instrumen metrik OpenTelemetry paling serbaguna untuk merekam distribusi. Azure Monitor saat ini meratakan instrumen histogram ke dalam lima jenis agregasi yang didukung, dan dukungan untuk persentil sedang berlangsung. Meskipun kurang serbaguna, instrumen OpenTelemetry lainnya memiliki efek yang lebih rendah pada performa aplikasi Anda.
Contoh histogram
Startup aplikasi harus berlangganan Meter menurut nama:
// 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 harus diinisialisasi menggunakan nama yang sama:
// 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);
}
}
Menyuntikkan OpenTelemetry:
Buat histogram:
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);
Catatan
Komunitas Quarkus mendukung dan memelihara ekstensi Quarkus. Untuk bantuan, gunakan saluran dukungan komunitas Quarkus. Microsoft tidak memberikan dukungan teknis untuk integrasi ini.
export class HistogramSample {
static async run() {
// Dynamically import Azure Monitor and metrics API
const { useAzureMonitor } = await import("@azure/monitor-opentelemetry");
const { metrics } = await import("@opentelemetry/api");
// Initialize Azure Monitor
const monitor = useAzureMonitor({
azureMonitorExporterOptions: {
connectionString:
process.env.APPLICATIONINSIGHTS_CONNECTION_STRING || "<YOUR-CONNECTION-STRING>",
},
});
// Create a histogram and record values
const meter = metrics.getMeter("testMeter");
const histogram = meter.createHistogram("histogram");
histogram.record(1, { testKey: "testValue" });
histogram.record(30, { testKey: "testValue2" });
histogram.record(100, { testKey2: "testValue" });
console.log("Histogram metrics recorded");
}
}
# 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()
Contoh pengecualian
Startup aplikasi harus berlangganan Meter menurut nama:
// 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 harus diinisialisasi menggunakan nama yang sama:
// 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"));
}
}
Menyuntikkan OpenTelemetry:
Buat penghitung:
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"));
Catatan
Komunitas Quarkus mendukung dan memelihara ekstensi Quarkus. Untuk bantuan, gunakan saluran dukungan komunitas Quarkus. Microsoft tidak memberikan dukungan teknis untuk integrasi ini.
export class CounterSample {
static async run() {
// Dynamically import Azure Monitor and metrics API
const { useAzureMonitor } = await import("@azure/monitor-opentelemetry");
const { metrics } = await import("@opentelemetry/api");
// Initialize Azure Monitor
const monitor = useAzureMonitor({
azureMonitorExporterOptions: {
connectionString:
process.env.APPLICATIONINSIGHTS_CONNECTION_STRING || "<YOUR-CONNECTION-STRING>",
},
});
// Create a counter and add some sample values
const meter = metrics.getMeter("otel_azure_monitor_counter_demo");
const counter = meter.createCounter("MyFruitCounter");
counter.add(1, { name: "apple", color: "red" });
counter.add(2, { name: "lemon", color: "yellow" });
counter.add(1, { name: "lemon", color: "yellow" });
counter.add(2, { name: "apple", color: "green" });
counter.add(5, { name: "apple", color: "red" });
counter.add(4, { name: "lemon", color: "yellow" });
console.log("Counter metrics recorded");
}
}
# 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()
Contoh pengukur
Startup aplikasi harus berlangganan Meter menurut nama:
// 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 harus diinisialisasi menggunakan nama yang sama:
// 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"));
});
}
}
Menyuntikkan OpenTelemetry:
Buat pengukur:
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"));
});
Catatan
Komunitas Quarkus mendukung dan memelihara ekstensi Quarkus. Untuk bantuan, gunakan saluran dukungan komunitas Quarkus. Microsoft tidak memberikan dukungan teknis untuk integrasi ini.
export class GaugeSample {
static async run() {
// Dynamically import Azure Monitor and metrics API
const { useAzureMonitor } = await import("@azure/monitor-opentelemetry");
const { metrics } = await import("@opentelemetry/api");
// Initialize Azure Monitor
const monitor = useAzureMonitor({
azureMonitorExporterOptions: {
connectionString:
process.env.APPLICATIONINSIGHTS_CONNECTION_STRING || "<YOUR-CONNECTION-STRING>",
},
});
// Create an observable gauge and register a callback
const meter = metrics.getMeter("testMeter");
const gauge = meter.createObservableGauge("gauge");
gauge.addCallback((observableResult) => {
const randomNumber = Math.floor(Math.random() * 100);
observableResult.observe(randomNumber, { testKey: "testValue" });
});
console.log("Observable gauge registered");
}
}
# 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()
Menambahkan pengecualian kustom
Pustaka instrumentasi yang dipilih secara otomatis melaporkan pengecualian ke Application Insights.
Namun, Anda mungkin ingin melaporkan pengecualian secara manual selain dari apa yang dilaporkan oleh pustaka instrumentasi.
Misalnya, pengecualian yang ditangkap oleh kode Anda biasanya tidak dilaporkan. Anda mungkin ingin melaporkannya untuk menarik perhatian dalam pengalaman terkait, termasuk di bagian kegagalan dan pandangan transaksi menyeluruh.
Untuk mencatat Pengecualian menggunakan Aktivitas:
// 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);
}
}
Untuk mencatat Pengecualian menggunakan 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" });
}
Untuk mencatat Pengecualian menggunakan Aktivitas:
// 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);
}
}
Untuk mencatat Pengecualian menggunakan 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" });
}
Anda dapat menggunakan opentelemetry-api untuk memperbarui status rentang dan merekam pengecualian.
Tambahkan opentelemetry-api-1.0.0.jar (atau yang lebih baru) ke aplikasi Anda:
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.0.0</version>
</dependency>
Atur status ke error dan rekam pengecualian dalam kode Anda:
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
Span span = Span.current();
span.setStatus(StatusCode.ERROR, "errorMessage");
span.recordException(e);
Atur status ke error dan rekam pengecualian dalam kode Anda:
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 mengekspor pengecualian berbasis rentang yang direkam secara manual ke Application Insights sebagai pengecualian hanya ketika dicatat pada rentang tingkat atas atau anak dari rentang jarak jauh atau internal.
export class CustomExceptionSample {
static async run() {
// Dynamically import Azure Monitor and tracing API
const { useAzureMonitor } = await import("@azure/monitor-opentelemetry");
const { trace } = await import("@opentelemetry/api");
// Initialize Azure Monitor
const monitor = useAzureMonitor({
azureMonitorExporterOptions: {
connectionString:
process.env.APPLICATIONINSIGHTS_CONNECTION_STRING || "<YOUR-CONNECTION-STRING>",
},
});
// Create a span and record an exception
const tracer = trace.getTracer("testTracer");
const span = tracer.startSpan("hello");
try {
throw new Error("Test Error");
} catch (error) {
span.recordException(error as Error);
} finally {
span.end();
}
console.log("Exception recorded on span");
}
}
OpenTelemetry Python SDK diimplementasikan sedemikian sehingga pengecualian yang dilemparkan secara otomatis ditangkap dan direkam. Lihat sampel kode berikut untuk contoh perilaku ini:
# 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")
Jika Anda ingin merekam pengecualian secara manual, Anda dapat menonaktifkan opsi tersebut dalam manajer konteks dan menggunakan record_exception() langsung seperti yang ditunjukkan dalam contoh berikut:
...
# 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)
...
Menambahkan rentang kustom
Anda mungkin ingin menambahkan rentang kustom dalam dua skenario. Pertama, ketika ada permintaan dependensi yang belum dikumpulkan oleh pustaka instrumentasi. Kedua, ketika Anda ingin memodelkan proses aplikasi sebagai rentang pada pandangan transaksi menyeluruh.
Catatan
Kelas Activity dan ActivitySource dari namespace System.Diagnostics, masing-masing menggambarkan konsep OpenTelemetry dari Span dan Tracer. Anda membuat ActivitySource secara langsung dengan menggunakan konstruktornya daripada menggunakan TracerProvider. Setiap kelas ActivitySource harus secara eksplisit terhubung ke TracerProvider dengan menggunakan AddSource(). Ini karena bagian dari API pelacakan OpenTelemetry dimasukkan langsung ke dalam runtime .NET. Untuk mempelajari lebih lanjut, lihat Introduction ke OpenTelemetry .NET Tracing 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 berfungsi sebagai bawaan ke ActivityKind.Internal, tetapi Anda dapat memberikan nilai lain ActivityKind.
ActivityKind.Client, ActivityKind.Producer, dan ActivityKind.Internal dipetakan ke Application Insights dependencies.
ActivityKind.Server dan ActivityKind.Consumer dipetakan ke Application Insights requests.
Catatan
Kelas Activity dan ActivitySource dari namespace System.Diagnostics, masing-masing menggambarkan konsep OpenTelemetry dari Span dan Tracer. Anda membuat ActivitySource secara langsung dengan menggunakan konstruktornya daripada menggunakan TracerProvider. Setiap kelas ActivitySource harus secara eksplisit terhubung ke TracerProvider dengan menggunakan AddSource(). Ini karena bagian dari API pelacakan OpenTelemetry dimasukkan langsung ke dalam runtime .NET. Untuk mempelajari lebih lanjut, lihat Introduction ke OpenTelemetry .NET Tracing 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 berfungsi sebagai bawaan ke ActivityKind.Internal, tetapi Anda dapat memberikan nilai lain ActivityKind.
ActivityKind.Client, ActivityKind.Producer, dan ActivityKind.Internal dipetakan ke Application Insights dependencies.
ActivityKind.Server dan ActivityKind.Consumer dipetakan ke Application Insights requests.
Gunakan anotasi OpenTelemetry
Cara paling sederhana untuk menambahkan span Anda sendiri adalah dengan menggunakan anotasi OpenTelemetry @WithSpan.
Rentang mengisi tabel requests dan dependencies di Application Insights.
Tambahkan opentelemetry-instrumentation-annotations-1.32.0.jar (atau yang lebih baru) ke aplikasi Anda:
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-instrumentation-annotations</artifactId>
<version>1.32.0</version>
</dependency>
Gunakan anotasi @WithSpan untuk memancarkan rentang setiap kali metode Anda dijalankan:
import io.opentelemetry.instrumentation.annotations.WithSpan;
@WithSpan(value = "your span name")
public void yourMethod() {
}
Secara bawaan, rentang berakhir di tabel dependencies dengan jenis InProc dependensi.
Untuk metode yang mewakili tugas latar belakang yang tidak tercakup oleh autoinstrumentasi, sebaiknya terapkan atribut kind = SpanKind.SERVER ke anotasi @WithSpan untuk memastikan mereka muncul di tabel Application Insights requests.
Menggunakan API OpenTelemetry
Jika anotasi OpenTelemetry @WithSpan sebelumnya tidak memenuhi kebutuhan Anda, Anda dapat menambahkan rentang Anda dengan menggunakan API OpenTelemetry.
Tambahkan opentelemetry-api-1.0.0.jar (atau yang lebih baru) ke aplikasi Anda:
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.0.0</version>
</dependency>
Gunakan kelas GlobalOpenTelemetry untuk membuat Tracer.
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Tracer;
static final Tracer tracer = GlobalOpenTelemetry.getTracer("com.example");
Buat rentang, jadikan sebagai yang aktif, lalu akhiri.
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();
}
Menyuntikkan OpenTelemetry:
Buat Tracer:
import io.opentelemetry.api.trace.Tracer;
static final Tracer tracer = openTelemetry.getTracer("com.example");
Buat rentang, jadikan sebagai yang aktif, lalu akhiri.
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();
}
Catatan
Komunitas Quarkus mendukung dan memelihara ekstensi Quarkus. Untuk bantuan, gunakan saluran dukungan komunitas Quarkus. Microsoft tidak memberikan dukungan teknis untuk integrasi ini.
export class CustomTraceSample {
static async run() {
// Dynamically import Azure Monitor and tracing API
const { useAzureMonitor } = await import("@azure/monitor-opentelemetry");
const { trace } = await import("@opentelemetry/api");
// Initialize Azure Monitor
const monitor = useAzureMonitor({
azureMonitorExporterOptions: {
connectionString:
process.env.APPLICATIONINSIGHTS_CONNECTION_STRING || "<YOUR-CONNECTION-STRING>",
},
});
// Create a custom span, add attributes/events, then end
const tracer = trace.getTracer("otel_azure_monitor_custom_trace_demo");
const span = tracer.startSpan("doWork");
try {
span.setAttribute("component", "worker");
span.setAttribute("operation.id", "42");
span.addEvent("invoking doWork");
for (let i = 0; i < 1_000_000; i++) { /* simulate work */ }
} catch (err) {
span.recordException(err as Error);
} finally {
span.end();
}
console.log("Custom span recorded");
}
}
API OpenTelemetry dapat digunakan untuk menambahkan rentang Anda sendiri, yang muncul di tabel requests dan dependencies dalam Application Insights.
Contoh kode menunjukkan cara menggunakan metode tracer.start_as_current_span() untuk memulai, membuat rentang menjadi saat ini, dan mengakhiri rentang dalam konteksnya.
...
# 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)
...
Secara bawaan, rentang berada dalam tabel dependencies dengan jenis dependensiInProc.
Jika metode Anda mewakili pekerjaan latar belakang yang belum diambil oleh autoinstrumentation, sebaiknya atur atribut kind = SpanKind.SERVER untuk memastikannya muncul di tabel 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.
...
Kirim peristiwa kustom
Application Insights menyimpan peristiwa kustom dalam customEvents tabel. Salah satu cara untuk menganalisis, memfilter, dan memvisualisasikannya adalah dengan menggunakan pengalaman penggunaan Application Insights.
Jika Anda ingin mengotomatiskan pengumpulan peristiwa interaksi sisi klien, Anda dapat menggunakan plugin di JavaScript SDK.
Peristiwa kustom menggunakan Azure.Monitor.OpenTelemetry.AspNetCore.
Untuk mengirim CustomEvent menggunakan ILogger, atur "microsoft.custom_event.name" atribut dalam templat pesan.
// Create a logger factory and configure OpenTelemetry with Azure Monitor
var loggerFactory = LoggerFactory.Create(builder =>
{
builder
.AddOpenTelemetry(options =>
{
options.AddAzureMonitorLogExporter();
});
});
// Create a logger for the specified category
var logger = loggerFactory.CreateLogger(logCategoryName);
// Log a custom event with a custom name and additional attribute
// The 'microsoft.custom_event.name' value will be used as the name of the customEvent
logger.LogInformation("{microsoft.custom_event.name} {additional_attrs}", "test-event-name", "val1");
Peristiwa kustom menggunakan Azure.Monitor.OpenTelemetry.Exporter.
Untuk mengirim CustomEvent menggunakan ILogger, atur "microsoft.custom_event.name" atribut dalam templat pesan.
// Create a logger factory and configure OpenTelemetry with Azure Monitor
var loggerFactory = LoggerFactory.Create(builder =>
{
builder
.AddOpenTelemetry(options =>
{
options.AddAzureMonitorLogExporter();
});
});
// Create a logger for the specified category
var logger = loggerFactory.CreateLogger(logCategoryName);
// Log a custom event with a custom name and additional attribute
// The 'microsoft.custom_event.name' value will be used as the name of the customEvent
logger.LogInformation("{microsoft.custom_event.name} {additional_attrs}", "test-event-name", "val1");
Untuk mengirim customEvent dengan agen Java, atur atribut "microsoft.custom_event.name" pada catatan log OpenTelemetry.
Bergantung pada apakah agen Java Application Insights sedang digunakan, atau SDK konfigurasi otomatis, cara mengambil pencatat OpenTelemetry sedikit berbeda. Detail ini dijelaskan lebih lanjut dalam contoh berikut.
Untuk agen Java Application Insights:
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.logs.Logger;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.logs.Severity;
Logger logger = GlobalOpenTelemetry.get().getLogsBridge().get("opentelemetry-logger");
logger.logRecordBuilder()
.setAttribute(AttributeKey.stringKey("microsoft.custom_event.name"),"test-event-name")
.setSeverity(Severity.INFO)
.emit();
Untuk konfigurasi otomatis SDK:
import com.azure.monitor.opentelemetry.autoconfigure.AzureMonitorAutoConfigure;
import com.azure.monitor.opentelemetry.autoconfigure.AzureMonitorAutoConfigureOptions;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.logs.Logger;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder;
AutoConfiguredOpenTelemetrySdkBuilder sdkBuilder = AutoConfiguredOpenTelemetrySdk.builder();
AzureMonitorAutoConfigureOptions options = new AzureMonitorAutoConfigureOptions();
options.connectionString("<YOUR-CONNECTION-STRING>");
AzureMonitorAutoConfigure.customize(sdkBuilder, options);
OpenTelemetry openTelemetry = sdkBuilder.build().getOpenTelemetrySdk();
Logger logger = openTelemetry.getLogsBridge().get("opentelemetry-logger");
logger.logRecordBuilder()
.setAttribute(AttributeKey.stringKey("microsoft.custom_event.name"),"test-event-name")
.setSeverity(Severity.INFO)
.emit();
Untuk memancarkan peristiwa kustom dengan andal, gunakan API OpenTelemetry secara langsung. Beberapa kerangka kerja pengelogan tidak mendukung penambahan atau penguraian atribut peristiwa kustom.
Tidak dimungkinkan untuk mengirim customEvent menggunakan atribut "microsoft.custom_event.name" di Java asli.
Untuk mengirim customEvent menggunakan logger.emit, atur "microsoft.custom_event.name" atribut di objek log attributes . Atribut lain juga dapat disertakan sesuai kebutuhan.
export class CustomEventSample {
static async run() {
// Dynamically import Azure Monitor and the OpenTelemetry logs API
const { useAzureMonitor } = await import("@azure/monitor-opentelemetry");
const { logs, SeverityNumber } = await import("@opentelemetry/api-logs");
// Initialize Azure Monitor (enables logs bridge)
const monitor = useAzureMonitor();
// Get a logger and emit a customEvent by setting the microsoft attribute key
const logger = logs.getLogger("my-app-logger");
logger.emit({
body: "Hello World!",
severityNumber: SeverityNumber.INFO,
attributes: {
"microsoft.custom_event.name": "test-event-name",
"additional_attrs": "val1",
},
});
// Example: populate client_IP via attribute 'client.address'
logger.emit({
body: "This entry will have a custom client_IP",
severityNumber: SeverityNumber.INFO,
attributes: {
"microsoft.custom_event.name": "test_event",
"client.address": "192.168.1.1",
},
});
console.log("Custom events emitted");
}
}
Untuk mengirim customEvent di Python, gunakan pustaka logging dengan atribut "microsoft.custom_event.name" dalam parameter extra.
import logging
from azure.monitor.opentelemetry import configure_azure_monitor
# Set up your application logger
logger = logging.getLogger("my-app-logger")
# Configure Azure Monitor to collect logs from the specified logger name
configure_azure_monitor(
logger_name="my-app-logger", # Collect logs from your namespaced logger
)
# Log a custom event with a custom name and additional attribute
# The 'microsoft.custom_event.name' value will be used as the name of the customEvent
logger.warning(
"Hello World!",
extra={
"microsoft.custom_event.name": "test-event-name",
"additional_attrs": "val1"
}
)
# You can also populate fields like client_IP with attribute `client.address`
logger.info(
"This entry will have a custom client_IP",
extra={
"microsoft.custom_event.name": "test_event",
"client.address": "192.168.1.1"
}
)
Mengubah telemetri
Bagian ini menjelaskan cara memodifikasi telemetri.
Menambahkan atribut rentang
Atribut ini mungkin menambahkan properti kustom ke telemetri Anda. Anda mungkin juga menggunakan atribut untuk mengatur bidang opsional dalam Skema Application Insights seperti IP Klien.
Menambahkan properti kustom ke Rentang
Atribut apa pun yang Anda tambahkan ke rentang diekspor sebagai properti kustom. Mereka mengisi kolom customDimensions dalam tabel yang berisi permintaan, jejak, pengecualian, atau dependensi.
Untuk menambahkan atribut rentang, gunakan salah satu dari dua cara berikut ini:
Tips
Keuntungan menggunakan opsi yang disediakan oleh pustaka instrumentasi, ketika opsi tersebut ada, yaitu tersedianya seluruh konteks. Sebagai hasilnya, pengguna dapat memilih untuk menambahkan atau memfilter lebih banyak atribut. Misalnya, opsi pengayaan di pustaka instrumentasi HttpClient memberi pengguna access ke HttpRequestMessage dan HttpResponseMessage itu sendiri. Mereka dapat memilih apa pun darinya dan menyimpannya sebagai atribut.
Banyak perpustakaan instrumentasi menyediakan opsi memperkaya. Sebagai panduan, lihat file readme dari pustaka instrumentasi individual:
Gunakan prosesor kustom:
Tips
Tambahkan prosesor yang ditampilkan di sini sebelum menambahkan 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();
Tambahkan ActivityEnrichingProcessor.cs ke project Anda dengan kode berikut:
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");
}
}
Untuk menambahkan atribut rentang, gunakan salah satu dari dua cara berikut ini:
- Gunakan opsi yang disediakan oleh pustaka instrumentasi.
- Tambahkan prosesor rentang kustom.
Tips
Keuntungan menggunakan opsi yang disediakan oleh pustaka instrumentasi, ketika opsi tersebut ada, yaitu tersedianya seluruh konteks. Sebagai hasilnya, pengguna dapat memilih untuk menambahkan atau memfilter lebih banyak atribut. Misalnya, opsi pengayaan di pustaka instrumentasi HttpClient memberi pengguna akses ke httpRequestMessage itu sendiri. Mereka dapat memilih apa pun darinya dan menyimpannya sebagai atribut.
Banyak perpustakaan instrumentasi menyediakan opsi memperkaya. Sebagai panduan, lihat file readme dari pustaka instrumentasi individual:
Gunakan prosesor kustom:
Tips
Tambahkan prosesor yang ditampilkan di sini sebelum Pengekspor 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();
Tambahkan ActivityEnrichingProcessor.cs ke project Anda dengan kode berikut:
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");
}
}
Anda dapat menggunakan opentelemetry-api untuk menambahkan atribut ke rentang.
Menambahkan satu atau beberapa atribut rentang mengisi bidang di customDimensions, requests, dependencies, traces, atau exceptions tabel yang disebutkan.
Tambahkan opentelemetry-api-1.0.0.jar (atau yang lebih baru) ke aplikasi Anda:
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.0.0</version>
</dependency>
Tambahkan dimensi kustom dalam kode Anda:
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.common.AttributeKey;
AttributeKey attributeKey = AttributeKey.stringKey("mycustomdimension");
Span.current().setAttribute(attributeKey, "myvalue1");
Tambahkan dimensi kustom dalam kode Anda:
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.common.AttributeKey;
AttributeKey attributeKey = AttributeKey.stringKey("mycustomdimension");
Span.current().setAttribute(attributeKey, "myvalue1");
export class SpanAttributeEnrichmentSample {
static async run() {
// Dynamically import the Azure Monitor integration
const { useAzureMonitor } = await import("@azure/monitor-opentelemetry");
// Create a SpanEnrichingProcessor to add custom dimensions
class SpanEnrichingProcessor {
forceFlush() { return Promise.resolve(); }
shutdown() { return Promise.resolve(); }
onStart() {}
onEnd(span: any) {
(span as any).attributes = (span as any).attributes || {};
(span as any).attributes["CustomDimension1"] = "value1";
(span as any).attributes["CustomDimension2"] = "value2";
}
}
// Initialize Azure Monitor with the custom processor
const monitor = useAzureMonitor({
spanProcessors: [new SpanEnrichingProcessor()],
});
console.log("Span enrichment processor registered");
}
}
Gunakan prosesor kustom:
...
# 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],
)
...
Tambahkan SpanEnrichingProcessor ke project Anda dengan kode berikut:
# 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"
Mengatur IP pengguna
Anda dapat mengisi bidang client_IP untuk permintaan dengan mengatur atribut pada rentang. Application Insights menggunakan alamat IP untuk menghasilkan atribut lokasi pengguna lalu membuangnya secara default.
Gunakan contoh properti kustom, tetapi ganti baris kode berikut di 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>");
Gunakan contoh properti kustom, tetapi ganti baris kode berikut di 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 secara otomatis mengisi bidang ini.
Bidang ini diisi secara otomatis.
Gunakan contoh properti kustom, tetapi ganti baris kode berikut:
export class SetUserIpSample {
static async run() {
// Dynamically import Azure Monitor and tracing API
const { useAzureMonitor } = await import("@azure/monitor-opentelemetry");
const { trace } = await import("@opentelemetry/api");
// Initialize Azure Monitor
const monitor = useAzureMonitor();
// Framework-agnostic helper to set client IP on the active server span
const setIpForRequest = (clientIp: string) => {
const span = trace.getActiveSpan();
if (span) {
// Preferred attribute for client IP
span.setAttribute("client.address", clientIp);
// Optional: legacy/alternate attribute
span.setAttribute("http.client_ip", clientIp);
}
};
// Call setIpForRequest("<IP Address>") from within your web framework's request pipeline
console.log("Use setIpForRequest('<IP Address>') inside your request handler to stamp the active span.");
}
}
Gunakan contoh properti kustom, tetapi ganti baris kode berikut di SpanEnrichingProcessor.py:
# Set the `http.client_ip` attribute of the span to the specified IP address.
span._attributes["http.client_ip"] = "<IP Address>"
Mengatur ID pengguna atau ID pengguna terautentikasi
Anda dapat mengisi bidang user_Id atau user_AuthenticatedId untuk permintaan dengan menggunakan panduan berikut. ID pengguna adalah pengidentifikasi pengguna anonim. ID Pengguna Terautentikasi adalah pengidentifikasi pengguna yang diketahui.
Penting
Lihat undang-undang privasi yang berlaku sebelum Anda menetapkan ID Pengguna Terautentikasi.
Gunakan contoh properti kustom:
// Add the user ID to the activity as a tag, but only if the activity is not null.
activity?.SetTag("enduser.id", "<User Id>");
Gunakan contoh properti kustom:
// Add the user ID to the activity as a tag, but only if the activity is not null.
activity?.SetTag("enduser.id", "<User Id>");
Isi bidang user ID di tabel requests, dependencies, atau exceptions.
Tambahkan opentelemetry-api-1.0.0.jar (atau yang lebih baru) ke aplikasi Anda:
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.0.0</version>
</dependency>
Atur user_Id dalam kode Anda:
import io.opentelemetry.api.trace.Span;
Span.current().setAttribute("enduser.id", "myuser"); // (user_AuthenticatedId)
Span.current().setAttribute("enduser.pseudo.id", "myuser"); // (user_Id)
Isi bidang user ID di tabel requests, dependencies, atau exceptions.
Atur user_Id dalam kode Anda:
import io.opentelemetry.api.trace.Span;
Span.current().setAttribute("enduser.id", "myuser"); // (user_AuthenticatedId)
Span.current().setAttribute("enduser.pseudo.id", "myuser"); // (user_Id)
Gunakan contoh properti kustom, tetapi ganti baris kode berikut:
export class SetUserIdSample {
static async run() {
// Dynamically import Azure Monitor and tracing API
const { useAzureMonitor } = await import("@azure/monitor-opentelemetry");
const { trace } = await import("@opentelemetry/api");
// Initialize Azure Monitor
const monitor = useAzureMonitor();
// Framework-agnostic helper to set user identifiers on the active server span
const setUserForRequest = (authenticatedId?: string, anonymousId?: string) => {
const span = trace.getActiveSpan();
if (span) {
if (authenticatedId) span.setAttribute("enduser.id", authenticatedId); // user_AuthenticatedId
if (anonymousId) span.setAttribute("enduser.pseudo.id", anonymousId); // user_Id
}
};
// Call setUserForRequest("<authenticated-id>", "<anonymous-id>") inside your request handler
console.log("Use setUserForRequest('<auth-id>', '<anon-id>') inside your request handler to stamp the active span.");
}
}
Gunakan contoh properti kustom, tetapi ganti baris kode berikut:
# Set the `enduser.id` attribute of the span to the specified user ID.
span._attributes["enduser.id"] = "<User ID>"
Menambahkan atribut log
OpenTelemetry menggunakan .NET ILogger.
Melampirkan dimensi kustom ke log bisa dilakukan menggunakan templat pesan.
OpenTelemetry menggunakan .NET ILogger.
Melampirkan dimensi kustom ke log bisa dilakukan menggunakan templat pesan.
Logback, Log4j, dan java.util.logging diinstrumentasikan secara otomatis. Melampirkan dimensi kustom ke log Anda dapat dicapai dengan cara berikut:
Untuk aplikasi Spring Boot native, Logback sudah siap digunakan secara otomatis.
export class BunyanLogAttributesSample {
static async run() {
// Dynamically import Azure Monitor and Bunyan
const { useAzureMonitor } = await import("@azure/monitor-opentelemetry");
const bunyanMod = await import("bunyan");
const bunyan = (bunyanMod as any).default ?? bunyanMod;
// Enable Azure Monitor integration and bunyan instrumentation
const monitor = useAzureMonitor({
instrumentationOptions: { bunyan: { enabled: true } },
});
// Emit a log with custom attributes
const log = (bunyan as any).createLogger({ name: "testApp" });
log.info({ key1: "value1", feature: "demo" }, "Warning log with properties");
console.log("Bunyan log with attributes emitted");
}
}
Pustaka Python loggingautoinstrumented. Anda dapat melampirkan dimensi kustom ke log Anda dengan meneruskan kamus ke extra argumen log Anda:
...
# Create a warning log message with the properties "key1" and "value1".
logger.warning("WARNING: Warning log with properties", extra={"key1": "value1"})
...
Mengesampingkan status kesalahan permintaan untuk respons HTTP 4xx
Anda dapat mencegah Application Insights menghitung respons 4xx sebagai kesalahan.
Kode berikut menunjukkan prosesor aktivitas kustom yang menandai respons HTTP 4xx sebagai berhasil.
Prosesor:
public class Http4xxSuccessProcessor : BaseProcessor<Activity>
{
public override void OnEnd(Activity activity)
{
if (activity.Kind == ActivityKind.Server)
{
var statusCodeTag = activity.GetTagItem("http.response.status_code");
if (statusCodeTag is int statusCode && statusCode >= 400 && statusCode < 500)
{
// Set status to Ok to bypass the Azure Monitor exporter's default logic
// which treats any HTTP 4xx as failure when status is Unset.
// The response code tag (e.g., 400) remains unchanged — only the
// success field in Application Insights is affected.
activity.SetStatus(ActivityStatusCode.Ok);
}
}
base.OnEnd(activity);
}
}
Pendaftaran:
builder.Services.AddOpenTelemetry()
.UseAzureMonitor(options =>
{
options.ConnectionString = "<your-connection-string>";
})
.WithTracing(tracing =>
{
// Add custom processor to mark 4xx responses as successful
tracing.AddProcessor<Http4xxSuccessProcessor>();
});
Kode berikut adalah untuk prosesor aktivitas kustom yang menandai respons HTTP 4xx sebagai berhasil.
Prosesor:
public class Http4xxSuccessProcessor : BaseProcessor<Activity>
{
public override void OnEnd(Activity activity)
{
if (activity.Kind == ActivityKind.Server)
{
var statusCodeTag = activity.GetTagItem("http.response.status_code");
if (statusCodeTag is int statusCode && statusCode >= 400 && statusCode < 500)
{
// Set status to Ok to bypass the Azure Monitor exporter's default logic
// which treats any HTTP 4xx as failure when status is Unset.
// The response code tag (e.g., 400) remains unchanged — only the
// success field in Application Insights is affected.
activity.SetStatus(ActivityStatusCode.Ok);
}
}
base.OnEnd(activity);
}
}
Pendaftaran:
using System.Diagnostics;
using OpenTelemetry;
using OpenTelemetry.Trace;
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
// Add the processor before the exporter
.AddProcessor(new Http4xxSuccessProcessor())
.AddAzureMonitorTraceExporter(options =>
{
options.ConnectionString = "<your-connection-string>";
})
.Build();
Catatan
Fitur ini tersedia dimulai dengan agen Java versi 3.3.0.
Secara default, agen menangkap permintaan server HTTP yang mengakibatkan kode respons 4xx sebagai kesalahan. Anda dapat mengubah perilaku ini untuk menganggapnya berhasil.
{
"preview": {
"captureHttpServer4xxAsError": false
}
}
Prosesor:
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.context.Context;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.trace.ReadWriteSpan;
import io.opentelemetry.sdk.trace.ReadableSpan;
import io.opentelemetry.sdk.trace.internal.ExtendedSpanProcessor;
import java.util.Set;
public final class Http4xxAsSuccessProcessor implements ExtendedSpanProcessor {
private static final AttributeKey<Long> HTTP_RESPONSE_STATUS_CODE =
AttributeKey.longKey("http.response.status_code");
// Deprecated semconv attribute that some libraries may still emit
private static final AttributeKey<Long> HTTP_STATUS_CODE =
AttributeKey.longKey("http.status_code");
private static final AttributeKey<Boolean> MODIFIED_FLAG =
AttributeKey.booleanKey("ai.modified.http4xx.success");
private final Set<Long> keepAsFailure = Set.of(429L);
@Override
public void onStart(Context parentContext, ReadWriteSpan span) {
// No-op
}
@Override
public boolean isStartRequired() {
return false;
}
@Override
public void onEnding(ReadWriteSpan span) {
if (span.getKind() != SpanKind.SERVER) {
return;
}
Long statusCode = span.getAttribute(HTTP_RESPONSE_STATUS_CODE);
if (statusCode == null) {
statusCode = span.getAttribute(HTTP_STATUS_CODE);
}
if (statusCode != null
&& statusCode >= 400
&& statusCode < 500
&& !keepAsFailure.contains(statusCode)) {
// Keep the HTTP status code attribute unchanged, but mark the span as OK
// so downstream backends such as Application Insights don't count it as a failure.
span.setStatus(StatusCode.OK);
span.setAttribute(MODIFIED_FLAG, true);
}
}
@Override
public boolean isOnEndingRequired() {
return true;
}
@Override
public void onEnd(ReadableSpan span) {
// No-op
}
@Override
public boolean isEndRequired() {
return false;
}
@Override
public CompletableResultCode shutdown() {
return CompletableResultCode.ofSuccess();
}
@Override
public CompletableResultCode forceFlush() {
return CompletableResultCode.ofSuccess();
}
}
Pendaftaran (Spring Boot):
import com.azure.monitor.opentelemetry.autoconfigure.AzureMonitorAutoConfigure;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder;
public class TelemetryConfiguration {
public static OpenTelemetry configureOpenTelemetry() {
AutoConfiguredOpenTelemetrySdkBuilder sdkBuilder = AutoConfiguredOpenTelemetrySdk.builder();
AzureMonitorAutoConfigure.customize(sdkBuilder, "<your-connection-string>");
sdkBuilder.addTracerProviderCustomizer(
(tracerProviderBuilder, configProperties) ->
tracerProviderBuilder.addSpanProcessor(new Http4xxAsSuccessProcessor())
);
return sdkBuilder.build().getOpenTelemetrySdk();
}
}
Pendaftaran (Quarkus):
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class Http4xxAsSuccessProcessor extends Http4xxAsSuccessProcessorBase {
}
import { SpanKind, SpanStatusCode } from "@opentelemetry/api";
import { SpanProcessor, ReadableSpan } from "@opentelemetry/sdk-trace-base";
import { ATTR_HTTP_RESPONSE_STATUS_CODE } from "@opentelemetry/semantic-conventions";
// Deprecated semconv attribute; not exported from the stable entry point.
const ATTR_HTTP_STATUS_CODE = "http.status_code";
export class Http4xxAsSuccessProcessor implements SpanProcessor {
private keepAsFailure = new Set<number>(/* [429] */);
onStart(): void {}
onEnd(span: ReadableSpan): void {
if (span.kind !== SpanKind.SERVER) return;
const attrs = span.attributes;
const sc =
(attrs[ATTR_HTTP_RESPONSE_STATUS_CODE] as number | undefined) ??
(attrs[ATTR_HTTP_STATUS_CODE] as number | undefined);
if (
typeof sc === "number" &&
sc >= 400 &&
sc < 500 &&
!this.keepAsFailure.has(sc)
) {
// By onEnd the span is ended, so setStatus()/setAttribute() are no-ops.
// Directly mutate the backing fields so the exporter sees the change.
(span as any).status = { code: SpanStatusCode.OK };
(span as any).attributes = {
...attrs,
"ai.modified.http4xx.success": true,
};
console.log(`[Processor] Rewrote ${sc} span to OK`);
}
}
shutdown(): Promise<void> {
return Promise.resolve();
}
forceFlush(): Promise<void> {
return Promise.resolve();
}
}
Prosesor:
from __future__ import annotations
from typing import Iterable, Optional
from opentelemetry.trace import SpanKind, Status, StatusCode
from opentelemetry.sdk.trace import ReadableSpan, SpanProcessor
# Current HTTP semconv attribute
ATTR_HTTP_RESPONSE_STATUS_CODE = "http.response.status_code"
# Older / deprecated attribute that some instrumentations may still emit
ATTR_HTTP_STATUS_CODE = "http.status_code"
class Http4xxAsSuccessProcessor(SpanProcessor):
def __init__(self, keep_as_failure: Optional[Iterable[int]] = None) -> None:
# Example: keep 429 as a failure if you want throttling to remain visible
# self._keep_as_failure = set(keep_as_failure or {429})
def on_start(self, span, parent_context=None) -> None:
# No-op
return
def on_end(self, span: ReadableSpan) -> None:
if span.kind is not SpanKind.SERVER:
return
attrs = span.attributes
status_code = attrs.get(
ATTR_HTTP_RESPONSE_STATUS_CODE,
attrs.get(ATTR_HTTP_STATUS_CODE),
)
if (
isinstance(status_code, int)
and 400 <= status_code < 500
and status_code not in self._keep_as_failure
):
# ReadableSpan.status is read-only, so in current released SDKs
# we mutate the private backing field that the exporter reads.
span._status = Status(StatusCode.OK) # pylint: disable=protected-access
# Optional diagnostic marker so you can tell the processor rewrote it.
# ReadableSpan.attributes returns a read-only MappingProxyType, so we
# update the private backing store instead.
if getattr(span, "_attributes", None) is None:
span._attributes = {} # pylint: disable=protected-access
try:
span._attributes["ai.modified.http4xx.success"] = True # pylint: disable=protected-access
except TypeError:
# Fallback if the backing store is not directly writable
span._attributes = dict(span.attributes) # pylint: disable=protected-access
span._attributes["ai.modified.http4xx.success"] = True # pylint: disable=protected-access
def shutdown(self) -> None:
return
def force_flush(self, timeout_millis: int = 30000) -> bool:
return True
Pendaftaran:
from azure.monitor.opentelemetrgit import configure_azure_monitor
configure_azure_monitor(
connection_string="<your-connection-string>",
span_processors=[Http4xxAsSuccessProcessor()],
)
Dapatkan ID jejak atau ID rentang
Dapatkan Trace ID dan Span ID untuk rentang yang aktif saat ini dengan menggunakan langkah-langkah berikut.
Catatan
Kelas Activity dan ActivitySource dari namespace System.Diagnostics, masing-masing menggambarkan konsep OpenTelemetry dari Span dan Tracer. Ini karena bagian dari API pelacakan OpenTelemetry dimasukkan langsung ke dalam runtime .NET. Untuk mempelajari lebih lanjut, lihat Introduction ke OpenTelemetry .NET Tracing 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();
Catatan
Kelas Activity dan ActivitySource dari namespace System.Diagnostics, masing-masing menggambarkan konsep OpenTelemetry dari Span dan Tracer. Ini karena bagian dari API pelacakan OpenTelemetry dimasukkan langsung ke dalam runtime .NET. Untuk mempelajari lebih lanjut, lihat Introduction ke OpenTelemetry .NET Tracing 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();
Anda dapat menggunakan opentelemetry-api untuk mendapatkan ID jejak atau ID rentang.
Tambahkan opentelemetry-api-1.0.0.jar (atau yang lebih baru) ke aplikasi Anda:
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.0.0</version>
</dependency>
Dapatkan ID pelacakan permintaan dan ID rentang dalam kode Anda:
import io.opentelemetry.api.trace.Span;
Span span = Span.current();
String traceId = span.getSpanContext().getTraceId();
String spanId = span.getSpanContext().getSpanId();
Dapatkan ID pelacakan permintaan dan ID rentang dalam kode Anda:
import io.opentelemetry.api.trace.Span;
Span span = Span.current();
String traceId = span.getSpanContext().getTraceId();
String spanId = span.getSpanContext().getSpanId();
Dapatkan ID pelacakan permintaan dan ID rentang dalam kode Anda:
export class GetTraceAndSpanIdSample {
static async run() {
// Dynamically import tracing API
const { trace } = await import("@opentelemetry/api");
// Read the span/trace id from the active span (if any)
const activeSpan = trace.getActiveSpan();
const spanId = activeSpan?.spanContext().spanId;
const traceId = activeSpan?.spanContext().traceId;
console.log("SpanId:", spanId, "TraceId:", traceId);
}
}
Dapatkan ID pelacakan permintaan dan ID rentang dalam kode Anda:
# 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
Pemecahan masalah, umpan balik, dan dukungan
Tips
Bagian berikut tersedia di semua artikel Distro OpenTelemetry.
Troubleshooting
Umpan Balik OpenTelemetry
Untuk memberikan umpan balik:
Support
Pilih tab untuk bahasa pilihan Anda untuk menemukan opsi dukungan.
- Untuk masalah Azure support, buka tiket Azure support.
- Untuk masalah OpenTelemetry, hubungi komunitas OpenTelemetry .NET secara langsung.
- Untuk daftar masalah terbuka yang terkait dengan pengekspor Azure Monitor, lihat Halaman Masalah GitHub.
- Untuk masalah Azure support, buka tiket Azure support.
- Untuk masalah OpenTelemetry, hubungi komunitas OpenTelemetry .NET secara langsung.
- Untuk daftar masalah terbuka yang terkait dengan pengekspor Azure Monitor, lihat Halaman Masalah GitHub.
- Untuk masalah Azure support, buka tiket Azure support.
- Untuk masalah OpenTelemetry, hubungi komunitas OpenTelemetry secara langsung.
- Untuk daftar masalah terbuka dengan aplikasi asli Spring Boot, lihat Halaman Masalah GitHub.
- Untuk daftar masalah terbuka dengan aplikasi asli Quarkus, lihat Halaman Masalah GitHub.
Catatan
Komunitas Quarkus mendukung dan memelihara ekstensi Quarkus. Untuk bantuan, gunakan saluran dukungan komunitas Quarkus. Microsoft tidak memberikan dukungan teknis untuk integrasi ini.
- Untuk masalah Azure support, buka tiket Azure support.
- Untuk masalah OpenTelemetry, hubungi komunitas Python OpenTelemetry secara langsung.
- Untuk daftar masalah terbuka yang terkait dengan Azure Monitor Distro, lihat Halaman Masalah GitHub.
Langkah berikutnya