Configure Azure Monitor OpenTelemetry

This guide explains how to configure OpenTelemetry (OTel) in Azure Monitor Application Insights using the Azure Monitor OpenTelemetry distro. Proper configuration ensures consistent telemetry data collection across .NET, Java, Node.js, and Python applications, allowing for more reliable monitoring and diagnostics.

Connection string

A connection string in Application Insights defines the target location for sending telemetry data.

Use one of the following two ways to configure the connection string:

  • Add the Azure Monitor Exporter to each OpenTelemetry signal in application startup.

    // Create a new OpenTelemetry tracer provider.
    // It is important to keep the TracerProvider instance active throughout the process lifetime.
    var tracerProvider = Sdk.CreateTracerProviderBuilder()
        .AddAzureMonitorTraceExporter(options =>
        {
            options.ConnectionString = "<Your Connection String>";
        })
        .Build();
    
    // Create a new OpenTelemetry meter provider.
    // It is important to keep the MetricsProvider instance active throughout the process lifetime.
    var metricsProvider = Sdk.CreateMeterProviderBuilder()
        .AddAzureMonitorMetricExporter(options =>
        {
            options.ConnectionString = "<Your Connection String>";
        })
        .Build();
    
    // Create a new logger factory.
    // It is important to keep the LoggerFactory instance active throughout the process lifetime.
    var loggerFactory = LoggerFactory.Create(builder =>
    {
        builder.AddOpenTelemetry(logging =>
        {
            logging.AddAzureMonitorLogExporter(options =>
            {
                options.ConnectionString = "<Your Connection String>";
            });
        });
    });
    
  • Set an environment variable.

    APPLICATIONINSIGHTS_CONNECTION_STRING=<Your Connection String>
    

Note

If you set the connection string in more than one place, we adhere to the following precedence:

  1. Code
  2. Environment Variable

Set the Cloud Role Name and the Cloud Role Instance

For supported languages, the Azure Monitor OpenTelemetry Distro automatically detects the resource context and provides default values for the Cloud Role Name and the Cloud Role Instance properties of your component. However, you might want to override the default values to something that makes sense to your team. The cloud role name value appears on the Application Map as the name underneath a node.

Set the Cloud Role Name and the Cloud Role Instance via Resource attributes. Cloud Role Name uses service.namespace and service.name attributes, although it falls back to service.name if service.namespace isn't set. Cloud Role Instance uses the service.instance.id attribute value. For information on standard attributes for resources, see OpenTelemetry Semantic Conventions.

// Setting role name and role instance

// Create a dictionary of resource attributes.
var resourceAttributes = new Dictionary<string, object> {
    { "service.name", "my-service" },
    { "service.namespace", "my-namespace" },
    { "service.instance.id", "my-instance" }};

// Create a resource builder.
var resourceBuilder = ResourceBuilder.CreateDefault().AddAttributes(resourceAttributes);

// Create a new OpenTelemetry tracer provider and set the resource builder.
// It is important to keep the TracerProvider instance active throughout the process lifetime.
var tracerProvider = Sdk.CreateTracerProviderBuilder()
    // Set ResourceBuilder on the TracerProvider.
    .SetResourceBuilder(resourceBuilder)
    .AddAzureMonitorTraceExporter()
    .Build();

// Create a new OpenTelemetry meter provider and set the resource builder.
// It is important to keep the MetricsProvider instance active throughout the process lifetime.
var metricsProvider = Sdk.CreateMeterProviderBuilder()
    // Set ResourceBuilder on the MeterProvider.
    .SetResourceBuilder(resourceBuilder)
    .AddAzureMonitorMetricExporter()
    .Build();

// Create a new logger factory and add the OpenTelemetry logger provider with the resource builder.
// It is important to keep the LoggerFactory instance active throughout the process lifetime.
var loggerFactory = LoggerFactory.Create(builder =>
{
    builder.AddOpenTelemetry(logging =>
    {
        // Set ResourceBuilder on the Logging config.
        logging.SetResourceBuilder(resourceBuilder);
        logging.AddAzureMonitorLogExporter();
    });
});

Enable Sampling

You might want to enable sampling to reduce your data ingestion volume, which reduces your cost. Azure Monitor provides a custom fixed-rate sampler that populates events with a sampling ratio, which Application Insights converts to ItemCount. The fixed-rate sampler ensures accurate experiences and event counts. The sampler is designed to preserve your traces across services, and it's interoperable with older Application Insights Software Development Kits (SDKs). For more information, see Learn More about sampling.

Note

Metrics and Logs are unaffected by sampling.

The sampler expects a sample rate of between 0 and 1 inclusive. A rate of 0.1 means approximately 10% of your traces are sent.

// Create a new OpenTelemetry tracer provider.
// It is important to keep the TracerProvider instance active throughout the process lifetime.
var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .AddAzureMonitorTraceExporter(options =>
    {   
        // Set the sampling ratio to 10%. This means that 10% of all traces will be sampled and sent to Azure Monitor.
        options.SamplingRatio = 0.1F;
    })
    .Build();

Tip

When using fixed-rate/percentage sampling and you aren't sure what to set the sampling rate as, start at 5%. (0.05 sampling ratio) Adjust the rate based on the accuracy of the operations shown in the failures and performance panes. A higher rate generally results in higher accuracy. However, ANY sampling affects accuracy so we recommend alerting on OpenTelemetry metrics, which are unaffected by sampling.

Live metrics

Live metrics provides a real-time analytics dashboard for insight into application activity and performance.

This feature isn't available in the Azure Monitor .NET Exporter.

Note

We recommend the Azure Monitor OpenTelemetry Exporter for console and worker service applications, which doesn't include live metrics.

Offline Storage and Automatic Retries

Azure Monitor OpenTelemetry-based offerings cache telemetry when an application disconnects from Application Insights and retries sending for up to 48 hours. For data handling recommendations, see Export and delete private data. High-load applications occasionally drop telemetry for two reasons: exceeding the allowable time or exceeding the maximum file size. When necessary, the product prioritizes recent events over old ones.

By default, the AzureMonitorExporter uses one of the following locations for offline storage (listed in order of precedence):

  • Windows
    • %LOCALAPPDATA%\Microsoft\AzureMonitor
    • %TEMP%\Microsoft\AzureMonitor
  • Non-Windows
    • %TMPDIR%/Microsoft/AzureMonitor
    • /var/tmp/Microsoft/AzureMonitor
    • /tmp/Microsoft/AzureMonitor

To override the default directory, you should set AzureMonitorExporterOptions.StorageDirectory.

// Create a new OpenTelemetry tracer provider and set the storage directory.
// It is important to keep the TracerProvider instance active throughout the process lifetime.
var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .AddAzureMonitorTraceExporter(options =>
    {
        // Set the Azure Monitor storage directory to "C:\\SomeDirectory".
        // This is the directory where the OpenTelemetry SDK will store any trace data that cannot be sent to Azure Monitor immediately.
        options.StorageDirectory = "C:\\SomeDirectory";
        })
        .Build();

// Create a new OpenTelemetry meter provider and set the storage directory.
// It is important to keep the MetricsProvider instance active throughout the process lifetime.
var metricsProvider = Sdk.CreateMeterProviderBuilder()
    .AddAzureMonitorMetricExporter(options =>
    {
        // Set the Azure Monitor storage directory to "C:\\SomeDirectory".
        // This is the directory where the OpenTelemetry SDK will store any metric data that cannot be sent to Azure Monitor immediately.
        options.StorageDirectory = "C:\\SomeDirectory";
        })
        .Build();

// Create a new logger factory and add the OpenTelemetry logger provider with the storage directory.
// It is important to keep the LoggerFactory instance active throughout the process lifetime.
var loggerFactory = LoggerFactory.Create(builder =>
{
    builder.AddOpenTelemetry(logging =>
    {
        logging.AddAzureMonitorLogExporter(options =>
        {
            // Set the Azure Monitor storage directory to "C:\\SomeDirectory".
            // This is the directory where the OpenTelemetry SDK will store any log data that cannot be sent to Azure Monitor immediately.
            options.StorageDirectory = "C:\\SomeDirectory";
        });
    });
});

To disable this feature, you should set AzureMonitorExporterOptions.DisableOfflineStorage = true.

Enable the OTLP Exporter

You might want to enable the OpenTelemetry Protocol (OTLP) Exporter alongside the Azure Monitor Exporter to send your telemetry to two locations.

Note

The OTLP Exporter is shown for convenience only. We don't officially support the OTLP Exporter or any components or third-party experiences downstream of it.

  1. Install the OpenTelemetry.Exporter.OpenTelemetryProtocol package in your project.

    dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol
    
  2. Add the following code snippet. This example assumes you have an OpenTelemetry Collector with an OTLP receiver running. For details, see the example on GitHub.

    // Create a new OpenTelemetry tracer provider and add the Azure Monitor trace exporter and the OTLP trace exporter.
    // It is important to keep the TracerProvider instance active throughout the process lifetime.
    var tracerProvider = Sdk.CreateTracerProviderBuilder()
        .AddAzureMonitorTraceExporter()
        .AddOtlpExporter()
        .Build();
    
    // Create a new OpenTelemetry meter provider and add the Azure Monitor metric exporter and the OTLP metric exporter.
    // It is important to keep the MetricsProvider instance active throughout the process lifetime.
    var metricsProvider = Sdk.CreateMeterProviderBuilder()
        .AddAzureMonitorMetricExporter()
        .AddOtlpExporter()
        .Build();
    

OpenTelemetry configurations

The following OpenTelemetry configurations can be accessed through environment variables while using the Azure Monitor OpenTelemetry Distros.

Environment variable Description
APPLICATIONINSIGHTS_CONNECTION_STRING Set it to the connection string for your Application Insights resource.
APPLICATIONINSIGHTS_STATSBEAT_DISABLED Set it to true to opt out of internal metrics collection.
OTEL_RESOURCE_ATTRIBUTES Key-value pairs to be used as resource attributes. For more information about resource attributes, see the Resource SDK specification.
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.

Redact URL Query Strings

To redact URL query strings, turn off query string collection. We recommend this setting if you call Azure storage using a SAS token.

When using the Azure.Monitor.OpenTelemetry.Exporter, you must manually include either the ASP.NET Core or HttpClient Instrumentation libraries in your OpenTelemetry configuration. These Instrumentation libraries have QueryString Redaction enabled by default.

To change this behavior, you must set an environment variable to either true or false.

  • ASP.NET Core Instrumentation: OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_DISABLE_URL_QUERY_REDACTION Query String Redaction is enabled by default. To disable, set this environment variable to true.
  • Http Client Instrumentation: OTEL_DOTNET_EXPERIMENTAL_HTTPCLIENT_DISABLE_URL_QUERY_REDACTION Query String Redaction is enabled by default. To disable, set this environment variable to true.