Common System 0.2.0
Common interfaces and patterns for system integration
Loading...
Searching...
No Matches
logger_interface.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
17#pragma once
18
19#include <algorithm>
20#include <array>
21#include <chrono>
22#include <functional>
23#include <memory>
24#include <string>
25#include <string_view>
26#include <utility>
27#include "../patterns/result.h"
30
31namespace kcenon::common {
32namespace interfaces {
33
41enum class log_level {
42 trace = 0,
43 debug = 1,
44 info = 2,
45 warning = 3,
46 warn = 3,
47 error = 4,
48 critical = 5,
49 fatal = 5,
50 off = 6
51};
52
53} // namespace interfaces
54
61template<>
62struct enum_traits<interfaces::log_level> {
63 static constexpr auto values = std::array{
64 std::pair{interfaces::log_level::trace, std::string_view{"TRACE"}},
65 std::pair{interfaces::log_level::debug, std::string_view{"DEBUG"}},
66 std::pair{interfaces::log_level::info, std::string_view{"INFO"}},
67 std::pair{interfaces::log_level::warning, std::string_view{"WARNING"}},
68 std::pair{interfaces::log_level::error, std::string_view{"ERROR"}},
69 std::pair{interfaces::log_level::critical, std::string_view{"CRITICAL"}},
70 std::pair{interfaces::log_level::off, std::string_view{"OFF"}},
71 };
72 static constexpr std::string_view module_name = "logger_interface";
73};
74
75namespace interfaces {
76
85struct log_entry {
87 std::string message;
88 std::string file;
89 int line;
90 std::string function;
91 std::chrono::system_clock::time_point timestamp;
93
100 const std::string& msg = "")
101 : level(lvl)
102 , message(msg)
103 , line(0)
104 , timestamp(std::chrono::system_clock::now())
105 , location() {}
106
125 log_level lvl,
126 std::string_view msg,
128
129 log_entry entry;
130 entry.level = lvl;
131 entry.message = std::string(msg);
132 entry.file = loc.file_name();
133 entry.line = loc.line();
134 entry.function = loc.function_name();
135 entry.timestamp = std::chrono::system_clock::now();
136 entry.location = loc;
137 return entry;
138 }
139};
140
153class ILogger {
154public:
155 virtual ~ILogger() = default;
156
163 virtual VoidResult log(log_level level, const std::string& message) = 0;
164
186 virtual VoidResult log(log_level level,
187 std::string_view message,
189 // Default implementation delegates to simple log method
190 // Derived classes should override to use source location information
191 (void)loc; // Unused in default implementation
192 return log(level, std::string(message));
193 }
194
200 virtual VoidResult log(const log_entry& entry) = 0;
201
207 virtual bool is_enabled(log_level level) const = 0;
208
214 virtual VoidResult set_level(log_level level) = 0;
215
220 virtual log_level get_level() const = 0;
221
226 virtual VoidResult flush() = 0;
227};
228
232using LoggerFactory = std::function<std::shared_ptr<ILogger>()>;
233
238class ILoggerProvider {
239public:
240 virtual ~ILoggerProvider() = default;
241
246 virtual std::shared_ptr<ILogger> get_logger() = 0;
247
253 virtual std::shared_ptr<ILogger> create_logger(const std::string& name) = 0;
254};
255
262struct logger_config {
264 std::string pattern = "[%Y-%m-%d %H:%M:%S.%e] [%l] %v";
265 bool async_mode = false;
266 size_t queue_size = 8192;
267 bool color_enabled = false;
268
269 logger_config() = default;
270
271 logger_config(log_level level, const std::string& fmt = "")
272 : min_level(level)
273 , pattern(fmt.empty() ? pattern : fmt) {}
274};
275
282class ILoggerRegistry {
283public:
284 virtual ~ILoggerRegistry() = default;
285
292 virtual VoidResult register_logger(const std::string& name, std::shared_ptr<ILogger> logger) = 0;
293
299 virtual std::shared_ptr<ILogger> get_logger(const std::string& name) = 0;
300
306 virtual VoidResult unregister_logger(const std::string& name) = 0;
307
312 virtual std::shared_ptr<ILogger> get_default_logger() = 0;
313
319 virtual VoidResult set_default_logger(std::shared_ptr<ILogger> logger) = 0;
320};
321
325inline std::string to_string(log_level level) {
326 return enum_to_string(level);
327}
328
334inline log_level from_string(const std::string& str) {
335 std::string upper(str.size(), '\0');
336 std::transform(str.begin(), str.end(), upper.begin(),
337 [](unsigned char c) { return static_cast<char>(std::toupper(c)); });
338
339 // Handle aliases first
340 if (upper == "WARN") {
341 return log_level::warning;
342 }
343 if (upper == "FATAL") {
344 return log_level::critical;
345 }
346
347 // Use generic template for standard values
348 auto result = enum_from_string<log_level>(str);
349 return result.is_ok() ? result.value() : log_level::info; // default
350}
351
352} // namespace interfaces
353} // namespace kcenon::common
Result type for error handling with member function support.
Definition core.cppm:165
Interface for modules that provide logger implementations.
Definition logger.cppm:116
virtual std::shared_ptr< ILogger > create_logger(const std::string &name)=0
Create a new logger with specific name.
virtual std::shared_ptr< ILogger > get_logger()=0
Get the default logger instance.
virtual VoidResult register_logger(const std::string &name, std::shared_ptr< ILogger > logger)=0
Register a logger with a name.
virtual VoidResult unregister_logger(const std::string &name)=0
Remove a logger by name.
virtual VoidResult set_default_logger(std::shared_ptr< ILogger > logger)=0
Set the default logger.
virtual std::shared_ptr< ILogger > get_logger(const std::string &name)=0
Get a logger by name.
virtual std::shared_ptr< ILogger > get_default_logger()=0
Get the default logger.
virtual VoidResult log(const log_entry &entry)=0
Log a structured entry.
virtual bool is_enabled(log_level level) const =0
Check if logging is enabled for the specified level.
virtual log_level get_level() const =0
Get the current minimum log level.
virtual VoidResult log(log_level level, std::string_view message, const source_location &loc=source_location::current())
Log a message with source location information (C++20)
virtual VoidResult set_level(log_level level)=0
Set the minimum log level.
virtual VoidResult flush()=0
Flush any buffered log messages.
virtual VoidResult log(log_level level, const std::string &message)=0
Log a message with specified level.
Generic enum serialization utilities using C++20 concepts.
log_level from_string(const std::string &str)
Parse log level from string (case-insensitive)
std::function< std::shared_ptr< ILogger >()> LoggerFactory
Factory function type for creating logger instances.
std::string to_string(log_level level)
Convert log level to string.
log_level
Standard log levels.
@ warn
Alias for warning (backward compatibility)
@ fatal
Alias for critical (backward compatibility)
Core interfaces.
Definition adapter.h:21
Result< Enum > enum_from_string(std::string_view str)
Convert a string to its enum value (case-insensitive)
std::string enum_to_string(Enum value)
Convert an enum value to its string representation.
Umbrella header for Result<T> type and related utilities.
C++17-compatible source_location implementation.
Primary template for enum traits (must be specialized for each enum)
Standard log entry structure.
Definition logger.cppm:65
log_level level
source_location location
C++20 source_location (Issue #177)
std::chrono::system_clock::time_point timestamp
int line
std::string function
std::string message
log_entry(log_level lvl=log_level::info, const std::string &msg="")
Default constructor.
static log_entry create(log_level lvl, std::string_view msg, const source_location &loc=source_location::current())
Factory method to create a log_entry with source_location.
std::string file
Configuration for logger instances.
Definition logger.cppm:123
logger_config(log_level level, const std::string &fmt="")
C++17-compatible source_location implementation using compiler builtins.
Definition utils.cppm:54
static constexpr source_location current(const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE()) noexcept