Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
logger_integration.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2024, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
5#pragma once
6#ifndef KCENON_NETWORK_INTERNAL_INTEGRATION_LOGGER_INTEGRATION_H_
7#define KCENON_NETWORK_INTERNAL_INTEGRATION_LOGGER_INTEGRATION_H_
8
10
25#include <atomic>
26#include <memory>
27#include <string>
28#include <string_view>
29
31
32// Conditionally include common_system logging facilities
33#if KCENON_WITH_COMMON_SYSTEM
34#include <kcenon/common/logging/log_macros.h>
35#include <kcenon/common/interfaces/global_logger_registry.h>
36#endif
37
39
44enum class log_level : int {
45 trace = 0,
46 debug = 1,
47 info = 2,
48 warn = 3,
49 error = 4,
50 fatal = 5
51};
52
53#if KCENON_WITH_COMMON_SYSTEM
57inline kcenon::common::interfaces::log_level to_common_level(log_level level) {
58 switch (level) {
59 case log_level::trace: return kcenon::common::interfaces::log_level::trace;
60 case log_level::debug: return kcenon::common::interfaces::log_level::debug;
61 case log_level::info: return kcenon::common::interfaces::log_level::info;
62 case log_level::warn: return kcenon::common::interfaces::log_level::warning;
63 case log_level::error: return kcenon::common::interfaces::log_level::error;
64 case log_level::fatal: return kcenon::common::interfaces::log_level::critical;
65 default: return kcenon::common::interfaces::log_level::info;
66 }
67}
68#endif // KCENON_WITH_COMMON_SYSTEM
69
77class logger_interface {
78public:
79 virtual ~logger_interface() = default;
80
86 virtual void log(log_level level, const std::string& message) = 0;
87
96 virtual void log(log_level level, const std::string& message,
97 const std::string& file, int line,
98 const std::string& function) = 0;
99
105 virtual bool is_level_enabled(log_level level) const = 0;
106
110 virtual void flush() = 0;
111};
112
113#if KCENON_WITH_COMMON_SYSTEM
121class common_system_logger_adapter : public logger_interface {
122public:
127 explicit common_system_logger_adapter(const std::string& logger_name = "");
128
129 ~common_system_logger_adapter() override = default;
130
131 void log(log_level level, const std::string& message) override;
132 void log(log_level level, const std::string& message,
133 const std::string& file, int line,
134 const std::string& function) override;
135 bool is_level_enabled(log_level level) const override;
136 void flush() override;
137
138private:
139 std::string logger_name_;
140 std::shared_ptr<kcenon::common::interfaces::ILogger> get_logger() const;
141};
142#endif // KCENON_WITH_COMMON_SYSTEM
143
152public:
157 explicit basic_logger(log_level min_level = log_level::info);
158
159 ~basic_logger() override;
160
161 // logger_interface implementation
162 void log(log_level level, const std::string& message) override;
163 void log(log_level level, const std::string& message,
164 const std::string& file, int line,
165 const std::string& function) override;
166 bool is_level_enabled(log_level level) const override;
167 void flush() override;
168
173 void set_min_level(log_level level);
174
179 log_level get_min_level() const;
180
181private:
182 class impl;
183 std::unique_ptr<impl> pimpl_;
184};
185
195public:
201
206 void set_logger(std::shared_ptr<logger_interface> logger);
207
212 std::shared_ptr<logger_interface> get_logger();
213
219 void log(log_level level, const std::string& message);
220
229 void log(log_level level, const std::string& message,
230 const std::string& file, int line, const std::string& function);
231
232private:
235
236 class impl;
237 std::unique_ptr<impl> pimpl_;
238};
239
240// =============================================================================
241// Static destruction guard
242//
243// When KCENON_WITH_COMMON_SYSTEM is enabled, LOG_* macros access common_system's
244// GlobalLoggerRegistry singleton. During static destruction, this singleton may
245// be destroyed before network_system's singletons, causing heap corruption when
246// thread pool threads try to log.
247//
248// This guard prevents logging during static destruction by tracking if the
249// logging subsystem is still valid.
250// =============================================================================
251
252namespace detail {
253
262public:
263 static_destruction_guard() { counter_.fetch_add(1, std::memory_order_relaxed); }
264 ~static_destruction_guard() { counter_.fetch_sub(1, std::memory_order_relaxed); }
265
270 static bool is_logging_safe()
271 {
272 return counter_.load(std::memory_order_relaxed) > 0;
273 }
274
275private:
276 static inline std::atomic<int> counter_{0};
277};
278
279// This static instance ensures the counter is incremented at program start
280// and decremented during static destruction. When counter_ reaches 0,
281// we know static destruction has begun.
283
284} // namespace detail
285
286} // namespace kcenon::network::integration
287
288// =============================================================================
289// Convenience macros for logging with automatic source location
290//
291// When KCENON_WITH_COMMON_SYSTEM is enabled, delegate to common_system's LOG_* macros.
292// Otherwise, use logger_integration_manager for standalone operation.
293//
294// Note: All macros now check static_destruction_guard to avoid heap corruption
295// during static destruction when common_system's GlobalLoggerRegistry is destroyed.
296// =============================================================================
297
298#if KCENON_WITH_COMMON_SYSTEM
299
300#define NETWORK_LOG_TRACE(msg) \
301 do { if (::kcenon::network::integration::detail::static_destruction_guard::is_logging_safe()) { LOG_TRACE(msg); } } while(0)
302#define NETWORK_LOG_DEBUG(msg) \
303 do { if (::kcenon::network::integration::detail::static_destruction_guard::is_logging_safe()) { LOG_DEBUG(msg); } } while(0)
304#define NETWORK_LOG_INFO(msg) \
305 do { if (::kcenon::network::integration::detail::static_destruction_guard::is_logging_safe()) { LOG_INFO(msg); } } while(0)
306#define NETWORK_LOG_WARN(msg) \
307 do { if (::kcenon::network::integration::detail::static_destruction_guard::is_logging_safe()) { LOG_WARNING(msg); } } while(0)
308#define NETWORK_LOG_ERROR(msg) \
309 do { if (::kcenon::network::integration::detail::static_destruction_guard::is_logging_safe()) { LOG_ERROR(msg); } } while(0)
310#define NETWORK_LOG_FATAL(msg) \
311 do { if (::kcenon::network::integration::detail::static_destruction_guard::is_logging_safe()) { LOG_CRITICAL(msg); } } while(0)
312
313#else // KCENON_WITH_COMMON_SYSTEM
314
315#define NETWORK_LOG_TRACE(msg) \
316 kcenon::network::integration::logger_integration_manager::instance().log( \
317 kcenon::network::integration::log_level::trace, msg, __FILE__, __LINE__, __FUNCTION__)
318
319#define NETWORK_LOG_DEBUG(msg) \
320 kcenon::network::integration::logger_integration_manager::instance().log( \
321 kcenon::network::integration::log_level::debug, msg, __FILE__, __LINE__, __FUNCTION__)
322
323#define NETWORK_LOG_INFO(msg) \
324 kcenon::network::integration::logger_integration_manager::instance().log( \
325 kcenon::network::integration::log_level::info, msg, __FILE__, __LINE__, __FUNCTION__)
326
327#define NETWORK_LOG_WARN(msg) \
328 kcenon::network::integration::logger_integration_manager::instance().log( \
329 kcenon::network::integration::log_level::warn, msg, __FILE__, __LINE__, __FUNCTION__)
330
331#define NETWORK_LOG_ERROR(msg) \
332 kcenon::network::integration::logger_integration_manager::instance().log( \
333 kcenon::network::integration::log_level::error, msg, __FILE__, __LINE__, __FUNCTION__)
334
335#define NETWORK_LOG_FATAL(msg) \
336 kcenon::network::integration::logger_integration_manager::instance().log( \
337 kcenon::network::integration::log_level::fatal, msg, __FILE__, __LINE__, __FUNCTION__)
338
339#endif // KCENON_WITH_COMMON_SYSTEM
340
341// Backward compatibility namespace alias is defined in thread_integration.h
342
343#endif // KCENON_NETWORK_INTERNAL_INTEGRATION_LOGGER_INTEGRATION_H_
Basic console logger implementation for standalone use.
basic_logger(log_level min_level=log_level::info)
Constructor with minimum log level.
void log(log_level level, const std::string &message) override
Log a message with specified level.
bool is_level_enabled(log_level level) const override
Check if a log level is enabled.
void set_min_level(log_level level)
Set minimum log level.
void flush() override
Flush any buffered log messages.
log_level get_min_level() const
Get current minimum log level.
Guard against logging during static destruction.
static bool is_logging_safe()
Check if logging is safe (not in static destruction)
static logger_integration_manager & instance()
Get the singleton instance.
void log(log_level level, const std::string &message)
Log a message.
void set_logger(std::shared_ptr< logger_interface > logger)
Set the logger implementation.
std::shared_ptr< logger_interface > get_logger()
Get the current logger.
Interface for logger integration.
Definition core.cppm:112
virtual void flush()=0
Flush any buffered log messages.
virtual bool is_level_enabled(log_level level) const =0
Check if a log level is enabled.
virtual void log(log_level level, const std::string &message)=0
Log a message with specified level.
virtual void log(log_level level, const std::string &message, const std::string &file, int line, const std::string &function)=0
Log a message with source location information.
Feature flags for network_system.
Thread system integration interface for network_system.