Line data Source code
1 : #ifndef THINGER_LOGGER_HPP
2 : #define THINGER_LOGGER_HPP
3 : #pragma once
4 :
5 : #if __has_include(<spdlog/spdlog.h>)
6 : #include <spdlog/spdlog.h>
7 : #include <spdlog/sinks/stdout_color_sinks.h>
8 : #include <string>
9 : #include <memory>
10 : #include <stdexcept>
11 :
12 : #ifndef THINGER_LOG_SPDLOG
13 : #define THINGER_LOG_SPDLOG
14 : #endif
15 :
16 : namespace thinger {
17 : namespace logging {
18 : // Get/set the logger instance used by the library
19 2391893 : inline std::shared_ptr<spdlog::logger>& get_logger() {
20 2391893 : static std::shared_ptr<spdlog::logger> logger;
21 2391893 : return logger;
22 : }
23 :
24 : // Set a custom logger for the library
25 540 : inline void set_logger(std::shared_ptr<spdlog::logger> logger) {
26 540 : get_logger() = logger;
27 540 : }
28 :
29 : // Enable logging with default console logger
30 3438 : inline void enable() {
31 3438 : auto& logger = get_logger();
32 3438 : if (!logger) {
33 : // Create default console logger with color
34 3438 : logger = spdlog::stdout_color_mt("thinger_http");
35 3438 : logger->set_level(spdlog::level::info);
36 : // Pattern: time [level:8] [thread_id] message
37 : // Note: file:line info is often lost when compiled as library
38 10314 : logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%-8l%$] [%t] %v");
39 : }
40 3438 : }
41 :
42 : // Set log level for the library logger
43 3438 : inline void set_log_level(spdlog::level::level_enum level) {
44 3438 : if (auto logger = get_logger()) {
45 3438 : logger->set_level(level);
46 3438 : }
47 3438 : }
48 :
49 : // Disable logging completely
50 : inline void disable() {
51 : set_logger(nullptr);
52 : }
53 :
54 : // Whether a message at `level` would be logged: check it before building
55 : // anything costly to log
56 64937 : inline bool should_log(spdlog::level::level_enum level) {
57 64937 : auto& logger = get_logger();
58 64937 : return logger && logger->should_log(level);
59 : }
60 : }
61 : }
62 :
63 : // Internal macros that use the custom logger if available
64 : #define THINGER_LOG_IMPL(level, ...) \
65 : do { \
66 : if (auto _logger = thinger::logging::get_logger()) { \
67 : _logger->log(level, __VA_ARGS__); \
68 : } \
69 : } while(0)
70 :
71 : // Public logging macros - backward compatible
72 : #define LOG_INFO(...) THINGER_LOG_IMPL(spdlog::level::info, __VA_ARGS__)
73 : #define LOG_ERROR(...) THINGER_LOG_IMPL(spdlog::level::err, __VA_ARGS__)
74 : #define LOG_WARNING(...) THINGER_LOG_IMPL(spdlog::level::warn, __VA_ARGS__)
75 : #define LOG_DEBUG(...) THINGER_LOG_IMPL(spdlog::level::debug, __VA_ARGS__)
76 : #define LOG_TRACE(...) THINGER_LOG_IMPL(spdlog::level::trace, __VA_ARGS__)
77 : #define LOG_LEVEL(LEVEL, ...) THINGER_LOG_IMPL(static_cast<spdlog::level::level_enum>(LEVEL), __VA_ARGS__)
78 :
79 : // Whether a message at that level would be logged
80 : #define LOG_INFO_ENABLED() thinger::logging::should_log(spdlog::level::info)
81 : #define LOG_DEBUG_ENABLED() thinger::logging::should_log(spdlog::level::debug)
82 : #define LOG_TRACE_ENABLED() thinger::logging::should_log(spdlog::level::trace)
83 :
84 : // Thinger specific macros
85 : #define THINGER_LOG(...) LOG_INFO(__VA_ARGS__)
86 : #define THINGER_LOG_TAG(TAG, ...) LOG_INFO("[{}] " __VA_ARGS__, TAG)
87 : #define THINGER_LOG_ERROR(...) LOG_ERROR(__VA_ARGS__)
88 : #define THINGER_LOG_ERROR_TAG(TAG, ...) LOG_ERROR("[{}] " __VA_ARGS__, TAG)
89 :
90 :
91 : #elif defined(THINGER_SERIAL_DEBUG)
92 : #define THINGER_LOG(...) Serial.printf(__VA_ARGS__)
93 : #define THINGER_LOG_ERROR(...) Serial.printf(__VA_ARGS__)
94 :
95 : #else
96 : #define LOG_INFO(...) void()
97 : #define LOG_ERROR(...) void()
98 : #define LOG_WARNING(...) void()
99 : #define LOG_DEBUG(...) void()
100 : #define LOG_TRACE(...) void()
101 : #define LOG_LEVEL(...) void()
102 :
103 : #define LOG_INFO_ENABLED() false
104 : #define LOG_DEBUG_ENABLED() false
105 : #define LOG_TRACE_ENABLED() false
106 :
107 : #define THINGER_LOG(...) void()
108 : #define THINGER_LOG_ERROR(...) void()
109 : #define THINGER_LOG_TAG(...) void()
110 : #define THINGER_LOG_ERROR_TAG(...) void()
111 : #endif
112 :
113 : #endif
|