End-to-End Observability for .NET 8 Minimal APIs with Azure Event Hubs and OpenTelemetry

Mahmut Sarıkaya 4 dk okuma 9 Görüntülenme 0
End-to-End Observability for .NET 8 Minimal APIs with Azure Event Hubs and OpenTelemetry

Why observability matters for Minimal APIs

Did you know that 73% of production incidents are traced back to insufficient logging and tracing? Minimal APIs in .NET 8 promise lightning‑fast startup and low overhead, but they also reduce the amount of boilerplate code that traditionally carries diagnostic scaffolding. Without a systematic observability strategy, a single latency spike can remain invisible until it escalates into a user‑facing outage.

Setting up the .NET 8 Minimal API

Begin with a clean .NET 8 SDK (6.0.400 or later). The following program defines a simple order endpoint that will later be instrumented. Save the file as Program.cs and run dotnet run to verify the API returns JSON.

using Microsoft.AspNetCore.Builder;<br/>using Microsoft.AspNetCore.Http;<br/>var builder = WebApplication.CreateBuilder(args);<br/>var app = builder.Build();<br/>app.MapPost("/order", async (OrderDto order) => {<br/>    // Simulate processing delay<br/>    await Task.Delay(150);<br/>    return Results.Created($"/order/{order.Id}", order);<br/>});<br/>app.Run();<br/>public record OrderDto(Guid Id, string Product, int Quantity);

The code uses only the essential builder pattern, keeping the footprint under 30 KB. This minimalism is ideal for micro‑services that will be deployed to Azure Container Apps or Azure Functions.

Instrumenting with OpenTelemetry

OpenTelemetry provides a vendor‑agnostic API for traces, metrics, and logs. Add the following NuGet packages: OpenTelemetry.Exporter.OpenTelemetryProtocol, OpenTelemetry.Extensions.Hosting, and OpenTelemetry.Instrumentation.AspNetCore. Then extend the builder configuration.

builder.Services.AddOpenTelemetry().WithTracing(tracer => {<br/>    tracer.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("OrderService"))<br/>          .AddAspNetCoreInstrumentation()<br/>          .AddHttpClientInstrumentation()<br/>          .AddOtlpExporter(opts => {<br/>              opts.Endpoint = new Uri("https://.servicebus.windows.net");<br/>          });<br/>});

Notice the AddOtlpExporter call – it will forward spans to Azure Event Hubs via the OpenTelemetry Protocol (OTLP). The service name OrderService becomes a searchable tag in downstream dashboards.

Sending traces to Azure Event Hubs

Azure Event Hubs now supports OTLP ingestion natively (preview as of March 2024). Create an Event Hub namespace, enable the “OTLP” feature, and generate a shared access key. The exporter configuration above expects the Event Hub endpoint in the form https://{namespace}.servicebus.windows.net and will use the default SAS token authentication.

az eventhubs namespace create --resource-group MyRG --name my-namespace --location eastus --sku Standard<br/>az eventhubs eventhub create --resource-group MyRG --namespace-name my-namespace --name otlp-hub<br/>az eventhubs namespace authorization-rule create --resource-group MyRG --namespace-name my-namespace --name otlp-auth --rights Send Listen<br/>az eventhubs namespace authorization-rule keys list --resource-group MyRG --namespace-name my-namespace --name otlp-auth

The last command returns primaryConnectionString. Paste it into the OTEL_EXPORTER_OTLP_ENDPOINT environment variable or supply it directly in the exporter options.

Configuring Azure Event Hubs as a collector

On the Azure side, create a Log Analytics workspace and link the Event Hub as a custom data source. Azure Monitor will decode the OTLP payload, correlate spans across services, and render a distributed trace view. Enable the “Enable sampling” option to keep ingestion costs below $0.02 per GB for typical traffic volumes (approximately 1 M spans per hour).

Viewing distributed traces

Open Azure Monitor, navigate to “Metrics Explorer”, and select the trace namespace. You can filter by service.name = “OrderService” and drill down to individual HTTP requests. The UI shows latency breakdowns for middleware, controller logic, and external HTTP calls, letting you pinpoint the 150 ms artificial delay introduced earlier.

For teams that prefer Grafana, the same Event Hub can be consumed by a Grafana Cloud Agent using the otlp_http receiver. The agent forwards data to a Grafana Loki instance, where you can build dashboards with the traceID field as a key.

Best practices and performance tips

1. **Sample wisely** – configure a 1‑5 % head‑based sampler in production to balance visibility and cost. 2. **Enrich spans** – add custom attributes such as order.id or customer.region using Activity.Current?.SetTag. 3. **Avoid blocking** – the OTLP exporter works asynchronously; never await ExportAsync in request pipelines. 4. **Monitor exporter health** – expose /metrics from the OpenTelemetry SDK to watch otel_exporter_otlp_successful_spans counters.

By following these steps, you turn a 30‑KB Minimal API into a fully observable micro‑service that integrates seamlessly with Azure’s serverless ecosystem.

Sources

Microsoft Docs – OpenTelemetry .NET SDK
Azure Documentation – Event Hubs OTLP support
OpenTelemetry Specification – Trace data model

Author: Mahmut Sarıkaya — sarikayadev.com

Etiketler: #.NET 8 #Minimal APIs #Azure Event Hubs #OpenTelemetry #Distributed Tracing
Paylaş:
M

Yazar

Mahmut Sarıkaya

yazılım Geliştirici

Yorumlar

Henüz yorum yok. İlk yorumu siz yapın!

Yorum Bırakın

1 + 3 =