#pragma once #include #include #include // For std::function #include #include "freertos/FreeRTOS.h" #include "freertos/queue.h" #include "freertos/task.h" enum LogLevel { LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR }; struct LogEntry { LogLevel level; time_t timestamp; char message[128]; }; class Logger { public: Logger(); ~Logger(); void begin(UBaseType_t taskPriority = 1, uint32_t taskStackSize = 2048); void setLogLevel(LogLevel level); LogLevel getLogLevel() const; // Use the more flexible std::function for callbacks void setLogCallback(std::function callback); // --- NEW: Variadic functions for printf-style formatting --- void debug(const char* format, ...); void info(const char* format, ...); void warn(const char* format, ...); void error(const char* format, ...); const LogEntry* getLogs(int& count) const; void clear(); const char* levelToString(LogLevel level) const; private: static const int MAX_LOGS = 20; LogEntry logs[MAX_LOGS]; int logCount; int logIndex; LogLevel currentLogLevel; std::function logCallback; QueueHandle_t logQueue; TaskHandle_t logTaskHandle; static void logProcessingTask(void* instance); void addLog(LogLevel level, const char* format, va_list args); }; extern Logger logger; // --- OPTIONAL: Performance-enhancing macros --- #define LOG_DEBUG(format, ...) if(logger.getLogLevel() <= LOG_DEBUG) { logger.debug(format, ##__VA_ARGS__); } #define LOG_INFO(format, ...) if(logger.getLogLevel() <= LOG_INFO) { logger.info(format, ##__VA_ARGS__); } #define LOG_WARN(format, ...) if(logger.getLogLevel() <= LOG_WARN) { logger.warn(format, ##__VA_ARGS__); } #define LOG_ERROR(format, ...) if(logger.getLogLevel() <= LOG_ERROR) { logger.error(format, ##__VA_ARGS__); }