Skip to content

ASP.NET Core OpenTelemetry instrumentation

This guide adds the OpenTelemetry .NET SDK to an ASP.NET Core service and configures it to send traces, metrics, and logs to Osuite. It uses OpenTelemetry.Extensions.Hosting to register instrumentation in Program.cs and the OTLP exporter to ship the data.

  • .NET 8.0 or later and an ASP.NET Core project with a Program.cs.
  • An Osuite ingest endpoint and token for your region.
  • Outbound network access to ingest.<region>.osuite.io on port 443.
  1. Install the OpenTelemetry packages.

    Terminal window
    dotnet add package OpenTelemetry.Extensions.Hosting
    dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol
    dotnet add package OpenTelemetry.Instrumentation.AspNetCore
    dotnet add package OpenTelemetry.Instrumentation.Http
    dotnet add package OpenTelemetry.Instrumentation.Runtime
  2. Configure OpenTelemetry in Program.cs. Register tracing and metrics through AddOpenTelemetry(), add logging through builder.Logging, and attach the OTLP exporter to each signal. The exporter reads its endpoint and headers from the environment variables set in the next step.

    using OpenTelemetry.Logs;
    using OpenTelemetry.Metrics;
    using OpenTelemetry.Trace;
    var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddOpenTelemetry()
    .WithTracing(tracing => tracing
    .AddAspNetCoreInstrumentation()
    .AddHttpClientInstrumentation()
    .AddOtlpExporter())
    .WithMetrics(metrics => metrics
    .AddAspNetCoreInstrumentation()
    .AddHttpClientInstrumentation()
    .AddRuntimeInstrumentation()
    .AddOtlpExporter());
    builder.Logging.AddOpenTelemetry(logging =>
    {
    logging.IncludeScopes = true;
    logging.IncludeFormattedMessage = true;
    logging.AddOtlpExporter();
    });
    var app = builder.Build();
    app.MapGet("/", () => "Hello from Osuite");
    app.Run();
  3. Set the Osuite environment variables. The OTLP exporter and the resource are configured entirely from the environment, so the same code runs in every environment.

    Terminal window
    export OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.<region>.osuite.io:443
    export OTEL_EXPORTER_OTLP_HEADERS=x-osuite-ingest-token=<your-ingest-token>
    export OTEL_SERVICE_NAME=my-service
    export OTEL_RESOURCE_ATTRIBUTES=service.environment=production
  4. Run the service and send it some traffic.

    Terminal window
    dotnet run

Instrumentation covers both minimal APIs and controller-based apps with no additional configuration. AddHttpClientInstrumentation traces outbound HttpClient calls so requests to downstream services join the same trace.

What you should see

The service appears in APM within a minute of receiving traffic, emitting request-rate, latency, and error-rate metrics. Open a trace to see the ASP.NET Core server span with any outbound HttpClient spans nested beneath it, and confirm application logs appear in Logs correlated to the same trace.

No data in Osuite after a few minutes? Work through these checks.

  • Endpoint — confirm the exporter targets exactly ingest.<region>.osuite.io:443 for your region, over TLS.
  • Token — confirm the ingest header carries a valid <your-ingest-token> and has not been rotated.
  • Pipeline — confirm the signal you expect (traces, logs, or metrics) is wired into an active pipeline with the otlp/osuite exporter attached.
  • Export errors — check the application or Collector logs for OTLP export failures (auth, DNS, TLS, connection refused).
  • Network — confirm the host has outbound access to the ingest endpoint on port 443.
  • Timing — allow up to a minute for the first data to appear before assuming a failure.

Still stuck? Ask the Investigation Agent or contact support.

See .NET troubleshooting for issues specific to the SDK, such as missing ActivitySource registration and IIS environment variables.