Bu kılavuz, Azure İzleyici Application Insights kapsamında OpenTelemetry (OTel) araçlarını entegre etme ve özelleştirmeye yönelik talimatlar sağlar.
OpenTelemetry kavramları hakkında daha fazla bilgi edinmek için bkz. OpenTelemetry'ye genel bakış.
Not
Azure İşlev Uygulamaları için bkz. Azure İşlevleri ile OpenTelemetry kullanma.
Azure İzleyici OpenTelemetry dağıtımına dahil edilen tüm izleme kitaplıklarına genel bakış için Azure İzleyici OpenTelemetry için Otomatik veri toplama ve kaynak algılayıcıları başlığına bakın.
OpenTelemetry topluluğundan izleme kitaplıkları eklediğinizde otomatik olarak daha fazla veri toplayabilirsiniz.
Dikkat
Topluluk izleme kitaplıklarının kalitesini desteklemiyoruz veya garanti vermiyoruz. Dağıtımımız için bir öneride bulunmak için, geri bildirim topluluğumuzda gönderi yapın veya oy verin. Deneysel OpenTelemetry belirtimlerini temel alan bazı durumların, gelecekte uyumsuzluklara yol açabilecek değişiklikler içerebileceğini unutmayın.
Topluluk kitaplığı eklemek için, kitaplığın NuGet paketini ekledikten sonra ConfigureOpenTelemetryMeterProvider veya ConfigureOpenTelemetryTracerProvider yöntemlerini kullanın.
Aşağıdaki örnekte, ek ölçümler toplamak için Çalışma Zamanı İzlemesi'nin nasıl ekleneceği gösterilmektedir:
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();
Aşağıdaki örnekte, ek ölçümler toplamak için Çalışma Zamanı İzlemesi'nin nasıl ekleneceği gösterilmektedir:
// 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 aracısını topluluk enstrümantasyon kitaplıklarıyla genişletemezsiniz. Diğer araç kütüphanesinin eklenmesini istemek için GitHub sayfasında bir sorun açın.
GraalVM Java yerel uygulamalarla topluluk araçları kitaplıklarını kullanamazsınız.
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");
}
}
Topluluk enstrümantasyon kütüphanesi eklemek için doğrudan enstrümantasyonları kullanarak enstrümantasyon yapın. Topluluk enstrümantasyon kitaplıklarının listesini GitHub'da bulabilirsiniz.
Not
Desteklenen izleme kitaplığınıinstrument() ve configure_azure_monitor() dağıtımını kullanarak el ile izlemeyin. Bu yaklaşım desteklenmez ve telemetriniz için istenmeyen davranışlara neden olabilir.
# 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())
Özel telemetri toplama
Bu bölümde, uygulamanızdan özel telemetri verilerinin nasıl toplayacağınız açıklanmaktadır.
Dilinize ve sinyal türünüze bağlı olarak, özel telemetri toplamanın farklı yolları vardır, örneğin:
- OpenTelemetry API'si
- Dile özgü günlük/ölçüm kitaplıkları
- Application Insights Klasik API'si
Aşağıdaki tablo, şu anda desteklenen özel telemetri türlerini temsil eder:
| Dil |
Özel Olaylar |
Özel Ölçümler |
Bağımlılıklar |
Özel durumlar |
Sayfa Görünümleri |
İstekler |
İzler |
|
ASP.NET Core |
|
|
|
|
|
|
|
| OpenTelemetry API'si |
|
Evet |
Evet |
Evet |
|
Evet |
|
ILogger API (Uygulama Programlama Arayüzü) |
Evet |
|
|
|
|
|
Evet |
| AI Klasik API |
Evet |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Java |
|
|
|
|
|
|
|
| OpenTelemetry API'si |
Evet |
Evet |
Evet |
Evet |
|
Evet |
|
Logback, Log4j, JUL |
|
|
|
Evet |
|
|
Evet |
| Mikrometre Özellikleri |
|
Evet |
|
|
|
|
|
| AI Klasik API |
Evet |
Evet |
Evet |
Evet |
Evet |
Evet |
Evet |
|
|
|
|
|
|
|
|
|
Node.js |
|
|
|
|
|
|
|
| OpenTelemetry API'si |
Evet |
Evet |
Evet |
Evet |
|
Evet |
|
|
|
|
|
|
|
|
|
|
Python |
|
|
|
|
|
|
|
| OpenTelemetry API'si |
|
Evet |
Evet |
Evet |
|
Evet |
|
| Python Günlüğü Modülü |
|
|
|
|
|
|
Evet |
| Etkinlik Eklentisi |
Evet |
|
|
|
|
|
Evet |
Not
Application Insights Java 3.x ve Application Insights Node.js 3.x, Application Insights Classic API telemetri verilerini toplar. Bu davranış, OpenTelemetry API'sinde tüm özel telemetri türleri bulunana kadar yükseltmeleri basitleştirir ve geçici olarak özel telemetriyi destekler.
Özel ölçümler ekleme
Bu bağlamda, özel metrikler terimi, OpenTelemetry İzleme Kitaplıklarının otomatik olarak topladıklarının ötesinde ek metrikler toplamak için kodunuzu manuel olarak izlemeye atıfta bulunur. Ölçümleri kullanma hakkında daha fazla bilgi edinmek için bkz. Application Insights'ta Ölçümler.
OpenTelemetry API'si, çeşitli ölçüm senaryolarını kapsayacak altı ölçüm "aracı" sunar ve Ölçüm Gezgini'nde ölçümleri görselleştirirken doğru "Toplama Türü"nü seçmeniz gerekir. Bu gereksinim, ölçümleri göndermek için OpenTelemetry Ölçüm API'sini kullanırken ve bir izleme kitaplığı kullanırken geçerlidir.
Aşağıdaki tabloda OpenTelemetry Ölçüm Araçlarının her biri için önerilen toplama türleri gösterilmektedir.
| OpenTelemetry Enstrüman |
Azure İzleyici Toplama Türü |
| Sayaç |
Toplam |
| Asenkron Sayaç |
Toplam |
| Histogram Grafiği |
Minimum, Maksimum, Ortalama, Toplam ve Sayı |
| Zaman Uyumsuz Ölçer |
Ortalama |
| UpDownCounter |
Toplam |
| Zaman Uyumsuz UpDownCounter |
Toplam |
Dikkat
Diğer toplama türleri çoğu durumda anlamlı değildir.
OpenTelemetry Specification araçları açıklar ve her birini ne zaman kullanabileceğinize ilişkin örnekler sağlar.
İpucu
Histogram, Application Insights GetMetric Klasik API'sinin en çok yönlü ve en yakın eşdeğeridir. Azure İzleyici şu anda histogram aracını, desteklenen beş toplama türüne göre düzleştirir ve yüzde değerleri için destek sağlanması devam etmektedir. Daha az çok yönlü olsa da, diğer OpenTelemetry araçları uygulamanızın performansı üzerinde daha az etkiye sahiptir.
Histogram örneği
Uygulama başlatılırken, bir Ölçüme adıyla abone olunmalıdır.
// 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();
Aynı adla Meter başlatılmalıdır.
// 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);
}
}
Ekleme OpenTelemetry:
Histogram oluşturma:
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);
Not
Quarkus topluluğu, Quarkus uzantılarını destekler ve korur. Yardım için Quarkus topluluk destek kanallarını kullanın. Microsoft bu tümleştirme için teknik destek sağlamaz.
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()
Karşıt örnek
Uygulama başlatılırken, bir Ölçüme adıyla abone olunmalıdır.
// 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();
Aynı adla Meter başlatılmalıdır.
// 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"));
}
}
Ekleme OpenTelemetry:
Sayacı oluşturun:
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"));
Not
Quarkus topluluğu, Quarkus uzantılarını destekler ve korur. Yardım için Quarkus topluluk destek kanallarını kullanın. Microsoft bu tümleştirme için teknik destek sağlamaz.
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()
Ölçer örneği
Uygulama başlatılırken, bir Ölçüme adıyla abone olunmalıdır.
// 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();
Aynı adla Meter başlatılmalıdır.
// 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"));
});
}
}
Ekleme OpenTelemetry:
Ölçer oluşturma:
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"));
});
Not
Quarkus topluluğu, Quarkus uzantılarını destekler ve korur. Yardım için Quarkus topluluk destek kanallarını kullanın. Microsoft bu tümleştirme için teknik destek sağlamaz.
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()
Özel durumlar ekleme
Seçilen izleme kitaplıkları, özel durumları Application Insights'a otomatik olarak bildirir.
Ancak, enstrümantasyon kütüphanelerinin raporladıklarının ötesinde istisnaları el ile raporlamak isteyebilirsiniz.
Örneğin, kodunuz tarafından yakalanan özel durumlar normalde bildirilmez. Hataların bölümü ve uçtan uca işlem görünümleri de dahil olmak üzere ilgili deneyimlerde dikkat çekmek için bunları raporlamak isteyebilirsiniz.
Bir Etkinlik Kullanarak Bir İstisna Kaydetmek İçin:
// 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);
}
}
Bir Özel Durumu, kullanarak günlüğe kaydetmek için:
// 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" });
}
Bir Etkinlik Kullanarak Bir İstisna Kaydetmek İçin:
// 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);
}
}
Bir Özel Durumu, kullanarak günlüğe kaydetmek için:
// 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" });
}
Bir yayılma alanının durumunu güncelleştirmek ve özel durumları kaydetmek için kullanabilirsiniz opentelemetry-api .
Uygulamanıza opentelemetry-api-1.0.0.jar (veya daha sonraki bir sürümünü) ekleyin.
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.0.0</version>
</dependency>
Durumunu olarak error ayarlayın ve kodunuzda bir özel durum kaydedin:
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
Span span = Span.current();
span.setStatus(StatusCode.ERROR, "errorMessage");
span.recordException(e);
Durumunu olarak error ayarlayın ve kodunuzda bir özel durum kaydedin:
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'sı, el ile kaydedilen span tabanlı özel durumları, yalnızca en üst düzey bir span veya bir uzak ya da iç span'ın alt öğesi üzerine kaydedildiklerinde Application Insights'a özel durumlar olarak dışa aktarır.
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'sı, oluşan özel durumlar otomatik olarak yakalanıp kaydedilebilecek şekilde uygulanır. Bu davranış örneği için aşağıdaki kod örneğine bakın:
# 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")
Özel durumları el ile kaydetmek isterseniz, bağlam yöneticisinde bu seçeneği devre dışı bırakabilir ve aşağıdaki örnekte gösterildiği gibi doğrudan kullanabilirsiniz 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)
...
Özel aralıklar ekleme
İki senaryoda özel bir aralık eklemek isteyebilirsiniz. İlk olarak, izleme kitaplığı tarafından henüz toplanmamış bir bağımlılık isteği olduğunda. İkincisi, bir uygulama işlemini uçtan uca işlem görünümünde bir yayılma alanı olarak modellemek istediğinizde.
Not
Activity ve ActivitySource sınıfları, sırasıyla, System.Diagnostics ad alanından Span ve Tracer OpenTelemetry kavramlarını temsil eder.
ActivitySource, TracerProvider yerine doğrudan yapıcı fonksiyonunu kullanarak oluşturursunuz. Her ActivitySource sınıfı, TracerProvider kullanılarak açıkça AddSource() bağlanmalıdır. Bunun nedeni OpenTelemetry izleme API'sinin bölümlerinin doğrudan .NET çalışma zamanına dahil edilmiş olmasıdır. Daha fazla bilgi edinmek için bkz. OpenTelemetry .NET İzleme API'sine Giriş.
// 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 varsayılan olarak ActivityKind.Internal'dir, ancak başka herhangi bir ActivityKind sağlayabilirsiniz.
ActivityKind.Client, ActivityKind.Producerve ActivityKind.Internal Application Insights dependenciesile eşlenir.
ActivityKind.Server ve ActivityKind.Consumer Application Insights requests ile eşlenir.
Not
Activity ve ActivitySource sınıfları, sırasıyla, System.Diagnostics ad alanından Span ve Tracer OpenTelemetry kavramlarını temsil eder.
ActivitySource, TracerProvider yerine doğrudan yapıcı fonksiyonunu kullanarak oluşturursunuz. Her ActivitySource sınıfı, TracerProvider kullanılarak açıkça AddSource() bağlanmalıdır. Bunun nedeni OpenTelemetry izleme API'sinin bölümlerinin doğrudan .NET çalışma zamanına dahil edilmiş olmasıdır. Daha fazla bilgi edinmek için bkz: OpenTelemetry .NET İzleme API'ye Giriş.
// 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 varsayılan olarak ActivityKind.Internal'dir, ancak başka herhangi bir ActivityKind sağlayabilirsiniz.
ActivityKind.Client, ActivityKind.Producerve ActivityKind.Internal Application Insights dependenciesile eşlenir.
ActivityKind.Server ve ActivityKind.Consumer Application Insights requests ile eşlenir.
OpenTelemetry ek açıklamasını kullanın
Kendi span'lerinizi eklemenin en basit yolu, OpenTelemetry'nin @WithSpan ek açıklamasını kullanmaktır.
Spans, Application Insights'taki requests ve dependencies tablolarını doldurur.
Uygulamanıza opentelemetry-instrumentation-annotations-1.32.0.jar (veya daha sonraki bir sürümünü) ekleyin.
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-instrumentation-annotations</artifactId>
<version>1.32.0</version>
</dependency>
@WithSpan Yönteminiz her yürütülürken bir yayılma alanı yaymak için ek açıklamayı kullanın:
import io.opentelemetry.instrumentation.annotations.WithSpan;
@WithSpan(value = "your span name")
public void yourMethod() {
}
Varsayılan olarak, span bağımlılık türüne dependenciesInProcsahip tabloda biter.
Otomatik araçlar tarafından yakalanmayan bir arka plan işini temsil eden yöntemler için, Application Insights kind = SpanKind.SERVER tablosunda göründüklerinden emin olmak için @WithSpan özniteliğini requests ek açıklamasına uygulamanızı öneririz.
OpenTelemetry API'sini kullanma
Yukarıdaki OpenTelemetry @WithSpan ek açıklaması gereksinimlerinizi karşılamıyorsa, OpenTelemetry API'sini kullanarak kendi span'lerinizi ekleyebilirsiniz.
Uygulamanıza opentelemetry-api-1.0.0.jar (veya daha sonraki bir sürümünü) ekleyin.
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.0.0</version>
</dependency>
GlobalOpenTelemetry sınıfını kullanarak bir Tracer oluşturun.
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Tracer;
static final Tracer tracer = GlobalOpenTelemetry.getTracer("com.example");
Zaman aralığı oluşturun, geçerli yapın ve ardından sonlandırın.
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();
}
Ekleme OpenTelemetry:
TracerOluştur
import io.opentelemetry.api.trace.Tracer;
static final Tracer tracer = openTelemetry.getTracer("com.example");
Zaman aralığı oluşturun, geçerli yapın ve ardından sonlandırın.
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();
}
Not
Quarkus topluluğu, Quarkus uzantılarını destekler ve korur. Yardım için Quarkus topluluk destek kanallarını kullanın. Microsoft bu tümleştirme için teknik destek sağlamaz.
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");
}
}
OpenTelemetry API'sini kullanarak Application Insights'taki ve requests tablolarında dependencies görünen kendi aralıklarınızı ekleyebilirsiniz.
Kod örneği, tracer.start_as_current_span() yönteminin bağlamı içinde başlatmak, span'ı geçerli hale getirmek ve sonlandırmak için nasıl kullanılacağını gösterir.
...
# 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)
...
Varsayılan olarak, dependencies tablosunda, InProc bağımlılık türü ile span bulunur.
Yönteminiz, otomatik enstrümantasyon tarafından henüz yakalanmamış bir arka plan işini temsil ediyorsa, kind = SpanKind.SERVER özniteliğini Application Insights requests tablosunda görünecek şekilde ayarlamanızı öneririz.
...
# 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.
...
Özel olaylar gönderme
Application Insights özel olayları customEvents tabloda depolar. Bunları analiz etmenin , filtrelemenin ve görselleştirmenin bir yolu , Application Insights kullanım deneyimlerini kullanmaktır.
İstemci tarafı etkileşim olaylarının koleksiyonunu otomatikleştirmek istiyorsanız JavaScript SDK'sında eklentiyi kullanabilirsiniz.
Özel olaylar Azure.Monitor.OpenTelemetry.AspNetCore kullanır.
Bir CustomEvent göndermek için ILogger kullanarak, ileti şablonunda "microsoft.custom_event.name" özelliğini ayarlayın.
// 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");
kullanılarak özel etkinlikler oluşturulur.
Bir CustomEvent göndermek için ILogger kullanarak, ileti şablonunda "microsoft.custom_event.name" özelliğini ayarlayın.
// 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");
Java aracısıyla customEvent göndermek için, OpenTelemetry günlük kaydında "microsoft.custom_event.name" özniteliğini ayarlayın.
Application Insights Java aracısının kullanımda olmasına veya otomatik yapılandırma SDK'sına bağlı olarak, OpenTelemetry günlükçüsünün getirilma şekli biraz farklıdır. Bu ayrıntı aşağıdaki örneklerde daha ayrıntılı olarak açıklanmıştır.
Application Insights Java aracısı için:
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();
Otomatik yapılandırma SDK'sı için:
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();
Özel olayları güvenilir bir şekilde yaymak için doğrudan OpenTelemetry API'sini kullanın. Bazı günlük çerçeveleri özel olaylar özniteliğini eklemeyi veya ayrıştırma işlemini desteklemez.
yerel Java customEvent özniteliğini kullanarak "microsoft.custom_event.name" göndermek mümkün değildir.
customEvent kullanarak logger.emit göndermek için, günlüğün "microsoft.custom_event.name" nesnesinde attributes özniteliğini ayarlayın. Gerektiğinde diğer öznitelikler de eklenebilir.
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");
}
}
Python'da bir customEvent göndermek için, extra parametresindeki "microsoft.custom_event.name" özniteliğiyle logging kütüphanesini kullanın.
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"
}
)
Telemetriyi değiştirme
Bu bölümde telemetrinin nasıl değiştirileceği açıklanmaktadır.
Span öznitelikleri ekleme
Bu öznitelikler telemetrinize özel özellik eklemeyi içerebilir. Application Insights şemasında İstemci IP'leri gibi isteğe bağlı alanlar ayarlamak için öznitelikleri de kullanabilirsiniz.
Span'a özel özellik ekleme
Span'lara eklediğiniz tüm öznitelikler özel özellikler olarak dışarı aktarılır. İstekler, bağımlılıklar, izlemeler veya özel durumlar tablosunda customDimensions alanını doldurur.
Span öznitelikleri eklemek için aşağıdaki iki yoldan birini kullanın:
-
Araç kütüphaneleri tarafından sağlanan seçenekleri kullanın.
- Özel bir span işlemcisi ekleyin.
İpucu
İzleme araçları kitaplıkları tarafından sağlanan seçenekleri kullanmanın avantajı, bunlar mevcut olduğunda tüm bağlamın erişilebilir olmasıdır. Sonuç olarak, kullanıcılar daha fazla öznitelik eklemeyi veya filtrelemeyi seçebilir. Örneğin, HttpClient izleme kitaplığındaki zenginleştirme seçeneği, kullanıcılara HttpRequestMessage ve HttpResponseMessage üzerinde erişim imkanı tanır. Herhangi bir öğeyi seçip bir öznitelik olarak depolayabilirler.
Birçok araçsal kütüphane zenginleştirme seçeneği sunar. Yönergeler için, her bir araç oluşturma kitaplığının readme dosyalarına bakın:
Özel işlemci kullanın:
İpucu
Azure İzleyici'ü eklemeden önce burada gösterilen işlemciyi ekleyin.
// 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();
Projenize aşağıdaki kodla ActivityEnrichingProcessor.cs ekleyin:
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");
}
}
Span öznitelikleri eklemek için aşağıdaki iki yoldan birini kullanın:
- Enstrümantasyon kitaplıkları tarafından sağlanan seçenekleri kullanın.
- Özel bir span işlemcisi ekleyin.
İpucu
İzleme araçları kitaplıkları tarafından sağlanan seçenekleri kullanmanın avantajı, bunlar mevcut olduğunda tüm bağlamın erişilebilir olmasıdır. Sonuç olarak, kullanıcılar daha fazla öznitelik eklemeyi veya filtrelemeyi seçebilir. Örneğin, HttpClient izleme kitaplığındaki zenginleştirme seçeneği, kullanıcılara httpRequestMessage'ın kendisine erişim sağlar. Herhangi bir öğeyi seçip bir öznitelik olarak depolayabilirler.
Birçok araçsal kütüphane zenginleştirme seçeneği sunar. Yönergeler için, her bir araç oluşturma kitaplığının readme dosyalarına bakın:
Özel işlemci kullanın:
İpucu
Azure İzleyici Exporter'dan önce burada gösterilen işlemciyi ekleyin.
// 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();
Projenize aşağıdaki kodla ActivityEnrichingProcessor.cs ekleyin:
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");
}
}
Spans'a öznitelik eklemek için kullanabilirsiniz opentelemetry-api .
Bir veya daha fazla span özniteliği eklemek customDimensions, requests, dependencies, traces veya exceptions tablolarındaki alanı doldurur.
Uygulamanıza opentelemetry-api-1.0.0.jar (veya daha sonraki bir sürümünü) ekleyin.
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.0.0</version>
</dependency>
Kodunuza özel boyutlar ekleyin:
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.common.AttributeKey;
AttributeKey attributeKey = AttributeKey.stringKey("mycustomdimension");
Span.current().setAttribute(attributeKey, "myvalue1");
Kodunuza özel boyutlar ekleyin:
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");
}
}
Özel işlemci kullanın:
...
# 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],
)
...
Projenize aşağıdaki kodla SpanEnrichingProcessor ekleyin:
# 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"
Kullanıcı IP'sini ayarlama
span üzerinde bir öznitelik ayarlayarak istekler için client_IP alanını doldurabilirsiniz. Application Insights, kullanıcı konumu öznitelikleri oluşturmak için IP adresini kullanır ve varsayılan olarak siler.
Özel özellik örneğini kullanın, ancak içindeki ActivityEnrichingProcessor.csaşağıdaki kod satırlarını değiştirin:
// 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>");
Özel özellik örneğini kullanın, ancak içindeki ActivityEnrichingProcessor.csaşağıdaki kod satırlarını değiştirin:
// 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 bu alanı otomatik olarak doldurur.
Bu alan otomatik olarak doldurulur.
Özel özellik örneğini kullanın, ancak aşağıdaki kod satırlarını değiştirin:
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.");
}
}
Özel özellik örneğini kullanın, ancak içindeki SpanEnrichingProcessor.pyaşağıdaki kod satırlarını değiştirin:
# Set the `http.client_ip` attribute of the span to the specified IP address.
span._attributes["http.client_ip"] = "<IP Address>"
Kullanıcı kimliğini veya kimliği doğrulanmış kullanıcı kimliğini ayarlama
aşağıdaki kılavuzu kullanarak istekler için user_Id veya user_AuthenticatedId alanını doldurabilirsiniz. Kullanıcı kimliği anonim bir kullanıcı tanımlayıcısıdır. Kimliği doğrulanmış Kullanıcı Kimliği bilinen bir kullanıcı tanımlayıcısıdır.
Önemli
Kimliği Doğrulanmış Kullanıcı Kimliği'ni ayarlamadan önce geçerli gizlilik yasalarına başvurun.
Özel özellik örneğini kullanın:
// Add the user ID to the activity as a tag, but only if the activity is not null.
activity?.SetTag("enduser.id", "<User Id>");
Özel özellik örneğini kullanın:
// Add the user ID to the activity as a tag, but only if the activity is not null.
activity?.SetTag("enduser.id", "<User Id>");
user ID, requestsveya dependencies tablosundaki exceptionsalanı doldurun.
Uygulamanıza opentelemetry-api-1.0.0.jar (veya daha sonraki bir sürümünü) ekleyin.
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.0.0</version>
</dependency>
Kodunuzda user_Id ayarlayın.
import io.opentelemetry.api.trace.Span;
Span.current().setAttribute("enduser.id", "myuser"); // (user_AuthenticatedId)
Span.current().setAttribute("enduser.pseudo.id", "myuser"); // (user_Id)
user ID, requestsveya dependencies tablosundaki exceptionsalanı doldurun.
Kodunuzda user_Id ayarlayın.
import io.opentelemetry.api.trace.Span;
Span.current().setAttribute("enduser.id", "myuser"); // (user_AuthenticatedId)
Span.current().setAttribute("enduser.pseudo.id", "myuser"); // (user_Id)
Özel özellik örneğini kullanın, ancak aşağıdaki kod satırlarını değiştirin:
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.");
}
}
Özel özellik örneğini kullanın, ancak aşağıdaki kod satırlarını değiştirin:
# Set the `enduser.id` attribute of the span to the specified user ID.
span._attributes["enduser.id"] = "<User ID>"
Günlük öznitelikleri ekleme
OpenTelemetry, .NET ILogger kullanır.
Günlüklere özel boyutlar ekleme, bir ileti şablonu kullanılarak gerçekleştirilebilir.
OpenTelemetry, .NET ILogger kullanır.
Günlüklere özel boyutlar ekleme, bir ileti şablonu kullanılarak gerçekleştirilebilir.
Logback, Log4j ve java.util.logging otomatik olarak araçlaştırılır. Günlüklerinize özel boyutlar ekleme şu yollarla gerçekleştirilebilir:
Spring Boot yerel uygulamaları için Logback, kutudan çıktığı gibi hazır şekilde sunulmaktadır.
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");
}
}
Python logging kitaplığı autoinstrumented şeklindedir. Günlüklerinize, günlüklerinizin parametresine bir sözlük extra geçirerek özelleştirilmiş boyutlar ekleyebilirsiniz.
...
# Create a warning log message with the properties "key1" and "value1".
logger.warning("WARNING: Warning log with properties", extra={"key1": "value1"})
...
HTTP 4xx yanıtları için geçersiz kılma isteği hata durumu
Application Insights'ın 4xx yanıtları hata olarak saymasını engelleyebilirsiniz.
Aşağıdaki kod, HTTP 4xx yanıtlarını başarılı olarak işaretleyen özel bir etkinlik işlemcisini gösterir.
Işlemci:
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);
}
}
Kayıt:
builder.Services.AddOpenTelemetry()
.UseAzureMonitor(options =>
{
options.ConnectionString = "<your-connection-string>";
})
.WithTracing(tracing =>
{
// Add custom processor to mark 4xx responses as successful
tracing.AddProcessor<Http4xxSuccessProcessor>();
});
Aşağıdaki kod, HTTP 4xx yanıtlarını başarılı olarak işaretleyen özel bir etkinlik işlemcisine yöneliktir.
Işlemci:
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);
}
}
Kayıt:
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();
Not
Bu özellik, Java aracısı 3.3.0 sürümünden itibaren kullanılabilir.
Varsayılan olarak aracı, hata olarak 4xx yanıt koduna neden olan HTTP sunucu isteklerini yakalar. Bu davranışı, bunları başarı olarak yakalamak için değiştirebilirsiniz.
{
"preview": {
"captureHttpServer4xxAsError": false
}
}
Işlemci:
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();
}
}
Kayıt (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();
}
}
Kayıt (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();
}
}
Işlemci:
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
Kayıt:
from azure.monitor.opentelemetrgit import configure_azure_monitor
configure_azure_monitor(
connection_string="<your-connection-string>",
span_processors=[Http4xxAsSuccessProcessor()],
)
İzleme kimliğini veya span kimliğini alma
Aşağıdaki adımları kullanarak geçerli etkin yayılma alanı için Trace ID ve Span ID alın.
Not
Activity ve ActivitySource sınıfları, sırasıyla, System.Diagnostics ad alanından Span ve Tracer OpenTelemetry kavramlarını temsil eder. Bunun nedeni OpenTelemetry izleme API'sinin bölümlerinin doğrudan .NET çalışma zamanına dahil edilmiş olmasıdır. Daha fazla bilgi edinmek için bakınız OpenTelemetry .NET İzleme API'sine Giriş.
// 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();
Not
Activity ve ActivitySource sınıfları, sırasıyla, System.Diagnostics ad alanından Span ve Tracer OpenTelemetry kavramlarını temsil eder. Bunun nedeni OpenTelemetry izleme API'sinin bölümlerinin doğrudan .NET çalışma zamanına dahil edilmiş olmasıdır. Daha fazla bilgi edinmek için OpenTelemetry .NET İzleme API’ne Giriş bölümüne bakın.
// 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 kullanarak izleme kimliğini veya span kimliğini alabilirsiniz.
Uygulamanıza opentelemetry-api-1.0.0.jar (veya daha sonraki bir sürümünü) ekleyin.
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.0.0</version>
</dependency>
kodunuzda istek izleme kimliğini ve span kimliğini alın:
import io.opentelemetry.api.trace.Span;
Span span = Span.current();
String traceId = span.getSpanContext().getTraceId();
String spanId = span.getSpanContext().getSpanId();
kodunuzda istek izleme kimliğini ve span kimliğini alın:
import io.opentelemetry.api.trace.Span;
Span span = Span.current();
String traceId = span.getSpanContext().getTraceId();
String spanId = span.getSpanContext().getSpanId();
kodunuzda istek izleme kimliğini ve span kimliğini alın:
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);
}
}
kodunuzda istek izleme kimliğini ve span kimliğini alın:
# 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
Sorun giderme, geri bildirim ve destek
İpucu
Aşağıdaki bölümler tüm OpenTelemetry Distro makalelerinde kullanılabilir.
Sorun giderme
OpenTelemetry Geri Bildirimi
Geri bildirim sağlamak için:
Support
Destek seçeneklerini keşfetmek için istediğiniz dil için bir sekme seçin.
- Azure destek sorunları için bir Azure destek talebi açın.
- Sorun giderme konusunda yardım için sorun giderme adımlarını gözden geçirin.
- OpenTelemetry sorunları için doğrudan OpenTelemetry topluluğuna başvurun.
- Azure İzleyici Java Otomatik Enstrümantasyon ile ilgili açık sorunların listesi için GitHub Sorunlar Sayfası'na bakın.
- Azure destek sorunları için bir Azure destek talebi açın.
- OpenTelemetry sorunları için doğrudan OpenTelemetry topluluğuna başvurun.
- Spring Boot yerel uygulamalarıyla ilgili açık sorunların listesi için bkz. GitHub Sorunlar Sayfası.
- Quarkus yerel uygulamalarıyla ilgili açık sorunların listesi için bkz. GitHub Sorunlar Sayfası.
Not
Quarkus topluluğu, Quarkus uzantılarını destekler ve korur. Yardım için Quarkus topluluk destek kanallarını kullanın. Microsoft bu tümleştirme için teknik destek sağlamaz.
Sonraki adımlar