Log#

Overview#

The Real-Time (RT) Logging library provides a high-performance, structured logging system built on top of the Quill logging library. It supports component-based and event-based logging with efficient runtime filtering, multiple log levels, and custom type formatting.

Key Features#

  • Component-based logging: Organize logs by functional components with individual log levels

  • Event-based logging: Track specific events throughout your application

  • High performance: Built on Quill’s asynchronous logging for minimal runtime overhead

  • Type safety: Compile-time enum validation and formatting

  • Custom types: Support for logging user-defined types with flexible formatting

  • Multiple outputs: Console, file, and rotating file logging

  • Thread safety: Safe for use in multi-threaded applications

Quick Start#

1. Include Required Headers#

#include "log/rt_log_macros.hpp"  // For logging macros
#include "log/components.hpp"     // For component/event declarations
#include "log/rt_log.hpp"         // For logger configuration

2. Define Your Components and Events#

// Define application components
DECLARE_LOG_COMPONENT(MyComponent, Core, Network, Database, Ui);

// Define system events
DECLARE_LOG_EVENT(MyEvent, AppStart, ConfigLoaded, UserAction);

3. Configure the Logger#

using namespace framework::log;

// Console logging with INFO level
Logger::configure(LoggerConfig::console(LogLevel::Info));

// Or file logging
Logger::configure(LoggerConfig::file("app.log", LogLevel::Debug));

4. Register Components#

using namespace framework::log;

// Set all components to DEBUG level
register_component<MyComponent>(LogLevel::Debug);

// Or set individual component levels
register_component<MyComponent>(
        {{MyComponent::Core, LogLevel::Info},
         {MyComponent::Network, LogLevel::Debug},
         {MyComponent::Database, LogLevel::Warn}});

5. Start Logging#

// Basic logging
RT_LOG_INFO("Application started");

// Component logging
RT_LOGC_INFO(MyComponent::Core, "Core system initialized");

// Event logging
RT_LOGE_INFO(MyEvent::AppStart, "Application startup completed");

// Combined component and event logging
RT_LOGEC_INFO(MyComponent::Core, MyEvent::ConfigLoaded, "Configuration loaded successfully");

Log Levels#

The framework supports multiple log levels in order of increasing severity:

Level

Use Case

TraceL3

Most verbose debugging

TraceL2

Detailed debugging

TraceL1

General debugging

Debug

Development debugging

Info

General information

Notice

Significant events

Warn

Warning conditions

Error

Error conditions

Critical

Critical failures

Log Level Filtering#

Messages are only logged if their level is greater than or equal to the configured level:

using namespace framework::log;

// Configure logger at INFO level
Logger::configure(LoggerConfig::file("app.log", LogLevel::Info));

RT_LOG_DEBUG("This won't appear"); // Below INFO level
RT_LOG_INFO("This will appear");   // INFO level
RT_LOG_WARN("This will appear");   // Above INFO level

Basic Logging Macros#

Standard Logging#

// Basic logging without components or events
RT_LOG_TRACE_L3("Entering function with param: {}", 42);
RT_LOG_TRACE_L2("Processing step {} of {}", 1, 10);
RT_LOG_TRACE_L1("Intermediate result: {}", "success");
RT_LOG_DEBUG("Debug information: {}", "debugging");
RT_LOG_INFO("Operation completed successfully");
RT_LOG_NOTICE("Important milestone reached");
RT_LOG_WARN("Deprecated function called: {}", "oldFunc");
RT_LOG_ERROR("Operation failed: {}", "connection timeout");
RT_LOG_CRITICAL("System in critical state: {}", "low memory");

Format String Support#

The logging macros support fmt-style format strings:

RT_LOG_INFO("User {} has {} credits remaining", "alice", 100);
RT_LOG_WARN("Memory usage at {:.1f}%", 85.7);
RT_LOG_ERROR("Failed after {} attempts in {:.2f}s", 3, 1.25);

Component-Based Logging#

Component-based logging allows you to organize log messages by functional areas of your application and control log levels independently for each component.

Declaring Components#

Use the DECLARE_LOG_COMPONENT macro to define your components:

DECLARE_LOG_COMPONENT(
        AppComponent,
        Core,       // Core functionality
        Network,    // Network operations
        Database,   // Database interactions
        Security,   // Security/authentication
        Ui,         // User interface
        FileSystem, // File operations
        Performance // Performance monitoring
);

Registering Components#

Before using component logging, register your components with desired log levels:

using namespace framework::log;

// Option 1: Set same level for all components
register_component<AppComponent>(LogLevel::Info);

// Option 2: Set individual levels
register_component<AppComponent>(
        {{AppComponent::Core, LogLevel::Info},
         {AppComponent::Network, LogLevel::Debug},
         {AppComponent::Database, LogLevel::Warn},
         {AppComponent::Security, LogLevel::Error}});

Component Logging Macros#

Use RT_LOGC_* macros for component-based logging:

// Log to specific components
RT_LOGC_DEBUG(MyComponent::Core, "Core subsystem initializing");
RT_LOGC_INFO(MyComponent::Network, "Connection established to server");
RT_LOGC_WARN(MyComponent::Database, "Query took longer than expected: {}ms", 500);
RT_LOGC_ERROR(MyComponent::Ui, "Failed to render component: {}", "NavBar");

Runtime Component Level Management#

using namespace framework::log;

// Query current component level
const LogLevel current_level = get_component_level<MyComponent>(MyComponent::Network);

// Dynamically change component levels
register_component<MyComponent>(
        {{MyComponent::Network, LogLevel::TraceL1}}); // Increase verbosity for debugging

Event-Based Logging#

Event-based logging tracks specific occurrences throughout your application lifecycle.

Declaring Events#

Define different types of events for your application:

// System lifecycle events
DECLARE_LOG_EVENT(
        SystemEventDoc,
        APP_START,
        APP_STOP,
        CONFIG_LOADED,
        CONFIG_ERROR,
        SHUTDOWN_REQUEST,
        HEALTH_CHECK_OK,
        RESOURCE_ALLOC);

// Error events
DECLARE_LOG_EVENT(
        ErrorEventDoc,
        INVALID_PARAM,
        NETWORK_ERROR,
        DATABASE_ERROR,
        AUTHENTICATION_FAILED,
        OPERATION_TIMEOUT);

Event Logging Macros#

Use RT_LOGE_* macros for event-based logging:

// Log specific events
RT_LOGE_INFO(SystemEventDoc::APP_START, "Application version 1.0.0 starting");
RT_LOGE_INFO(SystemEventDoc::CONFIG_LOADED, "Loaded configuration from config.yaml");
RT_LOGE_WARN(ErrorEventDoc::NETWORK_ERROR, "Retrying connection, attempt {}", 2);
RT_LOGE_ERROR(ErrorEventDoc::OPERATION_TIMEOUT, "Operation timed out after {}s", 30);

Combined Component and Event Logging#

For maximum context, combine both component and event information in your logs:

// Combine component and event for maximum context
RT_LOGEC_INFO(
        MyComponent::Core, SystemEventDoc::APP_START, "Core module initialized successfully");
RT_LOGEC_INFO(MyComponent::Network, SystemEventDoc::CONFIG_LOADED, "Network settings applied");
RT_LOGEC_WARN(
        MyComponent::Database,
        ErrorEventDoc::OPERATION_TIMEOUT,
        "Database query timeout on table: {}",
        "users");
RT_LOGEC_ERROR(
        MyComponent::Core,
        ErrorEventDoc::AUTHENTICATION_FAILED,
        "Authentication failed for user: {}",
        "admin");

This produces logs with both component and event context, providing maximum traceability for debugging and monitoring.

JSON Logging#

For structured logging, use JSON format macros:

// Basic JSON logging
RT_LOGJ_INFO("user_id", 12345, "action", "login", "timestamp", 1234567890);

// Component JSON logging with component as a key
RT_LOGJ_INFO(
        "component", "CORE", "event", "auth_success", "user", "alice", "ip", "192.168.1.1");

Custom Type Logging#

Making Types Loggable#

To log custom types, use the RT_LOGGABLE_* macros.

// Simple user-defined struct for logging demonstration
struct Product {
    std::string name;            //!< Product name
    double price;                //!< Product price in dollars
    std::vector<int> quantities; //!< Available quantities per size/variant

    /**
     * Create a new product with specified details
     *
     * @param[in] product_name Name of the product
     * @param[in] product_price Price in dollars
     * @param[in] product_quantities Available quantities for different variants
     */
    Product(std::string product_name, double product_price, std::vector<int> product_quantities)
            : name(std::move(product_name)), price(product_price),
              quantities(std::move(product_quantities)) {}
};

Register the struct with the logging framework using RT_LOGGABLE_DEFERRED_FORMAT:

RT_LOGGABLE_DEFERRED_FORMAT(
        Product,
        "Product{{ name: '{}', price: ${:.2f}, quantities: {} }}",
        obj.name,
        obj.price,
        obj.quantities)

The above example shows a struct with value types using RT_LOGGABLE_DEFERRED_FORMAT. For types containing pointers or references, use RT_LOGGABLE_DIRECT_FORMAT:

struct DocUser {
    std::string name;
    uint64_t *session_ptr; // Contains pointer - not safe for async
    std::vector<std::string> roles;
    std::chrono::time_point<std::chrono::system_clock> last_login;
};

// For types with pointers/references (immediate formatting)
RT_LOGGABLE_DIRECT_FORMAT(
        DocUser,
        "name: '{}', session_id: {}, roles: {}, last_login: {}",
        obj.name,
        obj.session_ptr ? *obj.session_ptr : 0,           // Conditional pointer access
        obj.roles.size(),                                 // Function call
        std::chrono::duration_cast<std::chrono::seconds>( // Complex computation
                obj.last_login.time_since_epoch())
                .count());

Advanced Formatting Examples#

The formatting expressions can include complex C++ code:

struct NetworkConnection {
    std::string host;
    uint16_t port;
    bool is_encrypted;
    std::optional<std::string> proxy;
    std::chrono::milliseconds latency;
};

RT_LOGGABLE_DEFERRED_FORMAT(
        NetworkConnection,
        "{}://{}:{} (latency: {}ms, proxy: {})",
        obj.is_encrypted ? "https" : "http", // Conditional protocol
        obj.host,
        obj.port,
        obj.latency.count(),         // Method call
        obj.proxy.value_or("none")); // Optional handling

struct DataBuffer {
    std::vector<uint8_t> data;
    std::size_t valid_bytes;
    bool is_compressed;
};

RT_LOGGABLE_DEFERRED_FORMAT(
        DataBuffer,
        "size: {}/{} bytes, compressed: {}, checksum: 0x{:x}",
        obj.valid_bytes,
        obj.data.size(),
        obj.is_compressed,
        std::accumulate(
                obj.data.begin(), // Complex computation
                obj.data.begin() + static_cast<std::ptrdiff_t>(obj.valid_bytes),
                0U,
                std::bit_xor<uint8_t>{})); // Custom checksum

What Can You Use in Formatting Expressions?#

The RT_LOGGABLE_* macros accept any valid C++ expressions that can be evaluated with the object instance (obj):

Expression Type

Example

Simple member access

obj.name

Conditional expressions

obj.ptr ? *obj.ptr : 0

Method calls

obj.size(), obj.empty()

Free function calls

std::to_string(obj.id)

Mathematical operations

obj.width * obj.height

Standard library algorithms

std::max(obj.a, obj.b)

Type conversions

static_cast<int>(obj.value)

Nested member access

obj.config.timeout.count()

Container operations

obj.items.size(), obj.map.empty()

Full Example#

Here’s an example with multiple expression types:

struct HttpRequest {
    std::string method;
    std::string url;
    std::map<std::string, std::string> headers;
    std::vector<uint8_t> body;
    std::chrono::steady_clock::time_point received_at;
    std::optional<std::string> user_agent;
};

RT_LOGGABLE_DEFERRED_FORMAT(
        HttpRequest,
        "{} {} | headers: {} | body: {} bytes | user-agent: {} | age: {}ms",
        obj.method,
        obj.url,
        obj.headers.size(),
        obj.body.size(),
        obj.user_agent.value_or("unknown"),
        std::chrono::duration_cast<std::chrono::milliseconds>(
                std::chrono::steady_clock::now() - obj.received_at)
                .count());

Using Custom Types in Logs#

Once a type is registered with RT_LOGGABLE_* macros, you can log it directly:

const Product laptop{"Gaming Laptop", 1299.99, {5, 3, 8}};
const Product mouse{"Wireless Mouse", 29.99, {50, 25}};

RT_LOG_INFO("Inventory item: {}", laptop);
RT_LOG_WARN("Low stock alert: {}", mouse);
RT_LOGC_INFO(AppComponent::Database, "Updated inventory: {}", laptop);

// Demonstrate product-related events
RT_LOGE_INFO(AppSystemEvent::ProductCreated, "New product added: {}", laptop.name);
RT_LOGEC_WARN(
        AppComponent::Inventory,
        AppErrorEvent::InventoryLow,
        "Low stock for product: {}",
        mouse);

Choosing Format Types#

  • RT_LOGGABLE_DEFERRED_FORMAT: Use for types containing only value types (primitives, strings, containers of value types). The object is copied and formatted asynchronously in a background thread for better performance.

  • RT_LOGGABLE_DIRECT_FORMAT: Use for types containing pointers or C++ references. The object is formatted immediately in the calling thread before the pointer could become invalid.

Important

Any type containing a pointer must use RT_LOGGABLE_DIRECT_FORMAT to avoid dangling pointer issues. If you defer formatting, the pointer may point to invalid memory by the time formatting occurs.

Container Logging#

Standard C++ containers (std::vector, std::array, etc.) are directly loggable without any special setup:

// Standard containers are directly loggable
const std::vector<int> numbers{1, 2, 3, 4, 5};
RT_LOG_INFO("Vector of ints: {}", numbers);

const std::vector<std::string> names{"Alice", "Bob", "Charlie"};
RT_LOG_INFO("Vector of strings: {}", names);

// Arrays can be logged via std::span
const std::array<int, 3> coords{10, 20, 30};
RT_LOG_INFO("Array as span: {}", std::span{coords});

// Works with component and event logging too
RT_LOGC_INFO(MyComponent::Core, "Config values: {}", numbers);

Containers work seamlessly with all logging macros (RT_LOG_*, RT_LOGC_*, RT_LOGE_*, RT_LOGEC_*).

Logger Configuration#

Console Logging#

using namespace framework::log;

// Basic console logging
Logger::configure(LoggerConfig::console(LogLevel::Info));

// Console with colors enabled
Logger::configure(LoggerConfig::console(LogLevel::Debug).with_colors(true));

// Console with timestamps
Logger::configure(LoggerConfig::console(LogLevel::Info).with_timestamps(true));

File Logging#

using namespace framework::log;

// Basic file logging
Logger::configure(LoggerConfig::file("app.log", LogLevel::Debug));

// File logging with timestamps
Logger::configure(LoggerConfig::file("app.log", LogLevel::Info).with_timestamps(true));

// File logging with file/line info
Logger::configure(LoggerConfig::file("app.log", LogLevel::Debug).with_file_line(true));

Rotating File Logging#

using namespace framework::log;

// Rotating files (good for long-running applications)
Logger::configure(LoggerConfig::rotating_file("app.log", LogLevel::Info)
                          .with_timestamps(true)
                          .with_file_line(false));

Flushing Logs#

Ensure all logs are written before application exit:

using namespace framework::log;

// Flush all pending log messages
Logger::flush();

// Get actual log file path (useful for rotating logs)
const std::string actual_file = Logger::get_actual_log_file();

Best Practices#

1. Component Level Management#

using namespace framework::log;

// Production: Conservative levels
register_component<MyComponent>(
        {{MyComponent::Core, LogLevel::Info},
         {MyComponent::Database, LogLevel::Warn},
         {MyComponent::Ui, LogLevel::Notice}});

// Development: Verbose levels
register_component<MyComponent>(LogLevel::Debug);

// Debugging specific issues
register_component<MyComponent>({
        {MyComponent::Network, LogLevel::TraceL1} // Focus on network issues
});

2. Meaningful Log Messages#

// Good: Informative and actionable
RT_LOGC_ERROR(
        MyComponent::Database,
        "Connection failed after {} retries to {}:{}",
        retry_count,
        host,
        port);

RT_LOGE_WARN(
        MyEvent::ConfigLoaded,
        "Missing config key '{}', using default: {}",
        key,
        default_value);

3. Error Context#

// Include relevant context in error messages
RT_LOGEC_ERROR(
        MyComponent::Network,
        ErrorEvent::NETWORK_ERROR,
        "Failed to connect to {}:{} after {}ms (attempt {} of {})",
        host,
        port,
        elapsed_ms,
        attempt,
        max_attempts);

Performance Considerations#

1. Asynchronous Logging#

The framework uses Quill’s asynchronous logging by default, which provides:

  • Minimal impact on application performance

  • Non-blocking log calls in most cases

  • Background thread handles actual I/O

  • Component level filtering is built into the logging macros (no manual checks needed)

2. Deferred vs Direct Formatting#

struct SafeType {
    int value;
};
RT_LOGGABLE_DEFERRED_FORMAT(SafeType, "value: {}", obj.value);

struct UnsafeType {
    int *ptr;
};
RT_LOGGABLE_DIRECT_FORMAT(UnsafeType, "ptr: {}", obj.ptr ? *obj.ptr : 0);

3. Avoiding Common Pitfalls#

// Good: Let the logger handle formatting
RT_LOG_INFO("Processing item {}", item_id);

// Avoid: Pre-formatting strings unnecessarily
// std::string msg = std::format("Processing item {}", item_id);  // Waste!
// RT_LOG_INFO("{}", msg);

// Good: Use direct values
RT_LOGC_DEBUG(MyComponent::Network, "Bytes sent: {}", bytes_sent);

// Avoid: Expensive conversions
// RT_LOGC_DEBUG(MyComponent::Network, "Bytes sent: {}", std::to_string(bytes_sent));

For more examples, see:

  • framework/log/samples/rt_log_sample.cpp - Complete usage examples

  • framework/log/tests/rt_log_tests.cpp - Unit tests with various scenarios

API Reference#

Complete C++ API documentation for the Real-Time Logging framework.

enum class framework::log::LogLevel#

Core log levels for the logging framework

Defines severity levels from most verbose (TRACE_L3) to most critical (CRITICAL). Used by both logger and component systems for filtering log messages.

Values:

enumerator TraceL3#

Most verbose trace level.

enumerator TraceL2#

Medium trace level.

enumerator TraceL1#

Least verbose trace level.

enumerator Debug#

Debug messages.

enumerator Info#

Informational messages.

enumerator Notice#

Notice messages.

enumerator Warn#

Warning messages.

enumerator Error#

Error messages.

enumerator Critical#

Critical error messages.

enum class framework::log::SinkType#

Supported sink types for log output destinations

Defines the various output destinations available for log messages, including console, file-based, and JSON format options.

Values:

enumerator Console#

Console output.

enumerator File#

File output.

enumerator RotatingFile#

Rotating file output.

enumerator JsonFile#

JSON file output.

enumerator JsonConsole#

JSON console output.

enumerator RotatingJsonFile#

Rotating JSON file output.

template<typename ComponentType>
using framework::log::ComponentRegistry = EnumRegistry<ComponentType>#

Component registry type alias for enum-based components

Template Parameters:

ComponentType – Component enum type

template<typename EventType>
using framework::log::EventRegistry = EnumRegistry<EventType>#

Event registry type alias for enum-based events

Template Parameters:

EventType – Event enum type

using framework::log::RealTimeFrontend = quill::FrontendImpl<RealTimeFrontendOptions>#

Real-time frontend implementation alias

Specialized frontend implementation using the real-time options for optimal logging throughput in production environments.

using framework::log::RealTimeLogger = quill::LoggerImpl<RealTimeFrontendOptions>#

Real-time logger implementation alias

Specialized logger implementation using the real-time frontend options for optimal logging performance.

LogLevel framework::log::get_logger_default_level()#

Get the default log level for new components

Returns:

Default log level (INFO)

template<typename ComponentType>
constexpr std::string_view framework::log::format_component_name(
ComponentType component,
)#

Get string representation of component name

Template Parameters:

ComponentType – Component enum type

Parameters:

component[in] Component enum value

Returns:

String view of component name

template<typename ComponentType>
constexpr bool framework::log::is_valid_component(
ComponentType component,
)#

Check if component value is valid

Template Parameters:

ComponentType – Component enum type

Parameters:

component[in] Component enum value to validate

Returns:

true if component is within valid range

template<typename ComponentType>
void framework::log::register_component(
const std::unordered_map<ComponentType, LogLevel> &component_levels,
)#

Register components with individual log levels

Template Parameters:

ComponentType – Component enum type

Parameters:

component_levels[in] Map of components to their log levels

template<typename ComponentType>
void framework::log::register_component(
LogLevel level,
)#

Register all components with the same log level

Template Parameters:

ComponentType – Component enum type

Parameters:

level[in] Log level to assign to all components

template<typename ComponentType>
LogLevel framework::log::get_component_level(
ComponentType component,
)#

Get the current log level for a specific component

Template Parameters:

ComponentType – Component enum type

Parameters:

component[in] Component to query

Returns:

Current log level for the component

template<typename EventType>
constexpr std::string_view framework::log::format_event_name(
EventType event,
)#

Get string representation of event name

Template Parameters:

EventType – Event enum type

Parameters:

event[in] Event enum value

Returns:

String view of event name

template<typename EventType>
constexpr bool framework::log::is_valid_event(
EventType event,
)#

Check if event value is valid

Template Parameters:

EventType – Event enum type

Parameters:

event[in] Event enum value to validate

Returns:

true if event is within valid range

std::string framework::log::read_file_contents(
const std::string &filepath,
)#

Read the contents of a file.

Parameters:

filepath – Path to the file to read

Returns:

File contents as a string

bool framework::log::file_contains(
const std::string &filepath,
const std::string &search_text,
)#

Check if a file contains the specified text.

Parameters:
  • filepath – Path to the file to check

  • search_text – Text to search for

Returns:

true if the text is found, false otherwise

bool framework::log::file_contains_all(
const std::string &filepath,
const std::vector<std::string> &search_texts,
)#

Check if a file contains all specified texts.

Parameters:
  • filepath – Path to the file to check

  • search_texts – Vector of texts to search for

Returns:

true if all texts are found, false otherwise

template<typename ComponentType>
class ComponentLevelStorage#
#include <components.hpp>

Component level storage with efficient access patterns

Manages per-component log levels using direct array indexing for maximum performance in logging hot paths.

Template Parameters:

ComponentType – The component enum type

Public Static Functions

static inline void initialize()#

Initialize the component level storage with default levels

static inline LogLevel get_level(ComponentType component)#

Get the current log level for a component

Parameters:

component[in] Component to query

Returns:

Current log level for the component

static inline void set_level(ComponentType component, LogLevel level)#

Set log level for a specific component

Parameters:
  • component[in] Component to configure

  • level[in] New log level for the component

static inline bool should_log(
ComponentType component,
LogLevel message_level,
)#

Check if a message should be logged for a component

Parameters:
  • component[in] Component being logged to

  • message_level[in] Log level of the message

Returns:

true if message should be logged

static inline void set_all_levels(LogLevel level)#

Set the same log level for all components

Parameters:

level[in] Log level to apply to all components

template<typename EnumType>
struct EnumRegistry#
#include <components.hpp>

Generic registry template for contiguous enum types

Provides O(1) lookup operations for enum name resolution and validation using compile-time generated lookup tables from wise_enum data.

Note

Requires enum values to be contiguous starting from 0

Template Parameters:

EnumType – The enum type to create registry for

Public Static Functions

static inline constexpr size_t get_table_size()#

Get the number of enum values

Returns:

Number of enum values in the registry

static inline constexpr std::string_view get_name(
const EnumType value,
)#

Get string name for enum value

Parameters:

value[in] Enum value to get name for

Returns:

String view of enum name, or “UNKNOWN” if invalid

static inline constexpr bool is_valid(const EnumType value)#

Check if enum value is valid

Parameters:

value[in] Enum value to validate

Returns:

true if value is within valid range

static inline constexpr size_t get_index(const EnumType value)#

Get array idx for enum value

Parameters:

value[in] Enum value

Returns:

Array idx for the enum value

class Logger#
#include <rt_log.hpp>

Main logger class providing real-time logging functionality

Singleton logger implementation that wraps Quill’s real-time logging library with a simplified interface and component-based log level management.

Public Functions

~Logger() noexcept#

Destructor - public so unique_ptr can call it

Logger(const Logger&) = delete#
Logger &operator=(const Logger&) = delete#
Logger(Logger&&) = delete#
Logger &operator=(Logger&&) = delete#

Public Static Functions

static void configure(const LoggerConfig &config)#

Configure the default logger with clean config struct

Warning

This method is NOT real-time safe. It performs internal locking to ensure thread-safe Logger configuration and should only be called during application initialization, never from real-time threads.

Parameters:

config[in] Logger configuration containing all setup options

static void set_level(LogLevel level)#

Set the global log level for the default logger

Parameters:

level[in] New log level to set

static void flush()#

Flush all pending log messages immediately

static SinkType get_sink_type()#

Get the current sink type of the logger

Returns:

Currently configured sink type

static LogLevel get_current_level()#

Get the current global log level

Returns:

Current global log level

static std::string get_actual_log_file()#

Get the actual log file path being used

Returns:

Path to the log file, or empty string if not using file output

struct LoggerConfig#
#include <rt_log.hpp>

Configuration structure for logger initialization

Contains all configurable options for setting up the logging system, including sink type, output formatting, performance tuning, and backend thread configuration.

Public Functions

LoggerConfig &with_file_line(bool enable = true)#

Enable file and line information in logs

Parameters:

enable[in] Whether to enable file and line information

Returns:

Reference to this config for method chaining

LoggerConfig &with_caller(bool enable = true)#

Enable caller function information in logs

Parameters:

enable[in] Whether to enable caller function information

Returns:

Reference to this config for method chaining

LoggerConfig &with_timestamps(bool enable = true)#

Enable or disable timestamps in log output

Parameters:

enable[in] Whether to enable timestamps

Returns:

Reference to this config for method chaining

LoggerConfig &with_log_level(bool enable = true)#

Enable or disable log level display in log output

Parameters:

enable[in] Whether to enable log level display

Returns:

Reference to this config for method chaining

LoggerConfig &with_thread_name(bool enable = true)#

Enable or disable thread name display in log output

Parameters:

enable[in] Whether to enable thread name display

Returns:

Reference to this config for method chaining

LoggerConfig &with_colors(bool enable = true)#

Enable or disable colors in console output

Parameters:

enable[in] Whether to enable color output

Returns:

Reference to this config for method chaining

LoggerConfig &with_backend_sleep_duration(
std::chrono::nanoseconds duration,
)#

Set backend thread sleep duration for performance tuning

Parameters:

duration[in] Sleep duration for the backend thread

Returns:

Reference to this config for method chaining

LoggerConfig &with_cpu_affinity(uint16_t cpu)#

Set CPU affinity for backend thread

Parameters:

cpu[in] CPU core to bind the backend thread to

Returns:

Reference to this config for method chaining

Public Members

SinkType sink_type = {SinkType::Console}#

Type of log output sink to use.

const char *log_file = {nullptr}#

Path to log file (for file-based sinks)

LogLevel min_level = {LogLevel::Info}#

Minimum log level to process.

bool enable_colors = {true}#

Enable color output for console sinks.

bool enable_file_line = {true}#

Include file and line number in log output.

bool enable_caller = {false}#

Include calling function name in log output.

bool enable_timestamps = {true}#

Include timestamps in log output.

bool enable_log_level = {true}#

Include log level in log output.

bool enable_thread_name = {true}#

Include thread name in log output.

std::chrono::nanoseconds backend_sleep_duration{std::chrono::nanoseconds{DEFAULT_BACKEND_SLEEP_NS}}#

Backend thread sleep duration for performance tuning

uint16_t backend_cpu_affinity = {std::numeric_limits<uint16_t>::max()}#

CPU affinity for backend thread

Public Static Functions

static LoggerConfig console(
LogLevel level = LogLevel::Info,
bool colors = true,
)#

Create console logger configuration (default)

Parameters:
  • level[in] Minimum log level to process

  • colors[in] Enable color output

Returns:

LoggerConfig configured for console output

static LoggerConfig file(
const char *path,
LogLevel level = LogLevel::Info,
)#

Create file logger configuration

Parameters:
  • path[in] Path to the log file

  • level[in] Minimum log level to process

Returns:

LoggerConfig configured for file output

static LoggerConfig rotating_file(
const char *path,
LogLevel level = LogLevel::Info,
)#

Create rotating file logger configuration

Parameters:
  • path[in] Path to the log file

  • level[in] Minimum log level to process

Returns:

LoggerConfig configured for rotating file output

static LoggerConfig json_file(
const char *path,
LogLevel level = LogLevel::Info,
)#

Create JSON file logger configuration

Parameters:
  • path[in] Path to the JSON log file

  • level[in] Minimum log level to process

Returns:

LoggerConfig configured for JSON file output

static LoggerConfig json_console(LogLevel level = LogLevel::Info)#

Create JSON console logger configuration

Parameters:

level[in] Minimum log level to process

Returns:

LoggerConfig configured for JSON console output

static LoggerConfig rotating_json_file(
const char *path,
LogLevel level = LogLevel::Info,
)#

Create rotating JSON file logger configuration

Parameters:
  • path[in] Path to the rotating JSON log file

  • level[in] Minimum log level to process

Returns:

LoggerConfig configured for rotating JSON file output

Public Static Attributes

static constexpr int DEFAULT_BACKEND_SLEEP_NS = 100#

Default backend thread sleep duration in nanoseconds.

struct RealTimeFrontendOptions#
#include <rt_log.hpp>

Custom frontend options optimized for real-time logging

Configures the Quill frontend with settings optimized for high-throughput logging scenarios with bounded dropping queues and larger initial capacity.

Public Static Attributes

static constexpr quill::QueueType queue_type = quill::QueueType::BoundedDropping#

Use bounded dropping queue for high performance

static constexpr uint32_t initial_queue_capacity = 8 * 1024 * 1024#

8 MB initial capacity (vs default 128KB)

static constexpr uint32_t blocking_queue_retry_interval_ns = 0#

No retry interval for blocking operations.

static constexpr size_t unbounded_queue_max_capacity = 0#

No unbounded queue limit.

static constexpr quill::HugePagesPolicy huge_pages_policy = quill::HugePagesPolicy::Never#

Disable huge pages for compatibility.

class TempFileManager#
#include <temp_file.hpp>

RAII utility for managing temporary files in tests.

Creates temporary files with unique names and automatically cleans them up when the object is destroyed. Each instance is independent with its own naming. Thread-safe for concurrent calls to get_temp_file().

Public Functions

explicit TempFileManager(std::string prefix = "rt_log_test")#

Create a temporary file manager.

Parameters:

prefix – Prefix for temporary file names

~TempFileManager()#

Destructor - cleans up all temporary files.

TempFileManager(const TempFileManager&) = delete#
TempFileManager &operator=(const TempFileManager&) = delete#
TempFileManager(TempFileManager&&) = delete#
TempFileManager &operator=(TempFileManager&&) = delete#
std::string get_temp_file(const std::string &suffix = "")#

Get a unique temporary file path.

Parameters:

suffix – Optional suffix to append to the file name

Returns:

Full path to the temporary file