OpenTelemetry .NET distro for Uptrace

This document explains how to configure the OpenTelemetry .NET SDK to export spans and metrics to Uptrace using OTLP/gRPC.

To learn about the OpenTelemetry API, see OpenTelemetry .NET Tracing API and OpenTelemetry .NET Metrics API.

Overview

OpenTelemetry provides observability for your .NET applications by collecting telemetry data (traces, metrics, and logs) and exporting it to monitoring systems like Uptrace.

Installation Options

uptrace-dotnet is a lightweight wrapper around opentelemetry-dotnet that pre-configures the OpenTelemetry SDK to export data to Uptrace. It doesn't add new functionality but simplifies the setup process for your convenience.

Installation:

shell
dotnet add package Uptrace.OpenTelemetry --prerelease

Option 2: Direct OTLP Exporter

Use the OTLP exporter directly if you prefer more control over the configuration or are already using OpenTelemetry exporters. See the Direct OTLP Configuration section below.

Quick Start Guide

Follow these steps to get your first trace running in 5 minutes:

Step 1: Create an Uptrace Project

Create an Uptrace project to obtain a DSN (Data Source Name), for example, https://<secret>@api.uptrace.dev?grpc=4317.

Step 2: Install uptrace-dotnet

shell
dotnet add package Uptrace.OpenTelemetry --prerelease

Step 3: Basic Configuration

Configure the Uptrace client using a DSN (Data Source Name) from your project settings page. Replace <FIXME> with your actual Uptrace DSN and myservice with a name that identifies your application.

cs
using System;
using System.Diagnostics;

using OpenTelemetry;
using OpenTelemetry.Trace;
using OpenTelemetry.Resources;

using Uptrace.OpenTelemetry;

var serviceName = "myservice";
var serviceVersion = "1.0.0";

var openTelemetry = Sdk.CreateTracerProviderBuilder()
    .AddSource("*") // Subscribe to all activity sources
    .SetResourceBuilder(
        ResourceBuilder
            .CreateDefault()
            .AddEnvironmentVariableDetector()
            .AddTelemetrySdk()
            .AddService(serviceName: serviceName, serviceVersion: serviceVersion)
    )
    // Copy your project DSN here or use UPTRACE_DSN env var
    //.AddUptrace("<FIXME>")
    .AddUptrace()
    .Build();

Step 4: Run the Complete Example

Clone the basic example to get a ready-to-run application:

shell
git clone https://github.com/uptrace/uptrace-dotnet.git
cd uptrace-dotnet/example/basic

Step 5: Run Your Application

Execute your application, replacing <FIXME> with your Uptrace DSN:

shell
UPTRACE_DSN="<FIXME>" dotnet run

You should see output similar to:

text
https://app.uptrace.dev/traces/<trace_id>

Step 6: View Your Trace

Click the generated link to view your trace in the Uptrace dashboard:

Basic trace

Direct OTLP Configuration

If you prefer to use the OTLP exporter directly or are already using OpenTelemetry exporters, you can configure OpenTelemetry manually without the uptrace-dotnet wrapper.

Uptrace fully supports the OpenTelemetry Protocol (OTLP) over both gRPC and HTTP transports.
If you already have an OTLP exporter configured, you can continue using it with Uptrace by simply pointing it to the Uptrace OTLP endpoint.

Connecting to Uptrace

Choose an OTLP endpoint from the table below and pass your DSN via the uptrace-dsn header for authentication:

TransportEndpointPort
gRPChttps://api.uptrace.dev:43174317
HTTPhttps://api.uptrace.dev443

When using HTTP transport, you often need to specify the full URL for each signal type:

  • https://api.uptrace.dev/v1/traces
  • https://api.uptrace.dev/v1/logs
  • https://api.uptrace.dev/v1/metrics

Note: Most OpenTelemetry SDKs support both transports. Use HTTP unless you're already familiar with gRPC.

For performance and reliability, we recommend:

  • Use BatchSpanProcessor and BatchLogProcessor for batching spans and logs, reducing the number of export requests.
  • Enable gzip compression to reduce bandwidth usage.
  • Prefer delta metrics temporality (Uptrace converts cumulative metrics automatically).
  • Use Protobuf encoding instead of JSON (Protobuf is more efficient and widely supported).
  • Use HTTP transport for simplicity and fewer configuration issues (unless you're already familiar with gRPC).
  • Optionally, use the AWS X-Ray ID generator to produce trace IDs compatible with AWS X-Ray.

Common Environment Variables

You can use environment variables to configure resource attributes and propagators::

VariableDescription
OTEL_RESOURCE_ATTRIBUTESComma-separated resource attributes, e.g., service.name=myservice,service.version=1.0.0.
OTEL_SERVICE_NAME=myserviceSets the service.name attribute (overrides OTEL_RESOURCE_ATTRIBUTES).
OTEL_PROPAGATORSComma-separated list of context propagators (default: tracecontext,baggage).

Most language SDKs allow configuring the OTLP exporter entirely via environment variables:

shell
# Endpoint (choose HTTP or gRPC)
export OTEL_EXPORTER_OTLP_ENDPOINT="https://api.uptrace.dev"         # HTTP
#export OTEL_EXPORTER_OTLP_ENDPOINT="https://api.uptrace.dev:4317"   # gRPC

# Pass DSN for authentication
export OTEL_EXPORTER_OTLP_HEADERS="uptrace-dsn=<FIXME>"

# Performance optimizations
export OTEL_EXPORTER_OTLP_COMPRESSION=gzip
export OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=BASE2_EXPONENTIAL_BUCKET_HISTOGRAM
export OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=DELTA

Configure BatchSpanProcessor to balance throughput and payload size:

shell
export OTEL_BSP_EXPORT_TIMEOUT=10000         # Max export timeout (ms)
export OTEL_BSP_MAX_EXPORT_BATCH_SIZE=10000  # Avoid >32MB payloads
export OTEL_BSP_MAX_QUEUE_SIZE=30000         # Adjust for available memory
export OTEL_BSP_MAX_CONCURRENT_EXPORTS=2     # Parallel exports

Troubleshooting

If you encounter issues with OpenTelemetry .NET, try these troubleshooting guides:

Common Issues

No data appearing in Uptrace:

  • Verify your DSN is correctly configured
  • Check that your application is generating spans/metrics
  • Ensure network connectivity to Uptrace endpoints

Performance issues:

  • Adjust sampling rates if collecting too much data
  • Review instrumentation configuration for unnecessary overhead

What's next?