Skip to content
nircoePublic

About

A small C++ logging library

Topics

Resources

Contributing

Stars

0 stars

Watchers

1 watching

Forks

Latest commit

 

History

19 Commits

Folders and files

Repository files navigation

logcoe

Thread-safe C++ logging library with console and file output and a configurable time format.

Windows Linux macOS

What is logcoe?

logcoe is a small thread-safe C++ logging library. It writes to the console, to a file or to both:

[06/07/2025__14:30:25] [INFO]: Application started successfully
[06/07/2025__14:30:25] [DEBUG] [NetworkManager]: Connecting to server 192.168.1.100
[06/07/2025__14:30:26] [WARNING] [Database]: Connection timeout, retrying...
[06/07/2025__14:30:27] [ERROR] [FileSystem]: Failed to open configuration file

Dependencies

No third-party libraries. Building the tests fetches testcoe from source. Toolchain versions are under Requirements.

Quick Start

1. Add to your project (CMake)

include(FetchContent)
FetchContent_Declare(
    logcoe
    GIT_REPOSITORY https://github.com/nircoe/logcoe.git
    GIT_TAG v0.1.1
)
FetchContent_MakeAvailable(logcoe)

target_link_libraries(your_target PRIVATE logcoe)

Linking logcoe turns on C++23 for your_target, so you don't have to set CMAKE_CXX_STANDARD yourself.

2. Use in your application

#include <logcoe.hpp>

int main()
{
    // Initialize with INFO level, no default source (empty string), console enabled, file disabled
    // logs will be printed as [timestamp] [log_level]: <log_message>
    logcoe::initialize(logcoe::log_level::info, std::string{}, true, false);

    logcoe::info("Application started");
    logcoe::infof("Loaded {} files in {} ms", 12, 340);
    logcoe::warning("This is a warning message");
    logcoe::error("Critical error occurred", "ErrorHandler");

    logcoe::shutdown();
    return 0;
}

3. Advanced configuration

#include <logcoe.hpp>
#include <fstream>

int main()
{
    // Enable both console and file output with DEBUG level and default source as logcoe
    // logs will be printed as [timestamp] [log_level] [logcoe]: <log_message>
    logcoe::initialize(logcoe::log_level::debug, "logcoe", true, true, "app.log");

    // Customize time format
    if (!logcoe::set_time_format("%H:%M:%S"))
        return 1;

    // Log with source information
    logcoe::debug("Debugging network connection", "NetworkModule");
    logcoe::info("User logged in successfully", "AuthSystem");

    // Redirect console to custom stream
    std::ofstream custom_log("custom.log");
    logcoe::set_console_output(custom_log);

    // Change log level at runtime
    logcoe::set_log_level(logcoe::log_level::warning);

    logcoe::shutdown();
    return 0;
}

Features

  • Thread-safe, one mutex guards every call
  • Log levels debug, info, warning and error, filtered at runtime
  • Console and file output at the same time
  • Log level, console stream, log file and time format can change at runtime
  • One public header, built as a static library
  • Windows, Linux and macOS
  • Compiles to no-op stubs in Release builds, see Release Builds

API Reference

All functions are declared in include/logcoe.hpp, with their default arguments.

  • initialize can be called more than once. Later calls ignore their arguments and only raise a counter. Logging stops after the matching number of shutdown calls.
  • The logging functions and the setters do nothing before initialize.
  • The logging functions take an optional source and a flush flag (default true). A message logged with flush==false may stay in the stream buffer until the next logcoe::flush() or shutdown(). logcoe::flush() flushes the console and file outputs.
  • debugf, infof, warningf and errorf take a std::format string and arguments. std::format_string checks the format string at compile time, so a bad one does not build. A message below the log level is not formatted. They use the default source and flush==true. To pass a source or flush, format the message yourself and call the plain function. A std::formatter that throws propagates out of the call.
  • The public header includes <format>.
  • set_file_output and set_time_format return std::expected<void, logcoe::error_reason>.
  • set_file_output, set_time_format, is_initialized and get_log_level are [[nodiscard]].
  • error_reason is file_open_failure, invalid_time_format or not_initialized. Both functions return not_initialized when called before initialize.
  • Time formats use strftime syntax.

Log Levels

Level Value Description
debug 0 Detailed diagnostic information
info 1 General application information
warning 2 Warning conditions that should be noted
error 3 Error conditions that affect functionality
none 4 Disable all logging

Thread Safety

All functions can be called from any thread. A single mutex is held for the whole of each call, see Architecture.

Requirements

  • Compiler: C++23 with <expected> and <format> (GCC 13+, Clang 17+ with libc++, Apple Clang from Xcode 15.3+, MSVC 2022 17.3+)
  • Build system: CMake 3.22+
  • Platforms: Windows, Linux, macOS

Release Builds

Defining NDEBUG (for example -DCMAKE_BUILD_TYPE=Release) replaces every function with a no-op stub at compile time. Call sites compile unchanged, but nothing is logged, formatted or written to a file:

  • initialize, debug/info/warning/error, flush, shutdown and the other setters do nothing. debugf/infof/warningf/errorf return early because get_log_level() is none, so they do not format.
  • is_initialized() returns false.
  • get_log_level() returns log_level::none.
  • set_file_output(...) returns success and never creates a file.
  • set_time_format(...) returns success.

This is automatic whenever NDEBUG is defined, no option is needed. It includes RelWithDebInfo and MinSizeRel, because CMake defines NDEBUG for those build types too.

Documentation

License

MIT License, see LICENSE.

About

A small C++ logging library

Topics

Resources

Contributing

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages