Logging in C++-Anwendungen: Best Practices und Tools

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

Logging in C++-Anwendungen: Best Practices



Logging ist ein grundlegender Bestandteil der Entwicklung jeder ernsthaften C++-Software. Ohne ein zuverlässiges Logging-System werden das Debuggen komplexer Fehler, die Leistungsüberwachung und die Sicherheitsprüfung praktisch unmöglich. In diesem Artikel behandeln wir die Best Practices für Logging in C++, von der Bibliotheksauswahl bis hin zu fortgeschrittenen Techniken für Formatierung und Dateirotation.



1. Auswahl einer Logging-Bibliothek



In C++ gibt es mehrere ausgereifte Bibliotheken für das Logging. Der Verzicht auf eine eigene Implementierung zugunsten einer fertigen Lösung spart Zeit und reduziert die Anzahl der Fehler.



  • spdlog — die beliebteste Bibliothek. Sie zeichnet sich durch hohe Leistung (header-only, asynchroner Modus), einfache API und Unterstützung vieler Formate (JSON, plain text) aus.
  • Boost.Log — eine leistungsstarke, aber schwergewichtigere Bibliothek aus dem Boost-Umfeld. Ideal für Enterprise-Projekte, die komplexe Filterung und flexible Backend-Konfiguration erfordern.
  • Google Logging (glog) — eine einfache Bibliothek von Google. Gut geeignet für kleine Projekte, aber weniger flexibel.


Beispiel für die Initialisierung von spdlog:



#include <spdlog/spdlog.h>#include <spdlog/sinks/basic_file_sink.h>

int main() { // Erstelle einen Logger, der in die Datei "logs/app.log" schreibt auto logger = spdlog::basic_logger_mt("file_logger", "logs/app.log"); // Setze die Logging-Stufe logger->set_level(spdlog::level::debug); // Protokolliere eine Nachricht logger->info("Anwendung gestartet"); return 0;}


2. Logging-Stufen und Filterung



Die Verwendung von Logging-Stufen (trace, debug, info, warning, error, critical) ist der De-facto-Standard. Sie ermöglichen eine flexible Anpassung des Ausgabeumfangs je nach Umgebung (Entwicklung, Test, Produktion).



Empfehlungen zu den Stufen:

  • Trace/Debug — nur für die Entwicklung. Detaillierte Informationen über Ausführungsabläufe, Variablenwerte.
  • Info — Standardereignisse: Start/Stopp eines Dienstes, erfolgreiche Operationen.
  • Warning — ungewöhnliche Situationen, die nicht zu einem Fehler führen (z. B. Verwendung einer veralteten API).
  • Error — Fehler, die Aufmerksamkeit erfordern, aber nicht fatal sind.
  • Critical — fatale Fehler, nach denen die Anwendung nicht weiterarbeiten kann.


Beispiel für die Filterkonfiguration in spdlog:



// In der Produktion schreiben wir nur warning und höherauto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();console_sink->set_level(spdlog::level::warn);

// In die Datei schreiben wir alles, einschließlich debugauto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("logs/debug.log");file_sink->set_level(spdlog::level::debug);

auto logger = std::make_shared<spdlog::logger>("multi_sink", spdlog::sinks_init_list({console_sink, file_sink}));

spdlog::register_logger(logger);


3. Leistung und asynchrones Logging



Synchrones Logging kann besonders in hochbelasteten Systemen zum Leistungsengpass werden. Jeder Aufruf von logger->info(...) blockiert den Thread, bis der Schreibvorgang auf die Festplatte abgeschlossen ist.



Best Practices für die Leistung:

  • Asynchrones Logging — verwenden Sie einen separaten Thread zum Schreiben der Logs. spdlog unterstützt dies von Haus aus.
  • Vermeiden Sie teure Operationen in Log-Zeilen — rufen Sie keine schweren Funktionen innerhalb des Logging-Makros auf. Beispielsweise führt logger->info("Result: {}", computeExpensiveValue()); dazu, dass computeExpensiveValue() auch dann ausgeführt wird, wenn die Log-Stufe nicht

Blogs

Buchempfehlungen