Skip to content

Class OpenTelemetrySetupExtensions ​

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

Provides extension methods for configuring OpenTelemetry instrumentation.

csharp
[ExcludeFromCodeCoverage]
public static class OpenTelemetrySetupExtensions

Inheritance ​

object ← OpenTelemetrySetupExtensions

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