Created
August 7, 2025 20:40
-
-
Save sidwarkd/dc970a96ae7795eb22669e042859d618 to your computer and use it in GitHub Desktop.
Abstracted Logger PoC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "freertos/FreeRTOS.h" | |
#include "freertos/semphr.h" | |
#include "esp_log.h" | |
#include "esp32_serial_logger.h" | |
#define RED_COLOR_CODE 31 | |
#define GREEN_COLOR_CODE 32 | |
#define YELLOW_COLOR_CODE 33 | |
#define MAGENTA_COLOR_CODE 35 | |
#define CYAN_COLOR_CODE 36 | |
static SemaphoreHandle_t xSemaphore = NULL; | |
char get_error_char(const LogLevel level) | |
{ | |
switch(level) | |
{ | |
case LogLevel::ERROR: | |
return 'E'; | |
case LogLevel::WARN: | |
return 'W'; | |
case LogLevel::INFO: | |
return 'I'; | |
case LogLevel::DEBUG: | |
return 'D'; | |
case LogLevel::VERBOSE: | |
return 'V'; | |
default: | |
return 'X'; | |
} | |
} | |
int get_console_color_code(const LogLevel level) | |
{ | |
switch(level) | |
{ | |
case LogLevel::ERROR: | |
return RED_COLOR_CODE; | |
case LogLevel::WARN: | |
return YELLOW_COLOR_CODE; | |
case LogLevel::INFO: | |
return GREEN_COLOR_CODE; | |
case LogLevel::DEBUG: | |
return CYAN_COLOR_CODE; | |
case LogLevel::VERBOSE: | |
return MAGENTA_COLOR_CODE; | |
default: | |
return GREEN_COLOR_CODE; | |
} | |
} | |
int map_log_level(const LogLevel level) | |
{ | |
switch(level) | |
{ | |
case LogLevel::NONE: | |
return ESP_LOG_NONE; | |
case LogLevel::ERROR: | |
return ESP_LOG_ERROR; | |
case LogLevel::WARN: | |
return ESP_LOG_WARN; | |
case LogLevel::INFO: | |
return ESP_LOG_INFO; | |
case LogLevel::DEBUG: | |
return ESP_LOG_DEBUG; | |
case LogLevel::VERBOSE: | |
return ESP_LOG_VERBOSE; | |
default: | |
return ESP_LOG_INFO; | |
} | |
} | |
void ESP32SerialLogger::log_message(const char *tag, LogLevel level, const char *fmt, va_list args) | |
{ | |
if(xSemaphore == NULL) | |
{ | |
xSemaphore = xSemaphoreCreateMutex(); | |
} | |
if(xSemaphore != NULL && xSemaphoreTake(xSemaphore, (TickType_t) 20)) | |
{ | |
esp_log_level_t esp_log_level = (esp_log_level_t)map_log_level(level); | |
esp_log_write(esp_log_level, tag, "\033[0;%dm%c (%ld) %s: ", get_console_color_code(level), get_error_char(level), esp_log_timestamp(), tag); | |
esp_log_writev(esp_log_level, tag, fmt, args); | |
esp_log_write(esp_log_level, tag, "\033[0m\n"); | |
xSemaphoreGive(xSemaphore); | |
} | |
else{ | |
printf("could not get semaphore\n"); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef ESP_SERIAL_LOGGER_H | |
#define ESP_SERIAL_LOGGER_H | |
#include <logging.h> | |
#include <stdarg.h> | |
class ESP32SerialLogger : public ILogHandler | |
{ | |
public: | |
void log_message(const char *tag, const LogLevel level, const char *fmt, va_list args) override; | |
}; | |
#endif // ESP_SERIAL_LOGGER_H |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "logging.h" | |
LogManager *LogManager::_log_manager = nullptr; | |
LogManager *LogManager::GetInstance() | |
{ | |
if(_log_manager == nullptr) | |
{ | |
_log_manager = new LogManager(); | |
} | |
return _log_manager; | |
} | |
void LogManager::dispatch_message(const char *tag, const LogLevel level, const char *fmt, va_list args) | |
{ | |
if (_log_level >= level) | |
{ | |
for(auto& log_handler: _log_handlers) | |
{ | |
log_handler->log_message(tag, level, fmt, args); | |
} | |
} | |
} | |
void LogManager::add_logger(ILogHandler *log_handler) | |
{ | |
_log_handlers.push_back(log_handler); | |
} | |
void LogManager::remove_logger(ILogHandler *log_handler) | |
{ | |
_log_handlers.remove(log_handler); | |
} | |
void LogManager::verbose(const char *tag, const char *fmt, ...) | |
{ | |
va_list args; | |
va_start(args, fmt); | |
dispatch_message(tag, LogLevel::VERBOSE, fmt, args); | |
va_end(args); | |
} | |
void LogManager::debug(const char *tag, const char *fmt, ...) | |
{ | |
va_list args; | |
va_start(args, fmt); | |
dispatch_message(tag, LogLevel::DEBUG, fmt, args); | |
va_end(args); | |
} | |
void LogManager::info(const char *tag, const char *fmt, ...) | |
{ | |
va_list args; | |
va_start(args, fmt); | |
dispatch_message(tag, LogLevel::INFO, fmt, args); | |
va_end(args); | |
} | |
void LogManager::warn(const char *tag, const char *fmt, ...) | |
{ | |
va_list args; | |
va_start(args, fmt); | |
dispatch_message(tag, LogLevel::WARN, fmt, args); | |
va_end(args); | |
} | |
void LogManager::error(const char *tag, const char *fmt, ...) | |
{ | |
va_list args; | |
va_start(args, fmt); | |
dispatch_message(tag, LogLevel::ERROR, fmt, args); | |
va_end(args); | |
} | |
void LogManager::set_log_level(LogLevel level) | |
{ | |
_log_level = level; | |
} | |
LogLevel LogManager::get_log_level() | |
{ | |
return _log_level; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef LOGGER_H | |
#define LOGGER_H | |
#include <stdarg.h> | |
#include <list> | |
enum class LogLevel | |
{ | |
NONE = 0, | |
ERROR, | |
WARN, | |
INFO, | |
DEBUG, | |
VERBOSE | |
}; | |
class ILogHandler | |
{ | |
public: | |
virtual void log_message(const char *tag, const LogLevel level, const char *fmt, va_list args) = 0; | |
}; | |
class LogManager | |
{ | |
private: | |
void dispatch_message(const char *tag, const LogLevel level, const char *fmt, va_list args); | |
LogManager() : _log_level(LogLevel::ERROR){} | |
std::list<ILogHandler*> _log_handlers; | |
static LogManager *_log_manager; | |
LogLevel _log_level; | |
public: | |
LogManager(LogManager &other) = delete; | |
void operator=(const LogManager &) = delete; | |
static LogManager *GetInstance(); | |
void add_logger(ILogHandler *log_handler); | |
void remove_logger(ILogHandler *log_handler); | |
void verbose(const char *tag, const char *fmt, ...); | |
void debug(const char *tag, const char *fmt, ...); | |
void info(const char *tag, const char *fmt, ...); | |
void warn(const char *tag, const char *fmt, ...); | |
void error(const char *tag, const char *fmt, ...); | |
void set_log_level(LogLevel level); | |
LogLevel get_log_level(); | |
}; | |
#endif //LOGGER_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment