.Net

Install the package

Install the Azure Monitor Distro for .NET from NuGet:

dotnet add package Azure.Monitor.OpenTelemetry.AspNetCore --prerelease

Enabling Azure Monitor OpenTelemetry in your application

The following examples demonstrate how to integrate the Azure Monitor Distro into your application.

Example 1

To enable Azure Monitor Distro, add UseAzureMonitor() to your Program.cs file and set the APPLICATIONINSIGHTS_CONNECTION_STRING environment variable to the connection string from your Application Insights resource.

// This method gets called by the runtime. Use this method to add services to the container.
var builder = WebApplication.CreateBuilder(args);

// The following line enables Azure Monitor Distro.
builder.Services.AddOpenTelemetry().UseAzureMonitor();

// This code adds other services for your application.
builder.Services.AddMvc();

var app = builder.Build();

Example 2

To enable Azure Monitor Distro with a hard-coded connection string, add UseAzureMonitor() to your Program.cs with the AzureMonitorOptions containing the connection string.

// This method gets called by the runtime. Use this method to add services to the container.
var builder = WebApplication.CreateBuilder(args);

// The following line enables Azure Monitor Distro with hard-coded connection string.
builder.Services.AddOpenTelemetry().UseAzureMonitor(o => o.ConnectionString = "InstrumentationKey=00000000-0000-0000-0000-000000000000");

// This code adds other services for your application.
builder.Services.AddMvc();

var app = builder.Build();

Note that in the examples above, UseAzureMonitor is added to the IServiceCollection in the Program.cs file. You can also add it in the ConfigureServices method of your Startup.cs file.

Note Multiple calls to AddOpenTelemetry.UseAzureMonitor() will NOT result in multiple providers. Only a single TracerProvider, MeterProvider and LoggerProvider will be created in the target IServiceCollection. To establish multiple providers use the Sdk.CreateTracerProviderBuilder() and/or Sdk.CreateMeterProviderBuilder() and/or LoggerFactory.CreateLogger methods with the Azure Monitor Exporter instead of using Azure Monitor Distro.

Authenticate the client

Azure Active Directory (AAD) authentication is an optional feature that can be used with Azure Monitor Distro. To enable AAD authentication, set the Credential property in AzureMonitorOptions. This is made easy with the Azure Identity library, which provides support for authenticating Azure SDK clients with their corresponding Azure services.

// Call UseAzureMonitor and set Credential to authenticate through Active Directory.
builder.Services.AddOpenTelemetry().UseAzureMonitor(o =>
{
    o.ConnectionString = "InstrumentationKey=00000000-0000-0000-0000-000000000000";
    o.Credential = new DefaultAzureCredential();
});

With this configuration, the Azure Monitor Distro will use the credentials of the currently logged-in user or of the service principal to authenticate and send telemetry data to Azure Monitor.

Note that the Credential property is optional. If it is not set, Azure Monitor Distro will use the Instrumentation Key from the Connection String to send data to Azure Monitor.

Advanced configuration

The Azure Monitor Distro includes .NET OpenTelemetry instrumentation for ASP.NET Core, HttpClient, and SQLClient. However, you can customize the instrumentation included or use additional instrumentation on your own using the OpenTelemetry API. Here are some examples of how to customize the instrumentation:

Customizing AspNetCoreInstrumentationOptions

builder.Services.AddOpenTelemetry().UseAzureMonitor();
builder.Services.Configure<AspNetCoreInstrumentationOptions>(options =>
{
    options.RecordException = true;
    options.Filter = (httpContext) =>
    {
        // only collect telemetry about HTTP GET requests
        return HttpMethods.IsGet(httpContext.Request.Method);
    };
});

Customizing HttpClientInstrumentationOptions

builder.Services.AddOpenTelemetry().UseAzureMonitor();
builder.Services.Configure<HttpClientInstrumentationOptions>(options =>
{
    options.RecordException = true;
    options.FilterHttpRequestMessage = (httpRequestMessage) =>
    {
        // only collect telemetry about HTTP GET requests
        return HttpMethods.IsGet(httpRequestMessage.Method.Method);
    };
});

Customizing SqlClientInstrumentationOptions

builder.Services.AddOpenTelemetry().UseAzureMonitor();
builder.Services.Configure<SqlClientInstrumentationOptions>(options =>
{
    options.SetDbStatementForStoredProcedure = false;
});

Customizing Sampling Percentage

When using the Azure Monitor Distro, the sampling percentage for telemetry data is set to 100% (1.0F) by default. For example, let's say you want to set the sampling percentage to 50%. You can achieve this by modifying the code as follows:

builder.Services.AddOpenTelemetry().UseAzureMonitor(o =>
{
    o.SamplingRatio = 0.5F;
});

Adding Custom ActivitySource to Traces

builder.Services.AddOpenTelemetry().UseAzureMonitor();
builder.Services.ConfigureOpenTelemetryTracerProvider((sp, builder) => builder.AddSource("MyCompany.MyProduct.MyLibrary"));

Adding Custom Meter to Metrics

builder.Services.AddOpenTelemetry().UseAzureMonitor();
builder.Services.ConfigureOpenTelemetryMeterProvider((sp, builder) => builder.AddMeter("MyCompany.MyProduct.MyLibrary"));

Adding Additional Instrumentation

If you need to instrument a library or framework that isn't included in the Azure Monitor Distro, you can add additional instrumentation using the OpenTelemetry Instrumentation packages. For example, to add instrumentation for gRPC clients, you can add the OpenTelemetry.Instrumentation.GrpcNetClient package and use the following code:

builder.Services.AddOpenTelemetry().UseAzureMonitor();
builder.Services.ConfigureOpenTelemetryTracerProvider((sp, builder) => builder.AddGrpcClientInstrumentation());

Adding Another Exporter

Azure Monitor Distro uses the Azure Monitor exporter to send data to Application Insights. However, if you need to send data to other services, including Application Insights, you can add another exporter. For example, to add the Console exporter, you can install the OpenTelemetry.Exporter.Console package and use the following code:

builder.Services.AddOpenTelemetry().UseAzureMonitor();
builder.Services.ConfigureOpenTelemetryMeterProvider((sp, builder) => builder.AddConsoleExporter());

Adding Custom Resource

To modify the resource, use the following code.

builder.Services.AddOpenTelemetry().UseAzureMonitor();
builder.Services.ConfigureOpenTelemetryTracerProvider((sp, builder) => builder.ConfigureResource(resourceBuilder => resourceBuilder.AddService("service-name")));

It is also possible to configure the Resource by using following environmental variables:

Environment variableDescription

OTEL_RESOURCE_ATTRIBUTES

Key-value pairs to be used as resource attributes. See the Resource SDK specification for more details.

OTEL_SERVICE_NAME

Sets the value of the service.name resource attribute. If service.name is also provided in OTEL_RESOURCE_ATTRIBUTES, then OTEL_SERVICE_NAME takes precedence.

Example:

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#if NET6_0_OR_GREATER
using System.Diagnostics;
using System.Net.Http;
using Azure.Monitor.OpenTelemetry.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenTelemetry().UseAzureMonitor();

/*
builder.Services.AddOpenTelemetry().UseAzureMonitor(o =>
{
    o.ConnectionString = "InstrumentationKey=00000000-0000-0000-0000-00000000CODE";
    // Set the Credential property to enable AAD based authentication:
    // o.Credential = new DefaultAzureCredential();
});
*/

var app = builder.Build();
app.MapGet("/", () =>
{
    app.Logger.LogInformation("Hello World!");

    using var client = new HttpClient();
    var response = client.GetAsync("https://www.bing.com/").Result;

    return $"Hello World! OpenTelemetry Trace: {Activity.Current?.Id}";
});

app.Run();
#endif

Last updated