Monitoring and Logging C++ Applications: From Chaos to Order

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Is Your C++ Application a Black Box? Time to Fix That!

\n\n

Imagine this: you've launched a high-load C++ service, everything works perfectly. A week passes, then another — and suddenly users complain about slowdowns. You dive into the code, add std::cout in critical places, recompile, restart... Sound familiar? If so, this article is for you.

\n\n

In the world of production C++, monitoring and logging are not a luxury, but a necessity. Without them, you're as blind as a mole in a dark room. But the good news is that modern C++ (especially starting from C++17) provides all the tools to create a transparent, observable system.

\n\n

In this article, we'll break down how to turn your application from a "black box" into a fully transparent system using real libraries and techniques. You'll learn how to log in a way that makes logs useful, not just noisy, and how to set up monitoring that truly helps during deployment.

\n\n

Why Plain std::cout is a Pain?

\n\n

Many beginner C++ developers write like this:

\n\n
std::cout << "Error: file not found" << std::endl;
\n\n

At first glance, it's fine. But let's think about the problems:

\n\n
    \n
  • No severity levels. You can't distinguish a debug message from a critical error.
  • \n
  • No timestamps. When did this happen? Yesterday? A second ago?
  • \n
  • No context. Which thread? Which request? What data?
  • \n
  • Blocking output. std::endl flushes the buffer, killing performance in high-load systems.
  • \n
  • No rotation. The log file will grow indefinitely until it fills the entire disk.
  • \n
\n\n

In short, std::cout is only suitable for toy projects. Serious C++ production requires a serious approach to logging C++ applications.

\n\n

Spdlog: Your New Best Friend

\n\n

The spdlog library is the gold standard for logging in modern C++. It's fast (one of the fastest), header-only (no need to build), and incredibly flexible. Let's see how to set it up properly.

\n\n

Installation and Basic Setup

\n\n

Spdlog can be added via CMake FetchContent or by simply copying the headers. Here's a minimal production setup:

\n\n
#include <spdlog/spdlog.h>\n#include <spdlog/sinks/rotating_file_sink.h>\n#include <spdlog/sinks/stdout_color_sinks.h>\n#include <memory>\n\nvoid setup_logging() {\n    // Create a console logger with colored output\n    auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();\n    \n    // Create a file logger with rotation: 5 files of 10 MB each\n    auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(\n        "logs/myapp.log",  // file path\n        10 * 1024 * 1024,   // maximum file size: 10 MB\n        5                   // number of files for rotation\n    );\n\n    // Combine into a multi-threaded logger\n    auto logger = std::make_shared<spdlog::logger>(\n        "main_logger",\n        spdlog::sinks_init_list{console_sink, file_sink}\n    );\n\n    // Set the format: [time] [level] [logger_name] message\n    logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] [%n] %v");\n    \n    // Set the global logging level (can be changed at runtime)\n    logger->set_level(spdlog::level::info);\n    \n    // Register as the default logger\n    spdlog::set_default_logger(logger);\n}\n\nint main() {\n    setup_logging();\n    \n    spdlog::info("Application started. Version: {}", APP_VERSION);\n    spdlog::warn("Configuration not found, using default values");\n    \n    try {\n        // some code\n        throw std::runtime_error("Database connection error");\n    } catch (const std                

Blogs

Book Recommendations