Journalisation dans les applications C++ : meilleures pratiques et outils

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : Pourquoi une journalisation correcte en C++ ?

La journalisation ne consiste pas simplement à écrire des messages dans un fichier. Dans un environnement de production, c'est votre outil principal pour la surveillance, le débogage et l'audit. Une journalisation mal configurée peut entraîner une perte de données critiques, une baisse des performances (I/O-bound) ou, à l'inverse, un encombrement "sonore" des disques. Dans cet article, nous allons analyser les meilleures pratiques de journalisation en C++ qui vous aideront à éviter les erreurs typiques et à construire un système de collecte de logs fiable.

1. Choix de la bibliothèque : spdlog vs glog vs std::clog

La bibliothèque standard C++ n'offre que les flux de base std::clog et std::cerr, qui ne conviennent pas aux projets sérieux. Examinons trois approches populaires :

1.1. spdlog — le standard moderne

spdlog est une bibliothèque header-only avec prise en charge de la journalisation asynchrone, de la rotation des fichiers, du formatage (à la fmtlib) et de multiples récepteurs (fichier, console, syslog, Kafka).

Avantages clés :

  • Haute performance (grâce aux flux asynchrones)
  • Configuration flexible des niveaux et des formats
  • Prise en charge de la journalisation structurée (JSON)
#include <spdlog/spdlog.h>
#include <spdlog/sinks/rotating_file_sink.h>

int main() {
    // Crée un logger fichier avec rotation (5 fichiers de 10 MB)
    auto logger = spdlog::rotating_logger_mt("file_logger", "logs/app.log", 1048576 * 10, 5);
    logger->set_level(spdlog::level::info);
    logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [%t] %v");

    logger->info("Application démarrée");
    logger->warn("Faible mémoire disponible : {} MB", free_memory);
    logger->error("Erreur de connexion à la BD : {}", err.what());
    return 0;
}

1.2. Google glog — une solution éprouvée

La bibliothèque glog de Google est simple à utiliser et intègre la prise en charge de la journalisation conditionnelle et des vidages de pile. Inconvénient : formatage moins flexible et absence d'asynchronisme.

#include <glog/logging.h>

int main(int argc, char* argv[]) {
    google::InitGoogleLogging(argv[0]);
    FLAGS_log_dir = "./logs";
    FLAGS_stderrthreshold = google::WARNING; // Duplique WARNING+ dans stderr

    LOG(INFO) << "Serveur démarré sur le port " << port;
    LOG_IF(WARNING, memory_usage > 0.9) << "Mémoire presque épuisée";
    LOG(FATAL) << "Erreur critique, arrêt";
    return 0;
}

1.3. Logger maison avec std::clog

Utilisez std::clog uniquement pour le débogage ou les très petits utilitaires. Il ne prend pas en charge la rotation, les niveaux et le multithreading.

#define LOG(level, msg) std::clog << "[" << level << "] " << msg << std::endl;
LOG("INFO", "Démarrage");
LOG("ERROR", "Erreur : " + std::to_string(errno));

2. Meilleures pratiques de configuration et d'architecture

Même la meilleure bibliothèque ne sauvera pas si l'architecture de journalisation est mal conçue. Suivez ces principes :

2.1. Utilisez les niveaux de journalisation

Définissez 5 à 6 niveaux et respectez-les strictement :

  • TRACE — débogage détaillé (entrée/sortie des fonctions)
  • DEBUG — informations de débogage pour les développeurs
  • INFO — fonctionnement normal de l'application (démarrage, arrêt)
  • WARN — problèmes potentiels (disque faible, charge élevée)
  • ERROR — erreurs qui n'interrompent pas le fonctionnement (exceptions)
  • FATAL — erreur critique après laquelle l'application s'arrête
// En production, on met WARN pour ne pas saturer les logs avec les messages INFO
logger->set_level(spdlog::level::warn);

2.2. Journalisation structurée (JSON)

Pour

Blogs

Book Recommendations