Exporters

Send telemetry to the OpenTelemetry Collector to make sure it’s exported correctly. Using the Collector in production environments is a best practice. To visualize your telemetry, export it to a backend such as Jaeger, Zipkin, Prometheus, or a vendor-specific backend.

Available exporters

The registry contains a list of exporters for .NET.

Among exporters, OpenTelemetry Protocol (OTLP) exporters are designed with the OpenTelemetry data model in mind, emitting OTel data without any loss of information. Furthermore, many tools that operate on telemetry data support OTLP (such as Prometheus, Jaeger, and most vendors), providing you with a high degree of flexibility when you need it. To learn more about OTLP, see OTLP Specification.

This page covers the main OpenTelemetry .NET exporters and how to set them up.

OTLP

Collector Setup

To try out and verify your OTLP exporters, you can run the collector in a docker container that writes telemetry directly to the console.

In an empty directory, create a file called collector-config.yaml with the following content:

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318
exporters:
  debug:
    verbosity: detailed
service:
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [debug]
    metrics:
      receivers: [otlp]
      exporters: [debug]
    logs:
      receivers: [otlp]
      exporters: [debug]

Now run the collector in a docker container:

docker run -p 4317:4317 -p 4318:4318 --rm -v $(pwd)/collector-config.yaml:/etc/otelcol/config.yaml otel/opentelemetry-collector

This collector is now able to accept telemetry via OTLP. Later you may want to configure the collector to send your telemetry to your observability backend.

Dependencies

If you want to send telemetry data to an OTLP endpoint (like the OpenTelemetry Collector, Jaeger or Prometheus), you can choose between two different protocols to transport your data:

  • HTTP/protobuf
  • gRPC

Start by installing the OpenTelemetry.Exporter.OpenTelemetryProtocol package as a dependency for your project:

dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol

If you’re using ASP.NET Core install the OpenTelemetry.Extensions.Hosting package as well:

dotnet add package OpenTelemetry.Extensions.Hosting

Usage

ASP.NET Core

Configure the exporters in your ASP.NET Core services:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenTelemetry()
    .WithTracing(tracing => tracing
        // The rest of your setup code goes here
        .AddOtlpExporter())
    .WithMetrics(metrics => metrics
        // The rest of your setup code goes here
        .AddOtlpExporter());

builder.Logging.AddOpenTelemetry(logging => {
    // The rest of your setup code goes here
    logging.AddOtlpExporter();
});

This will, by default, send telemetry using gRPC to http://localhost:4317, to customize this to use HTTP and the protobuf format, you can add options like this:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenTelemetry()
    .WithTracing(tracing => tracing
        // The rest of your setup code goes here
        .AddOtlpExporter(options =>
        {
            options.Endpoint = new Uri("your-endpoint-here/v1/traces");
            options.Protocol = OtlpExportProtocol.HttpProtobuf;
        }))
    .WithMetrics(metrics => metrics
        // The rest of your setup code goes here
        .AddOtlpExporter(options =>
        {
            options.Endpoint = new Uri("your-endpoint-here/v1/metrics");
            options.Protocol = OtlpExportProtocol.HttpProtobuf;
        }));

builder.Logging.AddOpenTelemetry(logging => {
    // The rest of your setup code goes here
    logging.AddOtlpExporter(options =>
    {
        options.Endpoint = new Uri("your-endpoint-here/v1/logs");
        options.Protocol = OtlpExportProtocol.HttpProtobuf;
    });
});

Non-ASP.NET Core

Configure the exporter when creating a TracerProvider, MeterProvider or LoggerFactory:

var tracerProvider = Sdk.CreateTracerProviderBuilder()
    // Other setup code, like setting a resource goes here too
    .AddOtlpExporter(options =>
    {
        options.Endpoint = new Uri("your-endpoint-here/v1/traces");
        options.Protocol = OtlpExportProtocol.HttpProtobuf;
    })
    .Build();

var meterProvider = Sdk.CreateMeterProviderBuilder()
    // Other setup code, like setting a resource goes here too
    .AddOtlpExporter(options =>
    {
        options.Endpoint = new Uri("your-endpoint-here/v1/metrics");
        options.Protocol = OtlpExportProtocol.HttpProtobuf;
    })
    .Build();

var loggerFactory = LoggerFactory.Create(builder =>
{
    builder.AddOpenTelemetry(logging =>
    {
        logging.AddOtlpExporter(options =>
        {
            options.Endpoint = new Uri("your-endpoint-here/v1/logs");
            options.Protocol = OtlpExportProtocol.HttpProtobuf;
        })
    });
});

Use environment variables to set values like headers and an endpoint URL for production.

Console

Dependencies

The console exporter is useful for development and debugging tasks, and is the simplest to set up. Start by installing the OpenTelemetry.Exporter.Console package as a dependency for your project:

dotnet add package OpenTelemetry.Exporter.Console

If you’re using ASP.NET Core install the OpenTelemetry.Extensions.Hosting package as well:

dotnet add package OpenTelemetry.Extensions.Hosting

Usage

ASP.NET Core

Configure the exporter in your ASP.NET Core services:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenTelemetry()
    .WithTracing(tracing => tracing
        // The rest of your setup code goes here
        .AddConsoleExporter()
    )
    .WithMetrics(metrics => metrics
        // The rest of your setup code goes here
        .AddConsoleExporter()
    );

builder.Logging.AddOpenTelemetry(logging => {
    // The rest of your setup code goes here
    logging.AddConsoleExporter();
});

Non-ASP.NET Core

Configure the exporter when creating a TracerProvider, MeterProvider or LoggerFactory:

var tracerProvider = Sdk.CreateTracerProviderBuilder()
    // The rest of your setup code goes here
    .AddConsoleExporter()
    .Build();

var meterProvider = Sdk.CreateMeterProviderBuilder()
    // The rest of your setup code goes here
    .AddConsoleExporter()
    .Build();

var loggerFactory = LoggerFactory.Create(builder =>
{
    builder.AddOpenTelemetry(logging =>
    {
        logging.AddConsoleExporter();
    });
});

Jaeger

Backend Setup

Jaeger natively supports OTLP to receive trace data. You can run Jaeger in a docker container with the UI accessible on port 16686 and OTLP enabled on ports 4317 and 4318:

docker run --rm \
  -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
  -p 16686:16686 \
  -p 4317:4317 \
  -p 4318:4318 \
  -p 9411:9411 \
  jaegertracing/all-in-one:latest

Usage

Now following the instruction to setup the OTLP exporters.

Prometheus

To send your metric data to Prometheus, you can either enable Prometheus’ OTLP Receiver and use the OTLP exporter or you can use the Prometheus exporter, a MetricReader that starts an HTTP server that collects metrics and serialize to Prometheus text format on request.

Backend Setup

You can run Prometheus in a docker container, accessible on port 9090 by following these instructions:

Create a file called prometheus.yml with the following content:

scrape_configs:
  - job_name: dice-service
    scrape_interval: 5s
    static_configs:
      - targets: [host.docker.internal:9464]

Run Prometheus in a docker container with the UI accessible on port 9090:

docker run --rm -v ${PWD}/prometheus.yml:/prometheus/prometheus.yml -p 9090:9090 prom/prometheus --enable-feature=otlp-write-receive

Dependencies

Install the exporter package as a dependency for your application:

dotnet add package OpenTelemetry.Exporter.Prometheus.AspNetCore --version 1.9.0-beta.2

If you’re using ASP.NET Core install the OpenTelemetry.Extensions.Hosting package as well:

dotnet add package OpenTelemetry.Extensions.Hosting

Usage

ASP.NET Core

Configure the exporter in your ASP.NET Core services:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenTelemetry()
    .WithMetrics(metrics => metrics.AddPrometheusExporter());

You’ll then need to add the endpoint so that Prometheus can scrape your site. You can do this using the IAppBuilder extension like this:

var builder = WebApplication.CreateBuilder(args);

// .. Setup

var app = builder.Build();

app.UseOpenTelemetryPrometheusScrapingEndpoint();

await app.RunAsync();

Non-ASP.NET Core

For applications not using ASP.NET Core, you can use the HttpListener version which is available in a different package:

dotnet add package OpenTelemetry.Exporter.Prometheus.HttpListener --version 1.9.0-beta.2

Then this is setup directly on the MeterProviderBuilder:

var meterProvider = Sdk.CreateMeterProviderBuilder()
    .AddMeter(MyMeter.Name)
    .AddPrometheusHttpListener(
        options => options.UriPrefixes = new string[] { "http://localhost:9464/" })
    .Build();

Finally, register the Prometheus scraping middleware using the UseOpenTelemetryPrometheusScrapingEndpoint extension method on IApplicationBuilder :

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseOpenTelemetryPrometheusScrapingEndpoint();

Further details on configuring the Prometheus exporter can be found here.

Zipkin

Backend Setup

You can run Zipkin on in a Docker container by executing the following command:

docker run --rm -d -p 9411:9411 --name zipkin openzipkin/zipkin

Dependencies

To send your trace data to Zipkin, install the exporter package as a dependency for your application:

dotnet add package OpenTelemetry.Exporter.Zipkin

If you’re using ASP.NET Core install the OpenTelemetry.Extensions.Hosting package as well:

dotnet add package OpenTelemetry.Extensions.Hosting

Usage

ASP.NET Core

Configure the exporter in your ASP.NET Core services:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenTelemetry()
    .WithTracing(tracing => tracing
        // The rest of your setup code goes here
        .AddZipkinExporter(options =>
        {
            options.Endpoint = new Uri("your-zipkin-uri-here");
        }));

Non-ASP.NET Core

Configure the exporter when creating a tracer provider:

var tracerProvider = Sdk.CreateTracerProviderBuilder()
    // The rest of your setup code goes here
    .AddZipkinExporter(options =>
    {
        options.Endpoint = new Uri("your-zipkin-uri-here");
    })
    .Build();

Last modified April 17, 2024: Dotnet exporters update 3 (#4310) (21006cc9)