Skip to content

Class OpenTelemetrySetupExtensions

Namespace: Momentum.ServiceDefaults.OpenTelemetry
Assembly: Momentum.ServiceDefaults.dll

Provides extension methods for configuring OpenTelemetry instrumentation.

csharp
public static class OpenTelemetrySetupExtensions

Inheritance

objectOpenTelemetrySetupExtensions

Inherited Members

object.GetType(), object.MemberwiseClone(), object.ToString(), object.Equals(object?), object.Equals(object?, object?), object.ReferenceEquals(object?, object?), object.GetHashCode()

Methods

AddOpenTelemetry(IHostApplicationBuilder)

Adds comprehensive OpenTelemetry instrumentation for production-ready observability including logging, metrics, and distributed tracing.

csharp
public static IHostApplicationBuilder AddOpenTelemetry(this IHostApplicationBuilder builder)

Parameters

builder IHostApplicationBuilder

The host application builder to configure.

Returns

IHostApplicationBuilder

The configured host application builder for method chaining.

Examples

Basic Usage with Default Configuration

csharp
var builder = WebApplication.CreateBuilder(args);

// Adds complete observability stack
builder.AddOpenTelemetry();

var app = builder.Build();

// Your traces will now include:
// - HTTP request spans with timing
// - Database query spans (if using Entity Framework)
// - Custom business logic spans
app.MapGet("/orders/{id}", async (int id, ActivitySource activitySource) =>
{
    using var activity = activitySource.StartActivity("GetOrder");
    activity?.SetTag("order.id", id);
    
    // This operation will be traced
    return await GetOrderById(id);
});

await app.RunAsync(args);

Custom Configuration for Production

json
// appsettings.Production.json
{
  "OpenTelemetry": {
    "ActivitySourceName": "ECommerce.OrderService",
    "MessagingMeterName": "ECommerce.Orders.Messaging"
  },
  "OTEL_EXPORTER_OTLP_ENDPOINT": "http://otel-collector:4317",
  "OTEL_SERVICE_NAME": "order-service",
  "OTEL_RESOURCE_ATTRIBUTES": "deployment.environment=production,service.version=1.2.0"
}

Custom Metrics in Business Logic

csharp
public class OrderService(Meter orderMeter)
{
    private readonly Counter<int> _ordersProcessed = 
        orderMeter.CreateCounter<int>("orders_processed_total");
    private readonly Histogram<double> _orderValue = 
        orderMeter.CreateHistogram<double>("order_value_dollars");
        
    public async Task<Order> CreateOrderAsync(CreateOrderRequest request)
    {
        var order = new Order(request);
        await _repository.SaveAsync(order);
        
        // Custom metrics for business insights
        _ordersProcessed.Add(1, new("customer_type", request.CustomerType));
        _orderValue.Record(order.TotalValue, new("product_category", order.PrimaryCategory));
        
        return order;
    }
}

Distributed Tracing Across Services

csharp
// Service A (Order API)
app.MapPost("/orders", async (CreateOrderRequest request, HttpClient httpClient) =>
{
    // Create order locally
    var order = await CreateOrder(request);
    
    // Call inventory service - trace context automatically propagated
    await httpClient.PostAsJsonAsync("http://inventory-service/reserve", 
        new { OrderId = order.Id, Items = order.Items });
        
    return order;
});

// Service B (Inventory API) - receives trace context automatically
app.MapPost("/reserve", async (ReserveItemsRequest request) =>
{
    // This operation appears as child span in the same trace
    return await ReserveInventory(request);
});

Troubleshooting Common Issues

csharp
// Problem: No traces appearing in collector
// Solution: Check OTLP endpoint and network connectivity

// Problem: Too many traces in production
// Solution: Sampling is automatically set to 10% in non-development environments

// Problem: Missing custom spans
// Solution: Ensure ActivitySource is injected and spans are disposed
using var activity = activitySource.StartActivity("MyOperation");
// ... work here ...
// Dispose happens automatically with 'using'

// Problem: Missing HTTP client traces
// Solution: Paths containing these patterns are excluded by default:
// - /OrleansSiloInstances (Orleans infrastructure)
// - /$batch (OData batch operations)

Remarks

OpenTelemetry Setup Detailed Configuration Guide

Overview

This method configures a complete observability stack suitable for cloud-native microservices with comprehensive instrumentation for logging, metrics, and distributed tracing.

Distributed Tracing

  • W3C Trace Context and Baggage propagation for cross-service correlation
  • ASP.NET Core request tracing with health check filtering
  • HTTP client instrumentation with sensitive path exclusion
  • gRPC client tracing with URI enrichment
  • Environment-aware sampling (100% dev, 10% production)

Metrics Collection

  • ASP.NET Core metrics (request duration, response status)
  • HTTP client metrics (request duration, retry counts)
  • .NET runtime metrics (GC, memory, thread pool)
  • Wolverine messaging metrics (message processing, errors)
  • Custom application metrics via configurable meters

OTLP Export

  • OTLP exporter for compatibility with Jaeger, Zipkin, and cloud providers
  • Automatic resource attribution with environment labeling
  • Efficient batching and compression for production workloads

Configuration Options

SettingDescription
OpenTelemetry:ActivitySourceNameCustom activity source name (defaults to application name)
OpenTelemetry:MessagingMeterNameCustom meter name for messaging metrics (defaults to {AppName}.Messaging)
OTEL_EXPORTER_OTLP_ENDPOINTOTLP collector endpoint (e.g., http://jaeger:4317)
OTEL_SERVICE_NAMEService name for telemetry attribution

Features

Environment-Aware Configuration

The setup automatically adjusts sampling rates and export configurations based on the hosting environment:

  • Development: 100% sampling for complete visibility during development
  • Production: Optimized sampling rates to balance performance and observability

Instrumentation Coverage

Comprehensive instrumentation across the entire application stack:

  • HTTP Traffic: Complete request/response tracking with timing and status codes
  • Database Operations: Query timing and performance monitoring
  • Message Processing: End-to-end message flow tracking
  • Custom Business Logic: Support for custom activity sources and meters

Performance Optimization

Production-ready configuration with:

  • Efficient batching to minimize network overhead
  • Compression for reduced bandwidth usage
  • Smart filtering to exclude noisy endpoints like health checks
  • Resource attribution for proper service identification