OpenTelemetry for .NET | Honeycomb

We use cookies or similar technologies to personalize your online experience & tailor marketing to you. Many of our product features require cookies to function properly.

Read our privacy policy I accept cookies from this site

OpenTelemetry for .NET

Honeycomb has a OpenTelemetry Distribution for .NET that wraps the official OpenTelemetry .NET SDK to simplify the setup process and add instrumentation your applications to send telemetry data to Honeycomb.

Requirements  🔗

These instructions will explain how to set instrumentation for a service written in .NET. In order to follow along, you will need:

  • A .NET application that conforms to NET Standard 2.0, or a .NET Framework 4.6.1+ application.
  • A Honeycomb API Key. You can find your API key on your Team Settings page. If you don’t have an API key yet, sign up for a free Honeycomb account.

Installing the Package  🔗

Install the Honeycomb.OpenTelemetry nuget package using a NuGet package manager or the dotnet CLI.

For example, with the dotnet CLI, use:

dotnet add package Honeycomb.OpenTelemetry

Configuration  🔗

Configure your app for Honeycomb OpenTelemetry Distribution for .NET with one of the following configuration methods:

Programmatically  🔗

You can provide an HoneycombOptions object to programmatically configure the OpenTelemetry SDK.

var tracerProvider = new TracerProviderBuilder()
    .AddHoneycomb(new HoneycombOptions
    {
        ServiceName = "my-app",
        ApiKey = "{apikey}",
        Dataset = "{dataset}"
    })
    .Build();

ASP.NET Core  🔗

You can provide an appsettings.json file:

{
  ...
  "Honeycomb": {
    "ServiceName": "my-app",
    "ApiKey": "{apikey}",
    "Dataset": "{dataset}",
  }
}

Then, pass the IConfiguration object to configure the OpenTelemetry SDK:

var tracerProvider = new TracerProviderBuilder()
    .AddHoneycomb(configuration)
    .Build();

NOTE: It is possible to leverage the AppSettings ability to read environment variables to populate values in the configuration object. For example, the following environment variables could be used to override the values in an AppSettings file:

export HONEYCOMB__SERVICENAME=my-app
export HONEYCOMB__APIKEY={apikey}
export HONEYCOMB__DATASET={dataset}

See the OpenTelemetry ASP.NET Core instrumentation for more advanced options.

ASP.NET (.NET Framework v4.6.1+)  🔗

Add the following to your Web.config:

<system.webServer>
    <modules>
    <add name="TelemetryCorrelationHttpModule"
         type="Microsoft.AspNet.TelemetryCorrelation.TelemetryCorrelationHttpModule,Microsoft.AspNet.TelemetryCorrelation"
         preCondition="integratedMode,managedHandler" />
    </modules>
</system.webServer>

Configure the OpenTelemetry SDK to use Honeycomb during application start:

using OpenTelemetry;
using OpenTelemetry.Trace;
using Honeycomb.OpenTelemetry;

public class WebApiApplication : HttpApplication
{
    private TracerProvider tracerProvider;

    protected void Application_Start()
    {
        this.tracerProvider = new TracerProviderBuilder()
            .AddHoneycomb(new HoneycombOptions
            {
                ServiceName = "my-app",
                ApiKey = "{apikey}",
                Dataset = "{dataset}"
            })
            .Build();
    }

    protected void Application_End()
    {
        this.tracerProvider?.Dispose();
    }
}

See the OpenTelemetry ASP.NET instrumentation for more advanced options.

Command Line Arguments  🔗

You can provide command line arguments when starting your application:

dotnet run \
  --service-name=my-app \
  --honeycomb-apikey={apikey} \
  --honeycomb-dataset={dataset}

Then, pass the command line arguments to configure the OpenTelemetry SDK:

var tracerProvider = new TracerProviderBuilder()
    .AddHoneycomb(args)
    .Build();

NOTE: AddHoneycomb sets the OpenTelemetry SDK ResourceBuilder, which is used to create the Resource that is associated to all spans created by the tracer. Please do not override the ResourceBuilder by calling SetResourceBuilder with another instance. Otherwise, some resource attributes may not be queryable in your Honeycomb data.

Enabled Instrumentation Packages  🔗

The Honeycomb Distribution enables the following official instrumentation packages automatically as part of the initialization process:

  • ASP.NET Core (For .NET Core apps)
  • ASP.NET (For .NET Framework apps)
  • Redis
  • HTTP Client
  • SQL Client
  • gRPC Client

Additional instrumentation packages can be added during initialization. For example, to add the MySQL instrumentation from OpenTelemetry-Contrib (after installing the package), use:

var tracerProvider = new TracerProviderBuilder()
    .AddHoneycomb(new HoneycombOptions
    {
        ServiceName = "my-app",
        ApiKey = "{apikey}",
        Dataset = "{dataset}"
    })
    .AddMySqlDataInstrumentation()
    .Builder();

Redis instrumentation requires access to the IConnection object to setup tracing. This can either be provided as part of the AddHoneycomb call by setting the RedisConnection property on HoneycombOptions or it can be automatically retrieved if it’s registered in the ASP.NET ServiceCollection object.

Adding Context to Spans  🔗

It’s often beneficial to add context to a currently executing span in a trace. For example, you may have an application or service that handles users and you want to associate the user with the span when querying your dataset in Honeycomb. In order to do this, get the current span from the context and set an attribute with the user ID:

using OpenTelemetry.Trace;

...

var currentSpan = Tracer.CurrentSpan;
currentSpan.SetAttribute("user_id", User.GetUserId())

This configuration will add a user_id attribute to the current span, so that you can use the field in WHERE, GROUP BY, or ORDER clauses in the Honeycomb query builder.

Creating New Spans  🔗

In order to get the full picture of what’s happening, you will have to add manual instrumentation and create custom spans to describe what is happening in your application. To do this, grab your tracer instance and use it to create a span:

using OpenTelemetry.Trace;

...

using (var span = TracerProvider.Default.GetTracer("my-service").StartActiveSpan("expensive-query"))
{
    // ... do cool stuff
}

Sampling  🔗

Deterministic sampling can be enabled by providing a SampleRate via the following methods. A sample rate of 5 means that one out of every five traces will be sent to Honeycomb.

var options = new HoneycombOptions
{
    ServiceName = "my-app",
    ApiKey = "{apikey}",
    Dataset = "{dataset}",
    SampleRate = 5 // sends 1/5 traces
}
{
  "Honeycomb": {
    "SampleRate": 5,
  }
}
dotnet run --honeycomb-samplerate=5

Distributed Trace Propagation  🔗

When a service calls another service, you want to be sure that the relevant trace information is propagated from one service to the other. This allows Honeycomb to connect the two services in a trace. Trace context propagation is done by sending and parsing headers that conform to the W3C Trace Context specification.

In order for this to work, both the sending and receiving service must be using the same propagation format, and both services must be configured to send data to the same Honeycomb dataset.