FastLED 3.9.15
Loading...
Searching...
No Matches
async_logger.h
Go to the documentation of this file.
1#pragma once
2
5
7#include "fl/stl/int.h"
8#include "fl/stl/singleton.h"
9#include "fl/task/task.h"
10#include "fl/stl/noexcept.h"
11
12namespace fl {
13
14// Scheduler is now fl::task::Scheduler (aliased via fl/stl/async.h)
15
20public:
22 ~AsyncLogger() FL_NOEXCEPT = default; // No cleanup needed (embedded storage)
23
24 void push(const fl::string& msg);
25 void push(const char* msg);
26 void flush();
27 fl::size size() const;
28 bool empty() const;
29 void clear();
30 fl::u32 droppedCount() const;
31
35 fl::size flushN(fl::size maxMessages);
36
41 bool enableBackgroundFlush(fl::u32 interval_ms, fl::size messages_per_tick = 5);
42
45
47 bool isBackgroundFlushEnabled() const;
48
49private:
50 AsyncLogQueue<128, 4096> mQueue; // Embedded storage (zero heap allocation)
51};
52
55enum class LogCategory : fl::u8 {
66 // Add new categories here (max 16 total)
68};
69
70namespace detail {
71 // Forward declare BackgroundFlushState for async_log_service
72 struct BackgroundFlushState;
73
74 // Forward declare printLoggerDisabledError (defined in async_logger.cpp.hpp)
75 void printLoggerDisabledError(const char* category_name, const char* define_name);
76
79 template<typename InfoProvider>
80 inline void checkLoggerEnabled() {
81 if (!InfoProvider::isEnabled()) {
82 static bool error_printed = false;
83 if (!error_printed) {
84 error_printed = true;
85 printLoggerDisabledError(InfoProvider::categoryName(), InfoProvider::defineName());
86 }
87 }
88 }
89
93 static const char* categoryName() { return "PARLIO"; }
94 static const char* defineName() { return "FASTLED_LOG_PARLIO_ENABLED"; }
95 static bool isEnabled() {
96 #ifdef FASTLED_LOG_PARLIO_ENABLED
97 return true;
98 #else
99 return false;
100 #endif
101 }
102 };
103
105 static const char* categoryName() { return "RMT"; }
106 static const char* defineName() { return "FASTLED_LOG_RMT_ENABLED"; }
107 static bool isEnabled() {
108 #ifdef FASTLED_LOG_RMT_ENABLED
109 return true;
110 #else
111 return false;
112 #endif
113 }
114 };
115
117 static const char* categoryName() { return "SPI"; }
118 static const char* defineName() { return "FASTLED_LOG_SPI_ENABLED"; }
119 static bool isEnabled() {
120 #ifdef FASTLED_LOG_SPI_ENABLED
121 return true;
122 #else
123 return false;
124 #endif
125 }
126 };
127
129 static const char* categoryName() { return "AUDIO"; }
130 static const char* defineName() { return "FASTLED_LOG_AUDIO_ENABLED"; }
131 static bool isEnabled() {
132 #ifdef FASTLED_LOG_AUDIO_ENABLED
133 return true;
134 #else
135 return false;
136 #endif
137 }
138 };
139
141 static const char* categoryName() { return "INTERRUPT"; }
142 static const char* defineName() { return "FASTLED_LOG_INTERRUPT_ENABLED"; }
143 static bool isEnabled() {
144 #ifdef FASTLED_LOG_INTERRUPT_ENABLED
145 return true;
146 #else
147 return false;
148 #endif
149 }
150 };
151
153 static const char* categoryName() { return "FLEX_IO"; }
154 static const char* defineName() { return "FASTLED_LOG_FLEXIO_ENABLED"; }
155 static bool isEnabled() {
156 #ifdef FASTLED_LOG_FLEXIO_ENABLED
157 return true;
158 #else
159 return false;
160 #endif
161 }
162 };
163
165 static const char* categoryName() { return "OBJECT_FLED"; }
166 static const char* defineName() { return "FASTLED_LOG_OBJECTFLED_ENABLED"; }
167 static bool isEnabled() {
168 #ifdef FASTLED_LOG_OBJECTFLED_ENABLED
169 return true;
170 #else
171 return false;
172 #endif
173 }
174 };
175
180
184
186 // Check if already registered
187 for (fl::size i = 0; i < mActiveLoggers.size(); ++i) {
188 if (mActiveLoggers[i] == logger) {
189 return; // Already registered
190 }
191 }
192 // Add to active list
193 mActiveLoggers.push_back(logger);
194 }
195
196 template<typename Func>
197 void forEach(Func func) {
198 for (fl::size i = 0; i < mActiveLoggers.size(); ++i) {
199 func(*mActiveLoggers[i]);
200 }
201 }
202 };
203
208 public:
210
214 void setInterval(u32 interval_ms);
215
217 u32 getInterval() const { return mIntervalMs; }
218
221 void setMessagesPerTick(fl::size messages_per_tick);
222
224 fl::size getMessagesPerTick() const { return mMessagesPerTick; }
225
228
229 private:
231
234
237 fl::task::Handle mTask; // Task object (stored to allow dynamic interval changes)
238 };
239
240} // namespace detail
241
248template<fl::size N, typename InfoProvider>
250 // Get singleton instance (only this specific N is instantiated)
251 static AsyncLogger* logger_ptr = []() {
253 detail::ActiveLoggerRegistry::instance().registerLogger(ptr);
254
255 // Auto-instantiate service task on first logger access
256 // This ensures automatic background servicing via fl::delay() and fl::task::Scheduler
258
259 return ptr;
260 }();
261
262 // Check if logging is enabled, print error once if not
263 // (Implementation in async_logger.cpp.hpp uses FL_ERROR)
265
266 return *logger_ptr;
267}
268
269// Convenience wrappers for category-based access (linker removes unused ones)
270// Each wrapper uses an info provider to check if logging is enabled
271// and prints an error message on first access if logging is disabled
272
276
280
284
288
292
296
300
304
308
312
316
320
324
328
329} // namespace fl
High-performance ISR-safe async logging queue (SPSC ring buffer) - declarations only.
High-performance SPSC async log queue.
fl::size flushN(fl::size maxMessages)
Flush up to N messages from queue (bounded flush)
fl::u32 droppedCount() const
bool isBackgroundFlushEnabled() const
Check if background flushing is enabled.
void push(const fl::string &msg)
~AsyncLogger() FL_NOEXCEPT=default
AsyncLogQueue< 128, 4096 > mQueue
bool enableBackgroundFlush(fl::u32 interval_ms, fl::size messages_per_tick=5)
Enable background timer-based flushing (opt-in)
AsyncLogger() FL_NOEXCEPT
void disableBackgroundFlush()
Disable background flushing.
fl::size size() const
ISR-safe async logger wrapper (zero heap allocation) Uses embedded AsyncLogQueue instead of heap-allo...
static T & instance() FL_NOEXCEPT
Definition singleton.h:81
void serviceLoggers()
Service all registered loggers (called by task)
void setInterval(u32 interval_ms)
Change the service interval (default 16ms)
static AsyncLoggerServiceTask & instance()
u32 getInterval() const
Get current service interval.
fl::size getMessagesPerTick() const
Get messages per tick.
void checkLoggerEnabled()
Check if logger is enabled and print error once if not.
void printLoggerDisabledError(const char *category_name, const char *define_name)
Print error message for disabled logger (non-template helper) Called from checkLoggerEnabled template...
unsigned char u8
Definition stdint.h:131
@ SPI_ISR
Use ISR-based software (Async)
Definition config.h:29
AsyncLogger & get_flexio_async_logger_main()
AsyncLogger & get_objectfled_async_logger_main()
AsyncLogger & get_parlio_async_logger_isr()
LogCategory
Logger category identifiers for registry-based access Each category has separate ISR and main thread ...
AsyncLogger & get_rmt_async_logger_main()
AsyncLogger & get_objectfled_async_logger_isr()
AsyncLogger & get_async_logger_by_index()
Template-based logger accessor with auto-registration and enablement check.
AsyncLogger & get_spi_async_logger_isr()
AsyncLogger & get_rmt_async_logger_isr()
AsyncLogger & get_parlio_async_logger_main()
AsyncLogger & get_interrupt_async_logger_isr()
AsyncLogger & get_spi_async_logger_main()
AsyncLogger & get_audio_async_logger_main()
AsyncLogger & get_interrupt_async_logger_main()
AsyncLogger & get_audio_async_logger_isr()
FixedVector< T, INLINED_SIZE > vector_fixed
Definition vector.h:1130
AsyncLogger & get_flexio_async_logger_isr()
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_NOEXCEPT
static ActiveLoggerRegistry & instance()
fl::vector_fixed< AsyncLogger *, 16 > mActiveLoggers
void registerLogger(AsyncLogger *logger)
Active logger registry for iteration (flush operations) Only tracks loggers that have been instantiat...
static const char * categoryName()
static const char * defineName()
static const char * categoryName()
static const char * defineName()
static const char * categoryName()
static const char * defineName()
static const char * defineName()
static const char * categoryName()
static const char * categoryName()
static const char * defineName()
Info providers for each logger category Used to supply category name, define name,...
static const char * categoryName()
static const char * defineName()
static const char * defineName()
static const char * categoryName()