Integration · Go

Go Monitoring und Golang APM

Instrumentieren Sie Ihre Handler mit OpenTelemetry Go, und Obseria zeigt Traces, Goroutines, Heap, GC und Scheduler-Latenz jedes Go-Service, korreliert mit CPU-Profilen, Logs und Kubernetes.
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 Go mit Obseria überwachen

Stabile Standard-Instrumentierung

Traces und Metriken im OpenTelemetry Go SDK sind stabil, Contrib-Pakete decken net/http, gRPC, database/sql-Treiber und verbreitete Frameworks ab.

Goroutines und GC im Kontext

Goroutine-Zahl, Heap-Größe und GC-Ziel stehen direkt neben den betroffenen Traces. Leaks und Allokationsdruck fallen so sofort auf.

Bis auf die Funktion

Continuous Profiling mit unter 1 % Overhead zeigt, welche Funktionen in Produktion CPU verbrauchen oder Speicher allokieren.

Abdeckung

Go-Bibliotheken und Runtimes, die Obseria überwacht

  • net/http-Server und -Clients. otelhttp umschließt Handler und Transports und erzeugt Server- und Client-Spans mit Route, Statuscode und Latenz.
  • gRPC. Die Stats-Handler von otelgrpc tracen Unary- und Streaming-Aufrufe und übertragen den Kontext zwischen Services.
  • Gin, Echo und weitere Web-Frameworks. Contrib-Middleware für gängige Router erzeugt Spans mit Routen-Templates statt roher Pfade.
  • database/sql-, Redis- und Kafka-Clients. Instrumentierte Treiber und Clients machen Queries, Cache-Aufrufe und Nachrichten zu Spans mit Laufzeit.
  • Go-Runtime. Das Contrib-Paket runtime meldet Goroutines, Speicher, GC-Ziel, GOMAXPROCS und Scheduler-Latenz nach den OpenTelemetry Semantic Conventions.
  • Container und Kubernetes. Der Obseria Agent reichert jeden Go-Service mit Pod-, Node- und Container-Metadaten an.
Auf einen Blick

Die Go-Kennzahlen, auf die es ankommt

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

Tempo der Antworten

Zeigt, wie schnell Ihre Go-Dienste auf Anfragen antworten, damit langsame Seiten und Schnittstellen vor Kundenbeschwerden auffallen.

  • http.server.request.duration

Parallele Arbeit

Zeigt, ob die vielen kleinen Aufgaben in der Anwendung normal abgeschlossen werden oder hängen bleiben und zu lange warten.

  • go.goroutine.count
  • go.schedule.duration
  • go.processor.limit

Verbrauch an Speicher

Zeigt, wie viel Speicher die Anwendung im Vergleich zu ihrem Limit nutzt, damit Neustarts durch vollen Speicher ausbleiben.

  • go.memory.used
  • go.memory.limit
  • go.memory.gc.goal

Kurzlebige Daten im Speicher

Macht sichtbar, wie viele kurzlebige Daten die Anwendung erzeugt, was zusätzliche Aufräumarbeit und verschwendete Rechenleistung verursacht.

  • go.memory.allocated
  • go.memory.allocations
Alle 9 Metriken im Detail anzeigen
MetrikEinheitAussage
http.server.request.durationsLatenz-Histogramm eingehender HTTP-Requests je Route und Statuscode, erfasst von otelhttp.
go.goroutine.count{goroutine}Aktive Goroutines; eine Zahl, die nur steigt, deutet auf ein Goroutine-Leak.
go.schedule.durationsWartezeit von Goroutines auf Ausführung; hohe Werte zeigen CPU-Mangel oder GOMAXPROCS-Grenzen.
go.memory.usedByVon der Go-Runtime genutzter Speicher, Grundlage für Leak- und Kapazitätsanalysen.
go.memory.limitByWeiches Speicherlimit aus GOMEMLIMIT, gemeldet, sobald ein Limit gesetzt ist.
go.memory.allocatedByAuf dem Heap allokierte Bytes; eine hohe Rate treibt die GC-Arbeit.
go.memory.allocations{allocation}Anzahl der Heap-Allokationen, um allokationsintensive Codepfade zu finden.
go.memory.gc.goalByZiel-Heapgröße für den nächsten GC-Zyklus, bestimmt durch GOGC und GOMEMLIMIT.
go.processor.limit{thread}GOMAXPROCS, also die Zahl der OS-Threads, die gleichzeitig Go-Code ausführen.
Einrichtung

Go-Monitoring in wenigen Minuten einrichten

  1. Schritt 1

    SDK und Exporter hinzufügen

    Holen Sie per go get das OpenTelemetry Go SDK, die OTLP-HTTP-Exporter für Traces und Metriken sowie das Contrib-Paket runtime.

  2. Schritt 2

    Provider initialisieren

    Legen Sie beim Start Tracer- und Meter-Provider an, rufen Sie runtime.Start auf und umschließen Sie Ihren Mux mit otelhttp.NewHandler.

  3. Schritt 3

    Auf Obseria zeigen

    Setzen Sie OTEL_SERVICE_NAME, den OTLP-Endpoint von Obseria und Ihr Token als Umgebungsvariablen; Traces und Runtime-Metriken treffen nach wenigen Minuten ein.

Beispielkonfiguration · GO
// Modules: go.opentelemetry.io/otel/sdk, .../otel/sdk/metric, .../otlptracehttp,
// .../otlpmetrichttp, go.opentelemetry.io/contrib/instrumentation/runtime and .../otelhttp
// OTEL_SERVICE_NAME, OTEL_EXPORTER_OTLP_ENDPOINT und OTEL_EXPORTER_OTLP_HEADERS
// (Authorization=Bearer%20${OBSERIA_TOKEN}) werden aus der Umgebung gelesen.
func main() {
    ctx := context.Background()
    traceExp, err := otlptracehttp.New(ctx)
    if err != nil {
        log.Fatal(err)
    }
    tp := sdktrace.NewTracerProvider(sdktrace.WithBatcher(traceExp))
    defer tp.Shutdown(ctx)
    otel.SetTracerProvider(tp)
    otel.SetTextMapPropagator(propagation.TraceContext{})

    metricExp, err := otlpmetrichttp.New(ctx)
    if err != nil {
        log.Fatal(err)
    }
    reader := sdkmetric.NewPeriodicReader(metricExp, sdkmetric.WithProducer(runtime.NewProducer()))
    mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader))
    defer mp.Shutdown(ctx)
    otel.SetMeterProvider(mp)
    runtime.Start() // go.goroutine.count, go.memory.used, go.memory.gc.goal ...

    mux := http.NewServeMux()
    mux.HandleFunc("/orders", handleOrders)
    log.Fatal(http.ListenAndServe(":8080", otelhttp.NewHandler(mux, "orders-api")))
}

Sofort einsatzbereit

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

  • Go-Runtime: Goroutines, Heap, GC-Ziel, Scheduler
  • Service-Health mit RED-Metriken je Route
  • Alert bei stetig steigender Goroutine-Zahl
  • Alert bei Speicher nahe GOMEMLIMIT
  • Langsamste gRPC-Methoden und Downstream-Aufrufe
Leitfaden

Go-Monitoring: Darauf kommt es an

Warum Go Monitoring wichtig ist

Go ist die Sprache der Cloud-Infrastruktur und vieler Backends mit hohem Durchsatz: API-Gateways, Zahlungsdienste, Kubernetes-Operatoren und Kommandozeilenwerkzeuge. Go-Services sind meist schlank und schnell, und genau deshalb bleiben Probleme lange unbemerkt. Ein Goroutine-Leak wächst tagelang leise, ein Container-Memory-Limit, das nicht zu GOMEMLIMIT passt, führt zu plötzlichen Neustarts, und ein CPU-Limit unterhalb von GOMAXPROCS verursacht Throttling und hohe Tail-Latenz. Go Monitoring bringt diese Runtime-Details mit Request-Traces zusammen, damit Sie Code, Runtime und Infrastruktur auseinanderhalten.

Anders als Java oder Python wird Go zu einer statischen Binärdatei kompiliert. Der wichtigste Weg zu Golang APM ist daher das OpenTelemetry Go SDK mit Contrib-Bibliotheken: otelhttp für net/http, otelgrpc für gRPC sowie Wrapper für Datenbanktreiber und Frameworks. Traces und Metriken im Go SDK sind stabil. Für Teams, die keinen Code anfassen können, arbeitet OpenTelemetry zudem an Zero-Code-Optionen für Go, darunter das eBPF-basierte Projekt opentelemetry-go-instrumentation und Instrumentierung zur Compile-Zeit. Prüfen Sie deren aktuellen Reifegrad, bevor Sie sich in Produktion darauf verlassen.

Die wichtigsten Signale für Go Performance Monitoring

  • Latenz und Fehler: http.server.request.duration je Route und Fehler-Spans liefern Rate, Fehler und Dauer für jeden Service.
  • Goroutines: go.goroutine.count sollte mit dem Traffic steigen und fallen. Eine Zahl, die nur wächst, ist das klassische Zeichen für ein Leak, meist ein blockierter Channel oder eine fehlende Context-Cancellation.
  • Scheduler-Latenz: go.schedule.duration zeigt, wie lange lauffähige Goroutines auf einen Thread warten. Hohe Werte bei mäßiger CPU-Last deuten oft auf CPU-Throttling im Container.
  • Speicher und GC: go.memory.used, go.memory.gc.goal und go.memory.limit zeigen, wie nah der Heap an Ziel und Limit liegt; go.memory.allocated und go.memory.allocations zeigen den Druck hinter der GC-Arbeit.
  • Parallelität: go.processor.limit zeigt das effektive GOMAXPROCS, das zur tatsächlich verfügbaren CPU passen sollte.

Typische Performance-Probleme in Go erkennen

Goroutine-Leaks

Goroutines, die ewig auf einen Channel, ein Lock oder einen Request ohne Timeout warten, sammeln sich an. Der Speicher folgt der Goroutine-Zahl nach oben. Ein Trend-Alert auf Goroutines je Instanz erkennt das Leak lange vor einem Out-of-Memory-Kill.

GC-Druck

Kurzlebige Allokationen in heißen Codepfaden, etwa beim JSON-Encoding oder Zusammensetzen von Strings, erzwingen häufige GC-Zyklen. Allokationsprofile aus dem Continuous Profiling zeigen, welche Funktionen Sie optimieren sollten, die Metrik zum Heap-Ziel zeigt die Wirkung.

CPU-Throttling in Containern

Liegt GOMAXPROCS über dem CPU-Limit des Containers, plant die Runtime mehr Arbeit ein, als die Quote erlaubt. Sie sehen steigende Scheduler-Latenz und p99-Spitzen, während die durchschnittliche CPU-Last unauffällig bleibt.

Langsame Downstream-Aufrufe

Fehlende Timeouts und erschöpfte Connection Pools lassen eine langsame Abhängigkeit viele Goroutines blockieren. Client-Spans für HTTP, gRPC und SQL machen die Wartezeit in jedem Trace sichtbar.

Retries, die Last verstärken

Aggressive Retries in Go-Clients können eine kurze Verlangsamung einer Abhängigkeit in eine Überlastung verwandeln. Traces mit wiederholten Client-Spans für dieselbe Operation und ein sprunghafter Anstieg ausgehender Requests machen solche Retry-Stürme schnell sichtbar.

Best Practices für Golang Monitoring

  1. Reichen Sie context.Context durch jeden Aufruf, damit Spans verbunden bleiben und Abbrüche weitergegeben werden.
  2. Setzen Sie service.name, service.version und deployment.environment.name per Umgebungsvariable, um Releases zu vergleichen.
  3. Stimmen Sie GOMEMLIMIT und GOMAXPROCS auf die Container-Limits ab und überwachen Sie Runtime- und cgroup-Metriken.
  4. Verwenden Sie Routen-Templates als Span-Namen, um die Kardinalität gering zu halten.
  5. Kombinieren Sie Traces mit Continuous Profiling, um vom langsamen Span zur verantwortlichen Funktion zu gelangen.

So unterstützt Obseria Golang APM

Obseria nimmt Traces und Metriken aus OpenTelemetry Go per OTLP entgegen; Sie behalten das Standard-SDK, ein proprietärer Agent ist nicht nötig. Der Obseria Agent ergänzt Host-, Container- und Kubernetes-Kontext, und TopoGraph ordnet jeden Go-Service seinen Aufrufern, Datenbanken und Queues zu. Continuous Profiling mit unter 1 % Overhead verknüpft heiße Funktionen mit langsamen Traces. Steigt die Latenz, korreliert Obseria Intelligence Goroutine-Wachstum, GC-Druck, Throttling oder ein Deployment und präsentiert die Ursache mit nachvollziehbarer Beweiskette. Dashboards, Alerts und SLOs sind inklusive.

Häufige Fragen zum Go-Monitoring

Üblich ist das OpenTelemetry Go SDK mit Contrib-Bibliotheken wie otelhttp und otelgrpc, was einige Zeilen beim Start erfordert. OpenTelemetry entwickelt zudem eBPF-basierte und Compile-Zeit-Optionen ohne Codeänderung; prüfen Sie deren aktuellen Stand für Ihre Workloads.

Alles, was das Contrib-Paket runtime liefert, darunter go.goroutine.count, go.memory.used, go.memory.gc.goal, go.processor.limit und über seinen Producer auch go.schedule.duration.

Das OpenTelemetry Go SDK ist für den Produktionseinsatz ausgelegt. Der Overhead hängt vom Span-Volumen ab; samplen Sie Routineverkehr und halten Sie Span-Namen kardinalitätsarm. Continuous Profiling in Obseria läuft mit unter 1 % Overhead.

Ja. Obseria liest Prometheus-Metriken per Scraping oder Remote Write ein und unterstützt PromQL. Bestehende client_golang-Metriken und Dashboards funktionieren neben den OpenTelemetry-Daten weiter.

Ja. Installieren Sie den Obseria Agent per Helm als DaemonSet und setzen Sie die OTEL_*-Variablen in der Pod-Spezifikation. Traces werden mit Pod-, Namespace- und Node-Metadaten angereichert.

Starten Sie heute mit dem Go-Monitoring

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