Observability in C++: Tracing, Metriken und Logs für Profis

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Blick in Ihren C++-Code: Warum Observability kein Luxus, sondern eine Notwendigkeit ist

\n\n

Stellen Sie sich vor: Sie haben einen hochlastigen Dienst in C++ gestartet. Eine Stunde, zwei, ein Tag vergeht – alles läuft. Und dann – peng! – Benutzer beschweren sich über Verzögerungen, und Sie sitzen da und raten: Wo ist der Engpass? Im Speicher? Im Netzwerk? Oder hat einfach jemand vergessen, eine Ressource freizugeben? Ohne ein Observability-System sind Sie wie ein Kapitän eines Schiffes mit zugeklebten Bullaugen. Sie spüren, dass etwas nicht stimmt, aber Sie sehen nicht, was genau.

\n\n

Observability (Beobachtbarkeit) in C++ ist Ihr Satz an Periskopen und Radaren. Es ist nicht nur Logging, es sind die drei Säulen: Tracing, Metriken und Logs. In diesem Artikel werden wir jede davon anhand von echten Codebeispielen durchgehen, zeigen, wie man C++ mit OpenTelemetry und Prometheus verbindet, und fertige Rezepte für die Produktion liefern. Los geht's!

\n\n

Die drei Säulen der Observability: Tracing, Metriken, Logs

\n\n

Bevor wir in den Code eintauchen, definieren wir klar, wie sich diese Konzepte unterscheiden und wie sie sich ergänzen. Viele verwechseln Observability mit einfachem Logging – zu Unrecht. Das ist, als würde man eine Taschenlampe mit einem Flutlicht vergleichen.

\n\n
    \n
  • Logs sind Ereignisse. "Was ist passiert?" (z. B. "Benutzer hat sich angemeldet" oder "Datenbankverbindungsfehler"). Sie sind detailliert, aber ohne Kontext können sie nutzlos sein.
  • \n
  • Metriken sind Zahlen. "Wie viele?" (Anzahl der Anfragen pro Sekunde, CPU-Auslastung, Antwortzeit). Sie sind aggregiert und zeigen Trends.
  • \n
  • Tracing ist der Pfad einer Anfrage. "Wie genau ist das passiert?" (vom Eintritt in den Dienst bis zum Datenbankaufruf und der Antwort an den Client). Es ist das verbindende Glied zwischen Logs und Metriken.
  • \n
\n\n

Ideale Observability in C++ bedeutet, dass Sie beim Blick auf ein Dashboard innerhalb von 10 Sekunden verstehen können: wo, wann und warum eine Anomalie aufgetreten ist. Ohne das werden Sie mit der Produktion Ratespielchen spielen.

\n\n

Tracing in C++: So integrieren Sie OpenTelemetry

\n\n

Beginnen wir mit dem leistungsstärksten, aber auch komplexesten Werkzeug – dem Tracing. OpenTelemetry ist der De-facto-Standard für die Erfassung von Telemetriedaten. In C++ wird es nicht so umfangreich unterstützt wie in Go oder Java, funktioniert aber stabil.

\n\n

Angenommen, wir haben einen einfachen HTTP-Server in C++ (wir verwenden die Idee, nicht eine bestimmte Bibliothek). Wir müssen nachverfolgen, wie lange die Verarbeitung jeder Anfrage dauert und welche Aufrufe darin stattfinden.

\n\n

Einrichtung von OpenTelemetry in C++

\n\n

Zuerst installieren wir die Abhängigkeiten. In CMakeLists.txt fügen wir hinzu:

\n\n
find_package(opentelemetry-cpp REQUIRED)\ntarget_link_libraries(my_app PRIVATE opentelemetry::api opentelemetry::exporter_ostream)
\n\n

Jetzt erstellen wir einen Tracer und Spans (ein Span ist eine Arbeitseinheit). Hier ist ein minimales Beispiel:

\n\n
#include <opentelemetry/trace/provider.h>\n#include <opentelemetry/exporters/ostream/span_exporter.h>\n#include <opentelemetry/sdk/trace/tracer_provider.h>\n#include <opentelemetry/sdk/trace/simple_processor.h>\n\nnamespace trace_api = opentelemetry::trace;\nnamespace trace_sdk = opentelemetry::sdk::trace;\nnamespace trace_exporter = opentelemetry::exporter::trace;\n\nvoid init_tracer() {\n    auto exporter = std::unique_ptr<trace_sdk::SpanExporter>(\n        new trace_exporter::OStreamSpanExporter(std::cout));\n    auto processor = std::unique_ptr<trace_sdk::SpanProcessor>(\n        new trace_sdk::SimpleSpanProcessor(std::move(exporter)));\n    auto provider = std::make_shared<trace_sdk::TracerProvider>(std::move(processor));\n    trace_api::Provider::SetTracerProvider(provider);\n}\n\nvoid process_request(const std::string& user_id) {\n    auto tracer = trace_api::Provider::GetTracerProvider()->GetTracer("my_service");\n    auto span = tracer->StartSpan("process_request");\n    span->SetAttribute("user.id", user_id);\n\n    // Simulation der Arbeit\n    std::this_thread::sleep_for(std::chrono::milliseconds(100));\n\n    span->End();\n}\n\nint main                

Blogs

Buchempfehlungen