Thread System 0.3.1
High-performance C++20 thread pool with work stealing and DAG scheduling
Loading...
Searching...
No Matches
kcenon::thread::thread_logger Class Reference

Structured logger for thread system. More...

#include <thread_logger.h>

Collaboration diagram for kcenon::thread::thread_logger:
Collaboration graph

Public Member Functions

void set_enabled (bool enabled)
 Enable/disable logging.
 
bool is_enabled () const
 Check if logging is enabled.
 
void set_level (log_level level)
 Set minimum log level.
 
void log (log_level level, std::string_view thread_name, std::string_view message, std::string_view context="")
 Log a message with context.
 
template<typename ErrorType >
void log_error (std::string_view thread_name, const ErrorType &error)
 Log error with error code.
 
void set_lightweight_mode (bool enabled)
 Enable lightweight mode (disables all logging for maximum performance).
 
bool is_lightweight_mode () const
 Check if in lightweight mode.
 

Static Public Member Functions

static thread_loggerinstance ()
 Get singleton instance.
 
static void prepare_shutdown ()
 Prepare for process shutdown.
 
static bool is_shutting_down ()
 Check if shutdown is in progress.
 

Private Member Functions

 thread_logger ()=default
 
 ~thread_logger ()=default
 
 thread_logger (const thread_logger &)=delete
 
thread_loggeroperator= (const thread_logger &)=delete
 

Static Private Member Functions

static const char * level_to_string (log_level level)
 

Private Attributes

bool enabled_ = true
 
log_level min_level_ = log_level::warning
 
std::mutex mutex_
 
bool lightweight_mode_ = false
 

Static Private Attributes

static std::atomic< bool > is_shutting_down_ {false}
 

Detailed Description

Structured logger for thread system.

Provides thread-safe, structured logging with timestamps, thread IDs, and severity levels for better diagnostics.

Thread Safety:

  • All methods are thread-safe
  • Uses mutex for synchronized output
  • Lock-free in disabled state

SDOF Prevention:

  • The shutdown handler is registered early during program initialization via thread_logger_init.cpp, ensuring it runs after all user static object destructors complete (atexit handlers run in LIFO order)
  • This guarantees is_shutting_down() returns true during static destruction
See also
thread_logger_init.cpp for early registration implementation

Definition at line 71 of file thread_logger.h.

Constructor & Destructor Documentation

◆ thread_logger() [1/2]

kcenon::thread::thread_logger::thread_logger ( )
privatedefault

Referenced by instance().

Here is the caller graph for this function:

◆ ~thread_logger()

kcenon::thread::thread_logger::~thread_logger ( )
privatedefault

◆ thread_logger() [2/2]

kcenon::thread::thread_logger::thread_logger ( const thread_logger & )
privatedelete

Member Function Documentation

◆ instance()

static thread_logger & kcenon::thread::thread_logger::instance ( )
inlinestatic

Get singleton instance.

Uses intentional leak pattern to avoid static destruction order issues. The logger may be accessed during other singletons' destruction, so we intentionally leak to ensure it remains valid.

Note
The atexit handler for SDOF protection is registered early during program initialization by thread_logger_init.cpp, not here. This ensures the handler runs after all user static object destructors complete, guaranteeing is_shutting_down() returns true during the destruction phase.
See also
thread_logger_init.cpp

Definition at line 88 of file thread_logger.h.

88 {
89 // Intentionally leak to avoid static destruction order issues
90 // Logger may be accessed during other singletons' destruction
91 static thread_logger* logger = []() {
92 auto* ptr = new thread_logger();
93 // Note: atexit handler is registered early by thread_logger_init.cpp
94 // We register here as well for safety (multiple calls to atexit with
95 // the same function are safe per C++ standard - they just add multiple
96 // entries, and prepare_shutdown() is idempotent)
97 std::atexit(prepare_shutdown);
98 return ptr;
99 }();
100 return *logger;
101 }
static void prepare_shutdown()
Prepare for process shutdown.

References prepare_shutdown(), and thread_logger().

Referenced by kcenon::thread::thread_base::start().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_enabled()

bool kcenon::thread::thread_logger::is_enabled ( ) const
inline

Check if logging is enabled.

Deprecated
Since v1.0.0. Check availability through thread_context::has_logger() instead. Will be removed in v2.0.0.

Definition at line 144 of file thread_logger.h.

144 {
145 return enabled_;
146 }

References enabled_.

◆ is_lightweight_mode()

bool kcenon::thread::thread_logger::is_lightweight_mode ( ) const
inline

Check if in lightweight mode.

Deprecated
Since v1.0.0. See set_lightweight_mode deprecation. Will be removed in v2.0.0.

Definition at line 308 of file thread_logger.h.

308 {
309 return lightweight_mode_;
310 }

References lightweight_mode_.

◆ is_shutting_down()

static bool kcenon::thread::thread_logger::is_shutting_down ( )
inlinestatic

◆ level_to_string()

static const char * kcenon::thread::thread_logger::level_to_string ( log_level level)
inlinestaticprivate

Definition at line 252 of file thread_logger.h.

252 {
253 switch (level) {
254 case log_level::trace: return "TRACE";
255 case log_level::debug: return "DEBUG";
256 case log_level::info: return "INFO";
257 case log_level::warning: return "WARN";
258 case log_level::error: return "ERROR";
259 case log_level::critical: return "CRITICAL";
260 default: return "UNKNOWN";
261 }
262 }

References kcenon::thread::critical, kcenon::thread::debug, kcenon::thread::error, kcenon::thread::info, kcenon::thread::trace, and kcenon::thread::warning.

Referenced by log().

Here is the caller graph for this function:

◆ log()

void kcenon::thread::thread_logger::log ( log_level level,
std::string_view thread_name,
std::string_view message,
std::string_view context = "" )
inline

Log a message with context.

Parameters
levelSeverity level
thread_nameThread identifier
messageLog message
contextAdditional context (optional)
Deprecated
Since v1.0.0. Use thread_context::log() backed by common::interfaces::ILogger instead. Will be removed in v2.0.0.

Definition at line 176 of file thread_logger.h.

177 {
178 // Early return during shutdown to avoid accessing potentially destroyed resources
179 if (is_shutting_down_.load(std::memory_order_acquire)) {
180 return;
181 }
182
183 if (!enabled_ || level < min_level_) {
184 return;
185 }
186
187 std::lock_guard<std::mutex> lock(mutex_);
188
189 auto now = std::chrono::system_clock::now();
190 auto time_t_val = std::chrono::system_clock::to_time_t(now);
191 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
192 now.time_since_epoch()) % 1000;
193
194 // Use thread-safe localtime variant
195 std::tm tm_buf{};
196#if defined(_MSC_VER) || defined(_WIN32)
197 localtime_s(&tm_buf, &time_t_val);
198#else
199 localtime_r(&time_t_val, &tm_buf);
200#endif
201
202 std::cerr << "["
203 << std::put_time(&tm_buf, "%Y-%m-%d %H:%M:%S")
204 << "." << std::setfill('0') << std::setw(3) << ms.count()
205 << "] "
206 << "[" << level_to_string(level) << "] "
207 << "[Thread:" << thread_name << "] "
208 << "[TID:" << std::this_thread::get_id() << "] "
209 << message;
210
211 if (!context.empty()) {
212 std::cerr << " | Context: " << context;
213 }
214
215 std::cerr << std::endl;
216 }
static const char * level_to_string(log_level level)

References enabled_, is_shutting_down_, level_to_string(), min_level_, and mutex_.

Referenced by log_error(), and kcenon::thread::thread_base::start().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ log_error()

template<typename ErrorType >
void kcenon::thread::thread_logger::log_error ( std::string_view thread_name,
const ErrorType & error )
inline

Log error with error code.

Deprecated
Since v1.0.0. Use thread_context::log() with a common::interfaces::ILogger implementation instead. Will be removed in v2.0.0.

Definition at line 229 of file thread_logger.h.

229 {
230 // Early return during shutdown
231 if (is_shutting_down_.load(std::memory_order_acquire) || !enabled_) {
232 return;
233 }
234
235 std::ostringstream oss;
236 oss << "Error code: " << error.code()
237 << ", Message: " << error.message();
238
239 log(log_level::error, thread_name, oss.str());
240 }
void log(log_level level, std::string_view thread_name, std::string_view message, std::string_view context="")
Log a message with context.
@ error
Error events that might still allow continuation.

References kcenon::thread::error::code(), enabled_, kcenon::thread::error, is_shutting_down_, log(), and kcenon::thread::error::message().

Here is the call graph for this function:

◆ operator=()

thread_logger & kcenon::thread::thread_logger::operator= ( const thread_logger & )
privatedelete

◆ prepare_shutdown()

static void kcenon::thread::thread_logger::prepare_shutdown ( )
inlinestatic

Prepare for process shutdown.

Call this before process termination to prevent log calls during static destruction. Once called, all log operations become no-ops.

Definition at line 110 of file thread_logger.h.

110 {
111 is_shutting_down_.store(true, std::memory_order_release);
112 }

References is_shutting_down_.

Referenced by instance().

Here is the caller graph for this function:

◆ set_enabled()

void kcenon::thread::thread_logger::set_enabled ( bool enabled)
inline

Enable/disable logging.

Deprecated
Since v1.0.0. Inject a common::interfaces::ILogger via thread_context and control logging through its implementation instead. Will be removed in v2.0.0.

Definition at line 131 of file thread_logger.h.

131 {
132 enabled_ = enabled;
133 }

References enabled_.

◆ set_level()

void kcenon::thread::thread_logger::set_level ( log_level level)
inline

Set minimum log level.

Deprecated
Since v1.0.0. Configure log level on the injected common::interfaces::ILogger implementation instead. Will be removed in v2.0.0.

Definition at line 158 of file thread_logger.h.

158 {
159 min_level_ = level;
160 }

References min_level_.

◆ set_lightweight_mode()

void kcenon::thread::thread_logger::set_lightweight_mode ( bool enabled)
inline

Enable lightweight mode (disables all logging for maximum performance).

In lightweight mode, all log calls become no-ops with minimal overhead. Useful for performance-critical production deployments where diagnostics are handled externally.

Parameters
enabledtrue to enable lightweight mode, false to use normal logging
Deprecated
Since v1.0.0. With common::interfaces::ILogger, a null logger in thread_context achieves the same effect without this toggle. Will be removed in v2.0.0.

Definition at line 291 of file thread_logger.h.

291 {
292 lightweight_mode_ = enabled;
293 // Disable logging when in lightweight mode
294 if (enabled) {
295 enabled_ = false;
296 }
297 }

References enabled_, and lightweight_mode_.

Member Data Documentation

◆ enabled_

bool kcenon::thread::thread_logger::enabled_ = true
private

Definition at line 266 of file thread_logger.h.

Referenced by is_enabled(), log(), log_error(), set_enabled(), and set_lightweight_mode().

◆ is_shutting_down_

std::atomic<bool> kcenon::thread::thread_logger::is_shutting_down_ {false}
inlinestaticprivate

Definition at line 245 of file thread_logger.h.

245{false};

Referenced by is_shutting_down(), log(), log_error(), and prepare_shutdown().

◆ lightweight_mode_

bool kcenon::thread::thread_logger::lightweight_mode_ = false
private

Definition at line 272 of file thread_logger.h.

Referenced by is_lightweight_mode(), and set_lightweight_mode().

◆ min_level_

log_level kcenon::thread::thread_logger::min_level_ = log_level::warning
private

Definition at line 267 of file thread_logger.h.

Referenced by log(), and set_level().

◆ mutex_

std::mutex kcenon::thread::thread_logger::mutex_
private

Definition at line 268 of file thread_logger.h.

Referenced by log().


The documentation for this class was generated from the following file: