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 3188006 : inline std::shared_ptr<spdlog::logger>& get_logger() {
20 3188006 : static std::shared_ptr<spdlog::logger> logger;
21 3188006 : return logger;
22 : }
23 :
24 : // Set a custom logger for the library
25 : inline void set_logger(std::shared_ptr<spdlog::logger> logger) {
26 : get_logger() = logger;
27 : }
28 :
29 : // Enable logging with default console logger
30 546 : inline void enable() {
31 546 : auto& logger = get_logger();
32 546 : if (!logger) {
33 : // Create default console logger with color
34 546 : logger = spdlog::stdout_color_mt("thinger_http");
35 546 : 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 1638 : logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%-8l%$] [%t] %v");
39 : }
40 546 : }
41 :
42 : // Set log level for the library logger
43 546 : inline void set_log_level(spdlog::level::level_enum level) {
44 546 : if (auto logger = get_logger()) {
45 546 : logger->set_level(level);
46 546 : }
47 546 : }
48 :
49 : // Disable logging completely
50 : inline void disable() {
51 : set_logger(nullptr);
52 : }
53 : }
54 : }
55 :
56 : // Internal macros that use the custom logger if available
57 : #define THINGER_LOG_IMPL(level, ...) \
58 : do { \
59 : if (auto _logger = thinger::logging::get_logger()) { \
60 : _logger->log(level, __VA_ARGS__); \
61 : } \
62 : } while(0)
63 :
64 : // Public logging macros - backward compatible
65 : #define LOG_INFO(...) THINGER_LOG_IMPL(spdlog::level::info, __VA_ARGS__)
66 : #define LOG_ERROR(...) THINGER_LOG_IMPL(spdlog::level::err, __VA_ARGS__)
67 : #define LOG_WARNING(...) THINGER_LOG_IMPL(spdlog::level::warn, __VA_ARGS__)
68 : #define LOG_DEBUG(...) THINGER_LOG_IMPL(spdlog::level::debug, __VA_ARGS__)
69 : #define LOG_TRACE(...) THINGER_LOG_IMPL(spdlog::level::trace, __VA_ARGS__)
70 : #define LOG_LEVEL(LEVEL, ...) THINGER_LOG_IMPL(static_cast<spdlog::level::level_enum>(LEVEL), __VA_ARGS__)
71 :
72 : // Thinger specific macros
73 : #define THINGER_LOG(...) LOG_INFO(__VA_ARGS__)
74 : #define THINGER_LOG_TAG(TAG, ...) LOG_INFO("[{}] " __VA_ARGS__, TAG)
75 : #define THINGER_LOG_ERROR(...) LOG_ERROR(__VA_ARGS__)
76 : #define THINGER_LOG_ERROR_TAG(TAG, ...) LOG_ERROR("[{}] " __VA_ARGS__, TAG)
77 :
78 :
79 : #elif defined(THINGER_SERIAL_DEBUG)
80 : #define THINGER_LOG(...) Serial.printf(__VA_ARGS__)
81 : #define THINGER_LOG_ERROR(...) Serial.printf(__VA_ARGS__)
82 :
83 : #else
84 : #define LOG_INFO(...) void()
85 : #define LOG_ERROR(...) void()
86 : #define LOG_WARNING(...) void()
87 : #define LOG_DEBUG(...) void()
88 : #define LOG_TRACE(...) void()
89 : #define LOG_LEVEL(...) void()
90 :
91 : #define THINGER_LOG(...) void()
92 : #define THINGER_LOG_ERROR(...) void()
93 : #define THINGER_LOG_TAG(...) void()
94 : #define THINGER_LOG_ERROR_TAG(...) void()
95 : #endif
96 :
97 : #endif
|