mirror of
https://github.com/HASwitchPlate/openHASP.git
synced 2025-07-23 11:16:45 +00:00
Log using multiple print callbacks
This commit is contained in:
parent
6f4b72d429
commit
35f371b306
@ -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);
|
||||
|
@ -22,7 +22,7 @@ Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
#include "StringStream.h"
|
||||
typedef void (*printfunction)(int level, Print *, String &);
|
||||
typedef void (*printfunction)(int level, Print *);
|
||||
|
||||
//#include <stdint.h>
|
||||
//#include <stddef.h>
|
||||
@ -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;
|
||||
|
@ -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<uint16_t>();
|
||||
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()
|
||||
{
|
||||
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user