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.

Samples  🔗

There are several samples that configure applications to send OpenTelemetry data to Honeycomb.

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 --prerelease

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.

using OpenTelemetry;

using var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .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 in your application startup code:

using Honeycomb.OpenTelemetry;

public IConfiguration Configuration { get; }

//...

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    // configure OpenTelemetry SDK to send data to Honeycomb
    services.AddHoneycomb(Configuration);
}

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()
    {
        _tracerProvider = Sdk.CreateTracerProviderBuilder()
            .AddHoneycomb(new HoneycombOptions
            {
                ServiceName = "my-app",
                ApiKey = "{apikey}",
                Dataset = "{dataset}"
            })
            .Build();
    }

    protected void Application_End()
    {
        _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:

using OpenTelemetry;

//...

using var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .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:

using OpenTelemetry;

//...

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

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.

Disabling Instrumentation Packages  🔗

You can disable individual instrumented packages by setting them as false, as shown in the following configuration:

using var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .AddHoneycomb(new HoneycombOptions
    {
        ServiceName = "my-app",
        ApiKey = "{apikey}",
        Dataset = "{dataset}",
        InstrumentHttpClient = false,
        InstrumentSqlClient = false,
        InstrumentGprcClient = false,
        InstrumentStackExchangeRedisClient = false
    })
    .Build();

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  🔗

By default, OpenTelemetry for .NET is configured to propagate traces and baggage across services. Trace context uses the W3C Trace Context specification by default.

If you wish to use a different propagation format, both the sending and receiving services must use the same propagation format.