Integration · .NET

.NET-Monitoring und APM

Die automatische Instrumentierung von OpenTelemetry .NET sendet Traces, Runtime-Metriken und Logs aus ASP.NET Core, Worker Services und .NET Framework an Obseria, ohne Codeänderung.
Obseria Apps und Funktionen: Observability, APM, Infrastruktur und Integrationen
Obseria Home-Dashboard mit Service-Zustand, offenen Problemen, SLO-Erfüllung und Ingestion
Obseria Trace-Explorer mit Span-Liste und Span-Attributen
Überblick

Warum .NET mit Obseria überwachen

Keine Codeänderung

Die automatische Instrumentierung von OpenTelemetry .NET bindet sich beim Start in ASP.NET Core, HttpClient, SQL-Clients und gRPC ein.

Runtime-Zustand auf einen Blick

GC, Heap-Größe, Thread-Pool-Warteschlange und Exceptions erscheinen je Service und korreliert mit der Request-Latenz.

Windows, Linux und Container

Überwachen Sie IIS-Anwendungen, Linux-Services und Kubernetes-Pods mit einem einheitlichen OpenTelemetry-Datenmodell.

Abdeckung

.NET-Frameworks und Bibliotheken, die Obseria überwacht

  • ASP.NET Core und Kestrel. Jeder eingehende Request wird zum Server-Span mit Route, Statuscode und Dauer.
  • ASP.NET auf .NET Framework und IIS. Klassische Webanwendungen unter Windows erfasst die Instrumentierung für .NET Framework.
  • HttpClient und gRPC. Ausgehende Aufrufe tragen den W3C-Trace-Kontext zu Services in jeder Sprache.
  • Entity Framework Core und SqlClient. SQL-Statements erscheinen als Client-Spans mit Dauer und Zieldatenbank.
  • Messaging-Clients. Unterstützte Clients wie Azure Service Bus, RabbitMQ und Kafka geben den Trace-Kontext über Queues weiter.
  • Worker Services und Hintergrundjobs. Hosted Services und Konsolenanwendungen werden wie Web-Workloads getract.
Auf einen Blick

Die .NET-Kennzahlen, auf die es ankommt

Obseria erfasst diese Werte automatisch und zeigt sie in fertigen Dashboards und Alerts.

Tempo und Verbindungen

Zeigt, wie schnell Ihre .NET-Dienste auf Anfragen antworten und wie viele Nutzer gleichzeitig verbunden sind.

  • http.server.request.duration
  • kestrel.active_connections

Speicher und Aufräumen

Zeigt, wie viel Speicher Ihre Anwendung nutzt und wie oft sie zum Aufräumen pausiert, was kurze Verzögerungen verursacht.

  • dotnet.gc.collections
  • dotnet.gc.pause.time
  • dotnet.gc.last_collection.heap.size
  • dotnet.process.memory.working_set

Warteschlange für Aufgaben

Macht sichtbar, ob sich eingehende Arbeit staut, weil die Anwendung mit der Nachfrage nicht Schritt hält.

  • dotnet.thread_pool.queue.length
  • dotnet.thread_pool.thread.count

Fehler der Anwendung

Hebt hervor, wie oft die Anwendung auf unerwartete Fehler stößt, eine frühe Warnung vor defekten Funktionen oder fehlerhaften Releases.

  • dotnet.exceptions
Alle 9 Metriken im Detail anzeigen
MetrikEinheitAussage
http.server.request.durationsLatenz eingehender ASP.NET-Core-Requests je Route und Statuscode.
dotnet.gc.collections{collection}Garbage Collections je Generation; häufige Gen-2-Collections erhöhen die Latenz.
dotnet.gc.pause.timesGesamtzeit, in der die Runtime durch GC pausiert war.
dotnet.gc.last_collection.heap.sizeByGröße des Managed Heap je Generation nach der letzten GC, um Leaks zu erkennen.
dotnet.thread_pool.queue.length{work_item}Wartende Work Items; Wachstum signalisiert Thread-Pool-Starvation.
dotnet.thread_pool.thread.count{thread}Threads im Thread-Pool; Sprünge folgen oft auf Sync-over-Async-Code.
dotnet.exceptions{exception}Geworfene Exceptions je Typ; Spitzen gehen oft steigenden Fehlerraten voraus.
dotnet.process.memory.working_setByPhysischer Speicher des Prozesses, im Vergleich zu Container-Limits.
kestrel.active_connections{connection}Offene Verbindungen am Kestrel-Webserver.
Einrichtung

.NET-Monitoring in wenigen Minuten einrichten

  1. Schritt 1

    Autoinstrumentierung installieren

    Führen Sie das offizielle Skript otel-dotnet-auto-install aus, nutzen Sie das NuGet-Paket oder überlassen Sie Hosts und Kubernetes dem Obseria Agent.

  2. Schritt 2

    Exporter konfigurieren

    Setzen Sie OTEL_SERVICE_NAME, den OTLP-Endpoint von Obseria und Ihr Token als Umgebungsvariablen.

  3. Schritt 3

    Anwendung starten

    Laden Sie instrument.sh (unter Windows das PowerShell-Modul) und starten Sie die Anwendung wie gewohnt.

Beispielkonfiguration · BASH
# OpenTelemetry .NET Autoinstrumentierung installieren (Linux/macOS)
curl -sSfL -O \
  https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/latest/download/otel-dotnet-auto-install.sh
sh ./otel-dotnet-auto-install.sh
chmod +x "$HOME/.otel-dotnet-auto/instrument.sh"

export OTEL_SERVICE_NAME="orders-api"
export OTEL_RESOURCE_ATTRIBUTES="deployment.environment.name=production"
export OTEL_EXPORTER_OTLP_ENDPOINT="${OBSERIA_OTLP_ENDPOINT}"
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer%20${OBSERIA_TOKEN}"
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"

. "$HOME/.otel-dotnet-auto/instrument.sh"
dotnet OrdersApi.dll

Sofort einsatzbereit

Dashboards, Alerts und SLOs, die bereitstehen, sobald die ersten Daten ankommen.

  • .NET-Runtime: GC, Heap, Thread-Pool, Exceptions
  • ASP.NET-Core-Endpoints mit RED-Metriken
  • Alert bei wachsender Thread-Pool-Queue
  • Alert auf Gen-2-Collection-Rate
  • Top-Exceptions je Typ und Service
Leitfaden

.NET-Monitoring: Darauf kommt es an

Warum .NET-Monitoring wichtig ist

.NET treibt eine große Bandbreite produktiver Systeme an, von ASP.NET-Core-APIs in Linux-Containern bis zu langlebigen .NET-Framework-Anwendungen unter Windows und IIS. Beide teilen sich eine Managed Runtime mit eigenem Garbage Collector, Thread-Pool und JIT-Compiler. .NET-Monitoring bedeutet, diese Runtime-Interna gemeinsam mit Request-Traces zu beobachten. Nur so lässt sich erklären, warum ein Endpoint langsam ist oder die Fehlerrate nach einem Release steigt.

Modernes .NET bringt Observability bereits mit: System.Diagnostics.Activity ist der native Span-Typ, System.Diagnostics.Metrics liefert Counter und Histogramme. OpenTelemetry baut auf beidem auf. Die automatische Instrumentierung von OpenTelemetry .NET aktiviert sie beim Start Ihrer Anwendung, sodass .NET APM ohne Neukompilierung funktioniert.

Die wichtigsten Runtime-Signale

  • Latenz und Fehler: http.server.request.duration je Route und Statuscode liefert die RED-Sicht auf jeden ASP.NET-Core-Service.
  • Garbage Collection: dotnet.gc.collections je Generation und dotnet.gc.pause.time. Gen-2-Collections sind teuer und sollten selten sein.
  • Heap-Größe: dotnet.gc.last_collection.heap.size je Generation, inklusive Large Object Heap. Stetiges Wachstum bedeutet, dass Objekte am Leben gehalten werden.
  • Thread-Pool: dotnet.thread_pool.queue.length und dotnet.thread_pool.thread.count. Eine wachsende Warteschlange ist das deutlichste Zeichen für Thread-Pool-Starvation.
  • Exceptions: dotnet.exceptions je Typ. Auch abgefangene Exceptions kosten CPU und deuten oft auf eine ausfallende Abhängigkeit hin.

Typische Performance-Probleme in .NET

Thread-Pool-Starvation

Blockierende Aufrufe wie .Result oder .Wait() auf asynchronem Code binden Threads des Thread-Pools. Der Pool fügt nur langsam neue Threads hinzu, Requests stauen sich, und die Latenz steigt sprunghaft, während die CPU moderat bleibt. Die Lösung ist meist ein durchgängig asynchroner Aufrufpfad; die Metriken zeigen Ihnen, wo und wann das Problem auftritt.

Memory Leaks und LOH-Fragmentierung

Statische Caches, nie abgemeldete Event-Handler und große Puffer auf dem Large Object Heap halten Speicher fest. Beobachten Sie Heap-Größe nach GC und Working Set gemeinsam, besonders in Containern mit knappen Memory-Limits. So erkennen Sie, ob der Managed Heap oder nativer Speicher wächst.

Gesprächiger Datenbankzugriff

Entity Framework Core erzeugt mitunter viele kleine Queries pro Request. Traces zeigen jeden SQL-Span mit Dauer, sodass N+1-Muster und fehlende Indizes ohne separate Profiler-Sitzung sichtbar werden.

Exceptions als Kontrollfluss

Code, der in heißen Pfaden Exceptions wirft und wieder fängt, verbrennt CPU. Eine hohe Rate bei dotnet.exceptions bei unveränderter Fehlerrate ist das typische Muster.

Socket-Erschöpfung durch falsch genutzten HttpClient

Wer für jeden Request einen neuen HttpClient erzeugt, hinterlässt viele Sockets im Zustand TIME_WAIT und kann unter Last die lokalen Ports erschöpfen. Ausgehende Client-Spans, die mit Verbindungsfehlern scheitern, obwohl der Zielservice gesund ist, sind ein deutlicher Hinweis. Die Lösung ist IHttpClientFactory oder ein gemeinsam genutzter, langlebiger Client.

Langsame Abhängigkeiten hinter Retries

Resilience-Bibliotheken wiederholen fehlgeschlagene Aufrufe transparent. Das hält die Fehlerrate niedrig, kostet aber Latenz. Traces zeigen jeden Wiederholungsversuch als eigenen Client-Span. So erkennen Sie, dass ein nachgelagerter Service schwächelt, lange bevor er vollständig ausfällt, und können rechtzeitig gegensteuern.

Container-Limits und Server-GC

Der Server-GC von .NET legt pro CPU-Kern einen eigenen Heap an. In Containern mit wenig Speicher führt das ohne passende Konfiguration schnell zu OOM-Kills. Vergleichen Sie Working Set und Container-Limit, bevor Pods unerwartet neu starten.

Best Practices für .NET APM

  1. Nutzen Sie die Autoinstrumentierung für breite Abdeckung und ergänzen Sie eigene ActivitySource-Spans für wichtige Geschäftsvorgänge.
  2. Setzen Sie service.name und service.version, um Deployments direkt vergleichen zu können.
  3. Aktivieren Sie die Log-Korrelation: OpenTelemetry ergänzt ILogger-Ausgaben um Trace- und Span-IDs.
  4. Alarmieren Sie auf Thread-Pool-Queue und Gen-2-Rate, nicht nur auf CPU und Speicher.
  5. Setzen Sie eine aktuelle .NET-Version ein, deren Runtime die standardisierten dotnet.*-Metriken nativ ausgibt.

So unterstützt Obseria das .NET Performance Monitoring

Obseria verarbeitet OpenTelemetry-Traces, -Metriken und -Logs aus .NET per OTLP. Ihre Instrumentierung bleibt herstellerneutral, und Daten lassen sich jederzeit exportieren. Der Obseria Agent ergänzt Host-, IIS- und Container-Kontext und kann die Autoinstrumentierung auf Hosts und in Kubernetes ausrollen. TopoGraph zeigt, wie jeder .NET-Service mit SQL Server, Caches und Message Brokern verbunden ist. Continuous Profiling mit unter 1 % Overhead deckt heiße Methoden und Allokationen auf. Im Fehlerfall korreliert Obseria Intelligence Thread-Pool-Starvation, Deployments oder ausfallende Abhängigkeiten und erklärt die Ursache mit einer Beweiskette. Dashboards, Alerts und SLOs sind inklusive.

Häufige Fragen zum .NET-Monitoring

Ja. Die automatische Instrumentierung von OpenTelemetry .NET unterstützt modernes .NET unter Windows und Linux sowie .NET Framework unter Windows. Obseria verarbeitet die OTLP-Daten beider Varianten.

Nein. Die Autoinstrumentierung wird beim Start über Umgebungsvariablen aktiviert. Optional ergänzen Sie eigene Spans mit ActivitySource und Metriken mit Meter.

Installieren Sie die Autoinstrumentierung auf dem Windows-Server und registrieren Sie sie mit dem mitgelieferten PowerShell-Modul für den IIS. Der Obseria Agent ergänzt Host- und IIS-Kontext.

Ja. Nutzt Ihre Anwendung bereits das OpenTelemetry .NET SDK, richten Sie den OTLP-Exporter auf Obseria aus. Erste Traces sind typischerweise in 15 Minuten sichtbar.

Ja. Über ILogger geschriebene Logs enthalten Trace- und Span-IDs, sodass Obseria jede Logzeile dem passenden Request-Trace zuordnet.

Starten Sie heute mit dem .NET-Monitoring

Binden Sie .NET in Minuten per OpenTelemetry oder Obseria Agent an. 14 Tage kostenlos.