diff --git a/lib/ArduinoLog/ArduinoLog.cpp b/lib/ArduinoLog/ArduinoLog.cpp index f8748b50..cf107e66 100644 --- a/lib/ArduinoLog/ArduinoLog.cpp +++ b/lib/ArduinoLog/ArduinoLog.cpp @@ -31,12 +31,29 @@ SOFTWARE. #include "ArduinoLog.h" -void Logging::begin(int level, Print * logOutput, bool showLevel) +void Logging::begin(int level, bool showLevel) { #ifndef DISABLE_LOGGING setLevel(level); setShowLevel(showLevel); - _logOutput = logOutput; +#endif +} + +void Logging::registerOutput(uint8_t slot, Print * logOutput, int level, bool showLevel) +{ +#ifndef DISABLE_LOGGING + setLevel(level); + setShowLevel(showLevel); + if(slot >= 3) return; + _logOutput[slot] = logOutput; +#endif +} + +void Logging::unregisterOutput(uint8_t slot) +{ +#ifndef DISABLE_LOGGING + if(slot >= 3) return; + _logOutput[slot] = NULL; #endif } @@ -94,7 +111,7 @@ void Logging::print(Print * logOutput, const __FlashStringHelper * format, va_li for(; c != 0; c = pgm_read_byte(p++)) { if(c == '%') { c = pgm_read_byte(p++); - printFormat(logOutput, c, &args); + printFormat(logOutput, c, (va_list *)&args); } else { logOutput->print(c); } @@ -108,7 +125,7 @@ void Logging::print(Print * logOutput, const char * format, va_list args) for(; *format != 0; ++format) { if(*format == '%') { ++format; - printFormat(logOutput, *format, &args); + printFormat(logOutput, *format, (va_list *)&args); } else { //_logOutput->print(*format); logOutput->print(*format); diff --git a/lib/ArduinoLog/ArduinoLog.h b/lib/ArduinoLog/ArduinoLog.h index 1759f74d..739c2dc9 100644 --- a/lib/ArduinoLog/ArduinoLog.h +++ b/lib/ArduinoLog/ArduinoLog.h @@ -22,7 +22,7 @@ Licensed under the MIT License . #include "WProgram.h" #endif #include "StringStream.h" -typedef void (*printfunction)(int level, Print *, String &); +typedef void (*printfunction)(int level, Print *); //#include //#include @@ -85,7 +85,7 @@ class Logging { */ Logging() #ifndef DISABLE_LOGGING - : _level(LOG_LEVEL_SILENT), _showLevel(true), _logOutput(NULL) + : _level(LOG_LEVEL_SILENT), _showLevel(true) #endif {} @@ -99,7 +99,26 @@ class Logging { * \return void * */ - void begin(int level, Print * output, bool showLevel = true); + void begin(int level, bool showLevel = true); + + /** + * Register up to 3 printers to a certain slot + * + * \param slot - index of the printer to register. + * \param printer - place that logging output will be sent to. + * \return void + * + */ + void registerOutput(uint8_t slot, Print * logOutput, int level, bool showLevel); + + /** + * Unregister the printer in a certain slot + * + * \param slot - index of the printer to register. + * \return void + * + */ + void unregisterOutput(uint8_t slot); /** * Set the log level. @@ -265,37 +284,29 @@ class Logging { return; } - String debugOutput((char *)0); - StringStream debugStream((String &)debugOutput); - debugOutput.reserve(4 * 128); + for(uint8_t i = 0; i < 3; i++) { + if(_logOutput[i] == NULL) continue; - if(_prefix != NULL) { - _prefix(level, &debugStream, debugOutput); + if(_prefix != NULL) { + _prefix(level, _logOutput[i]); + } + + va_list args; + va_start(args, msg); + print(_logOutput[i], msg, args); + + if(_suffix != NULL) { + _suffix(level, _logOutput[i]); + } } - if(_showLevel) { - static const char levels[] = "FEWNTV"; - debugStream.print(levels[level - 1]); - debugStream.print(": "); - } - - va_list args; - va_start(args, msg); - print(&debugStream, msg, args); - - if(_suffix != NULL) { - _suffix(level, &debugStream, debugOutput); - } - - //_logOutput->print(debugOutput); - debugOutput.clear(); #endif } #ifndef DISABLE_LOGGING int _level; bool _showLevel; - Print * _logOutput; + Print * _logOutput[3]; printfunction _prefix = NULL; printfunction _suffix = NULL; diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp index be7b7a30..b6aa05de 100644 --- a/src/hasp_debug.cpp +++ b/src/hasp_debug.cpp @@ -73,6 +73,7 @@ bool debugSerialStarted = false; #define TERM_COLOR_GRAY "\e[37m" #define TERM_COLOR_RED "\e[91m" #define TERM_COLOR_GREEN "\e[92m" +#define TERM_COLOR_ORANGE "\e[38;5;214m" #define TERM_COLOR_YELLOW "\e[93m" #define TERM_COLOR_BLUE "\e[94m" #define TERM_COLOR_MAGENTA "\e[35m" @@ -191,7 +192,7 @@ void syslogSend(uint8_t priority, const char * debugText) void debugSetup(JsonObject settings) { - debugSetConfig(settings); + // debugSetConfig(settings); #if HASP_USE_SYSLOG != 0 syslog = new Syslog(syslogClient, debugSyslogProtocol == 0 ? SYSLOG_PROTO_IETF : SYSLOG_PROTO_BSD); @@ -257,76 +258,121 @@ bool debugSetConfig(const JsonObject & settings) return changed; } -static void printTimestamp(int level, Print * _logOutput, String & debugOutput) +/* +void debugSendOuput(const char * buffer) { - char buffer[128]; - - /* Print Current Time */ - time_t rawtime; - struct tm * timeinfo; - // if(!time(nullptr)) return; - time(&rawtime); - timeinfo = localtime(&rawtime); - - strftime(buffer, sizeof(buffer), ("[%b %d %H:%M:%S."), timeinfo); - if(debugSerialStarted) { - if(debugAnsiCodes) Serial.print(TERM_COLOR_CYAN); - Serial.print(buffer); - } - if(debugAnsiCodes) telnetPrint(TERM_COLOR_CYAN); - telnetPrint(buffer); - - /* Print Memory Info */ - snprintf(buffer, sizeof(buffer), PSTR("%8.3fs] %5u/%5u %2u | "), float(millis()) / 1000, halGetMaxFreeBlock(), - ESP.getFreeHeap(), halGetHeapFragmentation()); - if(debugSerialStarted) { - if(debugAnsiCodes) Serial.print(buffer); - } - telnetPrint(buffer); - -#if LV_MEM_CUSTOM == 0 - /* lv_mem_monitor_t mem_mon; - lv_mem_monitor(&mem_mon); - debugTimeText += F("| "); - debugTimeText += mem_mon.used_pct; - debugTimeText += F("% "); - debugTimeText += mem_mon.free_biggest_size; - debugTimeText += F("b/"); - debugTimeText += mem_mon.free_size; - debugTimeText += F("b "); - debugTimeText += (mem_mon.total_size - mem_mon.free_size); - debugTimeText += F("b | ");*/ -#endif - - switch(level) { - case LOG_LEVEL_FATAL: - case LOG_LEVEL_ERROR: - strcpy(buffer, TERM_COLOR_RED); - break; - case LOG_LEVEL_WARNING: - strcpy(buffer, TERM_COLOR_YELLOW); - break; - case LOG_LEVEL_NOTICE: - strcpy(buffer, TERM_COLOR_WHITE); - break; - case LOG_LEVEL_VERBOSE: - strcpy(buffer, TERM_COLOR_CYAN); - break; - case LOG_LEVEL_TRACE: - strcpy(buffer, TERM_COLOR_GRAY); - break; - default: - strcpy(buffer, TERM_COLOR_RESET); - } - - if(debugSerialStarted) { - if(debugAnsiCodes) Serial.print(buffer); - } + if(debugSerialStarted) Serial.print(buffer); telnetPrint(buffer); } -static void printNewline(int level, Print * _logOutput, String & debugOutput) +void debugSendOuput(const __FlashStringHelper * txt) { + if(debugSerialStarted) Serial.print(txt); + telnetPrint(txt); +} +*/ + +inline void debugSendAnsiCode(char * buffer, Print * _logOutput) +{ + if(debugAnsiCodes) _logOutput->print(buffer); +} + +static void debugPrintTimestamp(int level, Print * _logOutput) +{ /* Print Current Time */ + time_t rawtime; + struct tm * timeinfo; + + time(&rawtime); + timeinfo = localtime(&rawtime); + + debugSendAnsiCode(TERM_COLOR_CYAN, _logOutput); + // strftime(buffer, sizeof(buffer), ("[%b %d %H:%M:%S."), timeinfo); + // strftime(buffer, sizeof(buffer), ("[%H:%M:%S."), timeinfo); + if(timeinfo->tm_year >= 2020) { + char buffer[64]; + strftime(buffer, sizeof(buffer), PSTR("[%b %d %H:%M:%S."), timeinfo); // Literal String + _logOutput->print(buffer); + _logOutput->printf(PSTR("%03u]"), millis() % 1000); + } else { + _logOutput->printf(PSTR("[%20.3f]"), (float)millis() / 1000); + } +} + +static void debugPrintHaspMemory(int level, Print * _logOutput) +{ + size_t maxfree = halGetMaxFreeBlock(); + uint32_t totalfree = ESP.getFreeHeap(); + uint8_t frag = halGetHeapFragmentation(); + + /* Print HASP Memory Info */ + if(debugAnsiCodes) { + if(maxfree > (1024u * 5) && (totalfree > 1024u * 6) && (frag <= 10)) + debugSendAnsiCode(TERM_COLOR_GREEN, _logOutput); + else if(maxfree > (1024u * 3) && (totalfree > 1024u * 5) && (frag <= 20)) + debugSendAnsiCode(TERM_COLOR_ORANGE, _logOutput); + else + debugSendAnsiCode(TERM_COLOR_RED, _logOutput); + } + _logOutput->printf(PSTR("[%5u/%5u %2u] "), maxfree, totalfree, frag); +} + +#if LV_MEM_CUSTOM == 0 +static void debugPrintLvglMemory(int level, Print * _logOutput) +{ + lv_mem_monitor_t mem_mon; + lv_mem_monitor(&mem_mon); + + /* Print LVGL Memory Info */ + if(debugAnsiCodes) { + if(mem_mon.free_biggest_size > (1024u * 2) && (mem_mon.free_size > 1024u * 2.5) && (mem_mon.frag_pct <= 10)) + debugSendAnsiCode(TERM_COLOR_GREEN, _logOutput); + else if(mem_mon.free_biggest_size > (1024u * 1) && (mem_mon.free_size > 1024u * 1.5) && + (mem_mon.frag_pct <= 25)) + debugSendAnsiCode(TERM_COLOR_ORANGE, _logOutput); + else + debugSendAnsiCode(TERM_COLOR_RED, _logOutput); + } + _logOutput->printf(PSTR("[%5u/%5u %2u] "), mem_mon.free_biggest_size, mem_mon.free_size, mem_mon.frag_pct); +} +#endif + +static void debugPrintPriority(int level, Print * _logOutput) +{ + switch(level) { + case LOG_LEVEL_FATAL: + case LOG_LEVEL_ERROR: + debugSendAnsiCode(TERM_COLOR_RED, _logOutput); + break; + case LOG_LEVEL_WARNING: + debugSendAnsiCode(TERM_COLOR_YELLOW, _logOutput); + break; + case LOG_LEVEL_NOTICE: + debugSendAnsiCode(TERM_COLOR_WHITE, _logOutput); + break; + case LOG_LEVEL_VERBOSE: + debugSendAnsiCode(TERM_COLOR_CYAN, _logOutput); + break; + case LOG_LEVEL_TRACE: + debugSendAnsiCode(TERM_COLOR_GRAY, _logOutput); + break; + default: + debugSendAnsiCode(TERM_COLOR_RESET, _logOutput); + } +} + +void debugPrintPrefix(int level, Print * _logOutput) +{ + debugPrintTimestamp(level, _logOutput); + debugPrintHaspMemory(level, _logOutput); +#if LV_MEM_CUSTOM == 0 + debugPrintLvglMemory(level, _logOutput); +#endif + debugPrintPriority(level, _logOutput); +} + +void debugPrintSuffix(int level, Print * _logOutput) +{ + /* if(debugSerialStarted) { Serial.print(debugOutput); if(debugAnsiCodes) Serial.print(TERM_COLOR_RESET); @@ -334,37 +380,74 @@ static void printNewline(int level, Print * _logOutput, String & debugOutput) if(debugAnsiCodes) Serial.print(TERM_COLOR_MAGENTA); } - telnetPrint(debugOutput.c_str()); + telnetPrint(debugOutput); if(debugAnsiCodes) telnetPrint(TERM_COLOR_RESET); telnetPrint("\r\n"); if(debugAnsiCodes) telnetPrint(TERM_COLOR_MAGENTA); +*/ - syslogSend(level, debugOutput.c_str()); + if(debugAnsiCodes) + _logOutput->println(TERM_COLOR_RESET); + else + _logOutput->println(); + if(debugAnsiCodes) _logOutput->print(TERM_COLOR_MAGENTA); + + // syslogSend(level, debugOutput); } void debugPreSetup(JsonObject settings) { // Link stream to debugOutput // debugOutput.reserve(512); - Log.begin(LOG_LEVEL_VERBOSE, &Serial, true); - Log.setPrefix(printTimestamp); // Uncomment to get timestamps as prefix - Log.setSuffix(printNewline); // Uncomment to get newline as suffix + Log.begin(LOG_LEVEL_VERBOSE, true); + Log.setPrefix(debugPrintPrefix); // Uncomment to get timestamps as prefix + Log.setSuffix(debugPrintSuffix); // Uncomment to get newline as suffix uint16_t baudrate = settings[FPSTR(F_CONFIG_BAUD)].as(); if(baudrate > 0) { Serial.begin(baudrate * 10); /* prepare for possible serial debug */ delay(10); debugSerialStarted = true; + Log.registerOutput(0, &Serial, LOG_LEVEL_VERBOSE, true); + Log.trace(F("Serial started at %u baud"), baudrate * 10); } // Serial.begin(74880); /* prepare for possible serial debug */ // Serial.begin(115200); } +#if LV_USE_LOG != 0 +void debugLvgl(lv_log_level_t level, const char * file, uint32_t line, const char * funcname, const char * descr) +{ + switch(level) { + case LV_LOG_LEVEL_TRACE: + Log.trace(descr); + // debugPrintPrefix(LOG_LEVEL_TRACE, NULL); + break; + case LV_LOG_LEVEL_WARN: + Log.warning(descr); + // debugPrintPrefix(LOG_LEVEL_WARNING, NULL); + break; + case LV_LOG_LEVEL_ERROR: + Log.error(descr); + // debugPrintPrefix(LOG_LEVEL_ERROR, NULL); + break; + default: + Log.notice(descr); + // debugPrintPrefix(LOG_LEVEL_WARNING, NULL); + } + /* + debugSendOuput(F("LVGL: ")); + debugSendOuput(descr); + debugSendOuput(F("\r\n")); + syslogSend(level, descr);*/ +} +#endif + void debugLoop() {} -void printLocalTime() +/*void printLocalTime() { char buffer[128]; time_t rawtime; @@ -400,7 +483,7 @@ void printLocalTime() } } #endif -} +}*/ void debugEverySecond() { diff --git a/src/hasp_debug.h b/src/hasp_debug.h index 262c0666..dc670a7b 100644 --- a/src/hasp_debug.h +++ b/src/hasp_debug.h @@ -2,6 +2,7 @@ #define HASP_DEBUG_H #include "ArduinoJson.h" +#include "lvgl.h" String debugHaspHeader(void); @@ -20,4 +21,9 @@ void syslogSend(uint8_t log, const char * debugText); bool debugGetConfig(const JsonObject & settings); bool debugSetConfig(const JsonObject & settings); +// void debugPrintPrefix(int level, Print * _logOutput); +// void debugPrintSuffix(int level, Print * _logOutput); +// void debugSendOuput(const char * buffer); +void debugLvgl(lv_log_level_t level, const char * file, uint32_t line, const char * funcname, const char * descr); + #endif \ No newline at end of file