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 |
|---|---|
|
Most verbose debugging |
|
Detailed debugging |
|
General debugging |
|
Development debugging |
|
General information |
|
Significant events |
|
Warning conditions |
|
Error conditions |
|
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 |
|
Conditional expressions |
|
Method calls |
|
Free function calls |
|
Mathematical operations |
|
Standard library algorithms |
|
Type conversions |
|
Nested member access |
|
Container operations |
|
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 examplesframework/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.
-
enumerator TraceL3#
-
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.
-
enumerator Console#
-
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
-
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
-
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
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
-
~Logger() noexcept#
-
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
-
const char *log_file = {nullptr}#
Path to log file (for file-based sinks)
-
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( )#
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( )#
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( )#
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( )#
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( )#
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.
-
LoggerConfig &with_file_line(bool enable = true)#
-
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.
-
static constexpr quill::QueueType queue_type = quill::QueueType::BoundedDropping#
-
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
-
explicit TempFileManager(std::string prefix = "rt_log_test")#