DEV Community

Cover image for GoodLog: A Lightweight C++17 Wrapper Around Boost.Log
SoleyRan
SoleyRan

Posted on

GoodLog: A Lightweight C++17 Wrapper Around Boost.Log

I recently cleaned up and published a small C++ logging component called GoodLog.

It is not meant to replace full logging frameworks. Instead, it wraps the parts of Boost.Log that I kept reusing in C++ projects: colored console output, rotating log files, severity filtering, source location, and hex dump helpers for binary buffers.

GitHub:

https://github.com/SoleyRan/Log

Why I Built It

Boost.Log is powerful, but setting it up repeatedly can get verbose.

In many C++ modules, I usually want the same basic behavior:

  • write readable logs to the terminal
  • keep rotated log files on disk
  • filter console and file output separately
  • include the source file and line number
  • dump binary buffers while debugging protocols or middleware messages

The application code should stay simple:

goodlog::logInit("/tmp/goodlog/", 2, 1, 10, 10);

LOG_Debug() << "debug details";
LOG_Info()  << "service started";
LOG_Warn()  << "using fallback config";
LOG_Error() << "connection failed";
Enter fullscreen mode Exit fullscreen mode

GoodLog is my attempt to keep Boost.Log as the backend while exposing a smaller interface for everyday use.

What GoodLog Supports

Currently, GoodLog provides:

  • C++17
  • Boost.Log based implementation
  • trace, debug, info, warning, error, and fatal levels
  • automatic file:line source location
  • colored terminal output
  • rotating file sink
  • separate severity thresholds for console and file logs
  • optional channel filtering
  • hex dump helpers for binary buffers
  • CMake build
  • demo and GoogleTest entry points

Here is a terminal preview:

Quick Start

git clone https://github.com/SoleyRan/Log.git
cd Log
cmake -S . -B build
cmake --build build
./build/demo/log_demo
Enter fullscreen mode Exit fullscreen mode

By default, the demo writes rotated log files under:

/tmp/goodlog/
Enter fullscreen mode Exit fullscreen mode

Basic Usage

#include <log.hpp>

int main()
{
    const std::string log_path = "/tmp/goodlog/";
    const int console_log_level = 2; // info and above
    const int file_log_level = 1;    // debug and above
    const int max_log_size_mb = 10;
    const int max_log_files = 10;

    goodlog::logInit(
        log_path,
        console_log_level,
        file_log_level,
        max_log_size_mb,
        max_log_files
    );

    LOG_Debug() << "debug details";
    LOG_Info()  << "service started";
    LOG_Warn()  << "using fallback config";
    LOG_Error() << "connection failed";
    LOG_Fatal() << "unrecoverable error";

    return 0;
}
Enter fullscreen mode Exit fullscreen mode

Output Format

GoodLog formats each record with timestamp, severity, source location, and message:

[2026-05-02 10:24:18.123456]<info>[main.cpp:18]:service started
[2026-05-02 10:24:18.123789]<warning>[main.cpp:19]:using fallback config
[2026-05-02 10:24:18.124000]<error>[main.cpp:20]:connection failed
Enter fullscreen mode Exit fullscreen mode

Log files use a sortable counter and timestamp pattern:

00000-2026-05-02-10-24-18.log
00001-2026-05-02-10-27-42.log
Enter fullscreen mode Exit fullscreen mode

Severity Configuration

console_log_level and file_log_level control the minimum severity for terminal output and file output.

Value Severity
0 trace
1 debug
2 info
3 warning
4 error
5 fatal

For example:

goodlog::logInit("/tmp/goodlog/", 2, 1, 10, 10);
Enter fullscreen mode Exit fullscreen mode

This means:

  • console output keeps info and above
  • file output keeps debug and above
  • each log file can grow up to 10 MB
  • up to 10 log files are retained

This keeps terminal output relatively clean while preserving more details in files.

Hex Dump Helpers

GoodLog also includes helpers for inspecting binary data.

This is useful when debugging network packets, sensor data, custom protocols, or middleware messages.

std::array<unsigned char, 4> payload = {0x12, 0x34, 0xab, 0xcd};

LOG_DEBUG_HEX(payload.data(), payload.size(), "rx payload");
Enter fullscreen mode Exit fullscreen mode

Why Keep Boost.Log Underneath?

I did not want to reimplement a logging system from scratch.

Boost.Log already has a mature model for sinks, formatters, severities, asynchronous logging, and file backends. GoodLog is more of a practical wrapper: it keeps the backend and makes the common setup easier to reuse.

When It Might Be Useful

GoodLog may be useful for:

  • C++ services
  • middleware modules
  • robotics or autonomous-driving related tools
  • debugging-heavy native applications
  • projects that already depend on Boost
  • applications that inspect binary protocols or sensor data

If you need a dependency-free logger, a package-manager-ready public library, or a fully hardened production logging framework, GoodLog still needs more work.

Project Layout

.
|-- CMakeLists.txt
|-- demo/
|   `-- log_demo.cpp
|-- src/
|   |-- log.hpp
|   |-- text_file_backend_self_defined.cpp
|   `-- text_file_backend_self_defined.hpp
`-- test/
    `-- log_test.cpp
Enter fullscreen mode Exit fullscreen mode

Roadmap

Next steps I want to improve:

  • better CMake install/export targets
  • Ubuntu CI
  • more complete integration examples
  • channel macro namespace cleanup
  • more tests

GitHub

https://github.com/SoleyRan/Log

Feedback on the macro API, CMake integration, and channel logging interface would be very welcome.

Top comments (0)