S

super-dev — full-stack

@super-dev.app · Full-stack · ★ offen für Aufträge
12,8k Abonnenten·47 Videos·Aktiv seit 2017

Full-Stack-Entwickler .NET / Angular mit DevOps-Erfahrung auf Azure Cloud. Auch zu Hause mit Flutter + Firebase. Ich entwickle Produkte, deploye sie und überwache sie.

Zurück zu den Artikeln
DEVOPS
DEVOPS

Observability in .NET mit OpenTelemetry

Artikel 6 von 6 — Azure DevOps von Grund auf
Prerender, Container Apps, Secrets, CI/CD, Docker, Observability: auf Azure deployen, ohne Server und ohne Schmerzen.

Wenn eine Anfrage drei Services durchläuft und langsam wird, sagen Logs allein nicht, wo . Moderne Observability beruht auf drei korrelierten Signalen — Traces, Metriken, Logs — und OpenTelemetry ist deren herstellerneutraler Standard: Man instrumentiert einmal und exportiert in ein beliebiges Backend (Jaeger, Prometheus, Azure Monitor), ohne den Code neu zu schreiben.

Drei Signale, eine einzige API

OpenTelemetry vereinheitlicht die drei Säulen der Observability. Traces verfolgen eine Anfrage von Ende zu Ende über eine Folge von Spans, die durch eine trace_id korreliert sind. Metriken aggregieren Zähler und Histogramme (Request-Rate, p95-Latenz). Logs liefern den textuellen Kontext, der nun an die aktuelle trace_id gebunden ist. .NET stellt diese Konzepte nativ bereit über System.Diagnostics.Activity (die Spans) und System.Diagnostics.Metrics .

C#
1var builder = WebApplication.CreateBuilder(args);
2
3builder.Services.AddOpenTelemetry()
4 .ConfigureResource(r => r.AddService("api-super-dev"))
5 .WithTracing(t => t
6 .AddAspNetCoreInstrumentation()
7 .AddHttpClientInstrumentation()
8 .AddOtlpExporter())
9 .WithMetrics(m => m
10 .AddAspNetCoreInstrumentation()
11 .AddRuntimeInstrumentation()
12 .AddOtlpExporter());

Auto-Instrumentation vs. manuelle Spans

Die Auto-Instrumentation deckt das Wesentliche kostenlos ab: AddAspNetCoreInstrumentation erzeugt einen Span pro eingehender Anfrage, AddHttpClientInstrumentation propagiert den Kontext bei ausgehenden Aufrufen — die serviceübergreifende Korrelation erfolgt automatisch über die traceparent -Header des W3C-Standards. Für die Geschäftslogik fügt man manuelle Spans hinzu, um eine konkrete Operation zu messen und ihr Business-Attribute anzuhängen.

C#
1private static readonly ActivitySource Source = new("SuperDev.Orders");
2
3public async Task<Order> PlaceOrderAsync(Cart cart)
4{
5 using var activity = Source.StartActivity("place-order");
6 activity?.SetTag("order.items", cart.Items.Count);
7 activity?.SetTag("order.total", cart.Total);
8
9 var order = await _repository.SaveAsync(cart);
10 activity?.SetTag("order.id", order.Id);
11
12 return order;
13}

Die Attribute ( SetTag ) verwandeln einen Trace in ein Debugging-Werkzeug: man filtert nach order.total > 1000 oder identifiziert den genauen Span, dessen Latenz explodiert ist.

Der OTLP-Exporter und der Collector

OTLP (OpenTelemetry Protocol) ist das gemeinsame Transportformat. Statt direkt in ein Backend zu exportieren, sendet man alles an den Collector : einen zwischengeschalteten Prozess, der empfängt, transformiert (Batching, Sampling, Filterung sensibler Attribute) und an ein oder mehrere Ziele weiterleitet. Die App kennt nur einen Endpoint; ein Backend-Wechsel wird zur Konfigurationsänderung auf Collector-Seite, nicht zu einem Redeployment.

YAML
1receivers:
2 otlp:
3 protocols:
4 grpc:
5 endpoint: 0.0.0.0:4317
6processors:
7 batch:
8 timeout: 5s
9exporters:
10 prometheus:
11 endpoint: 0.0.0.0:8889
12 otlp/jaeger:
13 endpoint: jaeger:4317
14service:
15 pipelines:
16 traces:
17 receivers: [otlp]
18 processors: [batch]
19 exporters: [otlp/jaeger]
20 metrics:
21 receivers: [otlp]
22 processors: [batch]
23 exporters: [prometheus]

Die App zeigt über OTEL_EXPORTER_OTLP_ENDPOINT , eine Standard-Umgebungsvariable, auf den Collector. Die OpenTelemetry-Dokumentation behandelt das Sampling ( ParentBased , TraceIdRatioBased ), das in der Produktion unverzichtbar ist, um nicht vom Trace-Volumen überwältigt zu werden.

Mit OpenTelemetry zu instrumentieren bedeutet, den Code vom Monitoring-Tool zu entkoppeln. Wenn man von Jaeger zu Azure Monitor migriert, ändert man keine einzige Zeile App-Code : man tauscht den Exporter des Collectors aus.
super-dev — portfolio.app
// Weiter in DEVOPS
>_
Eine CI/CD-Pipeline GitHub Actions → Azure, von Grund auf
8 min • 1,9k Aufrufe
Multi-Stage Docker-Images für .NET + Angular
9 min • 2,6k Aufrufe