Scope Logging¶
How RAII Scope Logging Works¶
siddiqsoft::ScopeTrace uses the C++ RAII pattern to measure scope execution duration and emit trace logs upon scope entry and exit.
#include <siddiqsoft/ScopeTrace.hpp>
void compute()
{
// Obtain process-wide root ScopeTrace instance ("compute")
auto& scope = siddiqsoft::ScopeTrace::GetInstance("compute");
// Explicit nested scope ("compute/stage1")
auto sub = scope.sub_scope("stage1");
sub.info("Processing stage 1 payload...");
} // Destructors automatically log completion status and elapsed duration at LogLevel::debug severity upon scope exit
Source Location & Function Name Extraction¶
Using std::source_location::current(), ScopeTrace captures caller details automatically upon construction:
- Source file path (m_location.file_name())
- Line number (m_location.line())
- Enclosing function signature (m_location.function_name())
ScopeTrace also includes internal protected helper routines (extract_file_name(), extract_func_name(), function_name()) to extract clean plain file names (e.g. "main.cpp") and function names matching __func__ from full signature strings.
Nesting Depth & ISO 8601 Timestamps¶
ScopeTrace tracks nested scope depth strictly by parentage (child.depth() = parent.depth() + 1), producing formatted visual indentation for hierarchical log trees. Each output line is prefixed with an ISO 8601 UTC timestamp:
Dynamic Log Level Filtering¶
Each ScopeTrace instance maintains a configurable log level threshold (LogLevel / trace_level, defaulted to LogLevel::none). You can set the threshold at instance acquisition or dynamically update it via set_level():
// Set logging threshold to debug at instance acquisition
auto& scope = siddiqsoft::ScopeTrace::GetInstance("compute", siddiqsoft::LogLevel::debug);
// Dynamically change logging threshold
scope.set_level(siddiqsoft::LogLevel::trace);
Filtering Rules¶
- Always Logged: Messages logged with
critical,exception, orerrorlevel are always output regardless ofm_log_level. LogLevel::trace: Enables all diagnostic logs (warning,info,debug,trace). Recommended for high-volume I/O operations.LogLevel::debug: Enableswarning,info, anddebuglogs (excludestrace).LogLevel::info: Enableswarningandinfologs (excludesdebugandtrace).LogLevel::warning: Enableswarninglogs only.
Log Level Colors & Output Styling¶
ScopeTrace applies distinct ANSI color escape codes to each log level tag to make terminal output visually scannable:
| Log Level / Method | Tag Label | Tag Color Output | ANSI Escape Code | Visual Terminal Preview |
|---|---|---|---|---|
trace_level::critical |
crit |
Reverse Red | \033[7;31m |
[crit ] System memory exhaustion |
trace_level::exception |
except |
Reverse Red | \033[7;31m |
[except] std::runtime_error - Timeout |
trace_level::error |
error |
Reverse Orange | \033[7;38;5;208m |
[error ] Failed to connect to db host |
trace_level::warning |
warn |
Reverse Light Yellow | \033[7;38;5;220m |
[warn ] Cache capacity reached 92% |
trace_level::info |
info |
Default / Neutral | \033[0m |
[info ] Processing batch item 42 |
trace_level::debug |
debug |
Light Gray | \033[38;5;250m |
[debug ] Worker thread pool depth: 4 |
trace_level::trace |
trace |
Dark Blue | \033[38;5;19m |
[trace ] RX buffer dump: 0x41 0x42 0x43 |
| Scope Exit | COMPLETED |
Green Time | \033[0;32m |
COMPLETED: time:450us |
[!TIP] Best Practice: High-Frequency I/O Operations Should Use
trace(scope.trace(...))High-volume diagnostic logging — such as socket reads/writes, raw payload packet dumps, file stream buffer transfers, HTTP payload tracing, or inner loop iterations — should always use
trace_level::trace(scope.trace(...)).When
m_log_levelis set toLogLevel::debugorinfo, allscope.trace(...)statements are bypassed via a zero-allocation threshold check (level <= m_log_level), eliminating string formatting and stream output overhead during standard debugging while keeping log buffers clean.
In-Scope Logging Sinks¶
Within an active scope, you can output formatted contextual messages to std::cerr with depth indentation and ANSI color coding:
scope.trace("..."): Trace diagnostic details (light gray, active whenm_log_level >= trace). Ideal for I/O packet/buffer dumps.scope.debug("..."): Debug diagnostic details (light gray, active whenm_log_level >= debug).scope.info("..."): Informational messages (active whenm_log_level >= info).scope.warn("..."): Warning messages (colored dark yellow, active whenm_log_level >= warning).scope.err("..."): Error messages (colored orange, always logged).scope.err_throw<EX>("..."): Unified error logging & exception throwing shortcut (colored orange, throwsEX(formatted_msg), always logged).scope.exp(e): Exception handler shortcut. Logs exception type (typeid(e).name()) in bold red ande.what()(always logged).scope.exp(e, "..."): Exception handler shortcut with context. Logs exception type, italicizede.what(), and custom formatted contextual details (always logged).
Unified Error Throwing & Catching Patterns¶
ScopeTrace simplifies error flow by combining console logging with exception throwing (err_throw()) and exception handling (exp()):
1. Throw Site (err_throw)¶
Instead of separate log and throw statements, err_throw<EX>(fmt, args...) logs the formatted error message with timestamps, depth indentation, and exception type details, then immediately throws EX:
void validate_input(int value)
{
auto scope = siddiqsoft::ScopeTrace::GetInstance().sub_scope("validate_input");
if (value < 0) {
// Logs orange error message and throws std::invalid_argument
scope.err_throw<std::invalid_argument>("Value must be non-negative, got: {}", value);
}
}
2. Catch Site (exp)¶
Inside catch blocks, exp() logs caught exception details with zero boilerplate: