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()
{
// Defaults scope name to plain function name ("compute")
siddiqsoft::ScopeTrace scope;
// Explicit nested scope ("compute-stage1")
auto sub = scope.nest("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_func_name() / function_name()) to extract clean plain function names matching __func__ from full signature strings. When ScopeTrace is declared in the global scope (outside of any enclosing function), extract_func_name() evaluates to "GLOBAL".
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::critical upon construction). You can set the threshold at scope creation or dynamically update it via set_level():
// Set logging threshold to debug at construction
siddiqsoft::ScopeTrace scope("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 | Color Output | ANSI Escape Code | Visual Terminal Preview |
|---|---|---|---|---|
trace_level::critical |
[crit ] |
Red | \033[0;31m |
[crit ] System memory exhaustion |
trace_level::exception |
[except] |
Red / Bold Red | \033[0;31m |
[except] std::runtime_error - Timeout |
trace_level::error |
[error ] |
Orange | \033[38;5;208m |
[error ] Failed to connect to db host |
trace_level::warning |
[warn ] |
Dark Yellow / Gold | \033[38;5;136m |
[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)
{
siddiqsoft::ScopeTrace scope;
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: