Introducing experimental OpenTelemetry support in the Azure SDK for .NET

Pavel

Cloud-hosted apps are often composed of many services that are integrated together in some fashion. For example, processing a single request might involve:

  • Calling an Azure Storage service.
  • Posting an event to Azure Event Hubs.
  • Calling a custom authentication backend.

With an increasing number of moving pieces comes an increasing number of distributed failure points. Distributed tracing helps collect and correlate diagnostics for complex, multi-service apps. It allows you to follow a customer’s request from the browser to all the components of the system.

How OpenTelemetry helps

OpenTelemetry unifies instrumentation, collection, and export of distributed tracing data across languages, clouds, and libraries. Before OpenTelemetry, changing the hosting platform (running locally, self-hosted, Azure, AWS) or tracing solution (Zipkin, Jaeger, Azure Monitor) required switching the distributed tracing library as well. Switching the tracing library involves changing your app’s code. Also, different tracing libraries vary in their supported integrations (instrumentations). For example, one library might support tracing Redis calls but not Azure Table. Another library might support Azure Table but not Redis, and so on.

OpenTelemetry helps by defining common abstractions for instrumentation, collection, and exporting. When switching your tracing solution to OpenTelemetry, only the exporter plugin needs to change. Your app’s code and third-party library integrations are unaffected.

OpenTelemetry support in the Azure SDK for .NET

OpenTelemetry support means that calls made using Azure SDK libraries would appear in your distributed traces. Azure SDK libraries produce the following kinds of telemetry spans:

  • HTTP calls: Every HTTP call that originates from an Azure SDK library.
  • Client method calls: For example, BlobClient.DownloadTo or SecretClient.StartDeleteSecret.
  • Messaging events: Event Hubs and Service Bus message creation is traced and correlated with its sending, receiving, and processing.

For more detailed distributed tracing conventions, see the specification.

At the time of writing, OpenTelemetry support in the Azure SDK for .NET is experimental. For information on when OpenTelemetry support will be officially released, see the Azure SDK releases page. While the OpenTelemetry SDK for .NET is stable, many tracing conventions that describe the shape of telemetry spans are still experimental. Because OpenTelemetry support is experimental, the shape of spans may change in the future. You can follow changes at the Azure.Core changelog. These changes might impact:

  • The kinds of operations that are tracked.
  • Relationships between telemetry spans.
  • Attributes attached to telemetry spans.

Get started

To start collecting telemetry, complete the following steps:

  1. Enable OpenTelemetry support via one of the following ways:

    • Set the AZURE_EXPERIMENTAL_ENABLE_ACTIVITY_SOURCE environment variable to true.

    • Set the Azure.Experimental.EnableActivitySource context switch to true in your app’s code:

      AppContext.SetSwitch("Azure.Experimental.EnableActivitySource", true);
    • Add the RuntimeHostConfigurationOption setting to your project file:

      <ItemGroup>
          <RuntimeHostConfigurationOption Include="Azure.Experimental.EnableActivitySource" Value="true" />
      </ItemGroup> 
  2. Install the OpenTelemetry package with the following .NET CLI command:

    dotnet package OpenTelemetry
  3. Install one of the exporter packages. To use the preview Azure Monitor/Application Insights exporter, run the following .NET CLI command:

    dotnet add package Azure.Monitor.OpenTelemetry.Exporter --version 1.0.0-beta.2
  4. Create an Application Insights resource to store the data. Follow the create new resource tutorial and copy the connection string.

  5. Configure OpenTelemetry to collect traces and export them to Application Insights:

    using var openTelemetry = Sdk.CreateTracerProviderBuilder()
        .AddSource("Azure.*") // Collect all traces from Azure SDKs
        .AddAzureMonitorTraceExporter(options => options.ConnectionString = 
            "<Application Insights connection string>") // Export traces to Azure Monitor
        .Build(); // Start listening
  6. Add some code making an Azure SDK call. When put together, your code should look something like this:

    AppContext.SetSwitch("Azure.Experimental.EnableActivitySource", true);
    
    using var openTelemetry = Sdk.CreateTracerProviderBuilder()
        .AddSource("Azure.*")
        .AddAzureMonitorTraceExporter(options => options.ConnectionString = 
            "<Application Insights connection string>")
        .Build();
    
    new BlobClient(new Uri("https://aka.ms/bloburl")).DownloadTo("hello.jpg");
  7. Run your app. It takes up to 5 minutes for data to propagate and become accessible through the Azure portal.

  8. View your traces in the Azure portal by navigating to Transaction search on the left for your Application Insights resource. Select See all data in the last 24 hours.

The following screenshot shows a sample trace collected using OpenTelemetry and displayed in the Azure portal:

Azure portal screenshot showing Azure SDK trace collected using OpenTelemetry

Only packages prefixed with Azure. and released after October 1, 2021 have OpenTelemetry support. Earlier packages support only the ApplicationInsights SDK.

We hope you’ll try the new tracing integration and are eager to hear your feedback.

2 comments

Leave a comment

  • Rehan Saeed

    Presumably if we want to collect telemetry from calling CosmosDB or blob storage and export to some provider other than Application Insights we only need to complete step one?

    • Cijo ThomasMicrosoft employee

      Step1 alone won’t be sufficient. You’ll need to replace AddAzureMonitorTraceExporter with something else, like AddConsoleExporter, AddOtlpExporter etc