From 69cdacaac7cb33fb4f341effae6d9ec814e2503c Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 15 Dec 2023 11:33:12 +0100 Subject: [PATCH 1/2] Enhancement: log to syslog server instead of web-serial --- src/utils/syslog.cpp | 99 ++++++++++++++++++++++++++++++++++++++++++++ src/utils/syslog.h | 54 ++++++++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 src/utils/syslog.cpp create mode 100644 src/utils/syslog.h diff --git a/src/utils/syslog.cpp b/src/utils/syslog.cpp new file mode 100644 index 00000000..5e73f287 --- /dev/null +++ b/src/utils/syslog.cpp @@ -0,0 +1,99 @@ +#include +#include "syslog.h" + +#ifdef ENABLE_SYSLOG + +#define SYSLOG_MAX_PACKET_SIZE 256 + + +//----------------------------------------------------------------------------- +void DbgSyslog::setup(settings_t *config) { + mConfig = config; + + // Syslog callback overrides web-serial callback + registerDebugCb(std::bind(&DbgSyslog::syslogCb, this, std::placeholders::_1)); // dbg.h +} + +//----------------------------------------------------------------------------- +void DbgSyslog::syslogCb (String msg) +{ + if (!mSyslogIP.isSet()) { + // use WiFi.hostByName to DNS lookup for IPAddress of syslog server + if (WiFi.status() == WL_CONNECTED) { + WiFi.hostByName(SYSLOG_HOST,mSyslogIP); + } + } + if (!mSyslogIP.isSet()) { + return; + } + uint16_t msgLength = msg.length(); + uint16_t msgPos = 0; + + do { + uint16_t charsToCopy = std::min(msgLength-msgPos,SYSLOG_BUF_SIZE - mSyslogBufFill); + + while (charsToCopy > 0) { + mSyslogBuffer[mSyslogBufFill] = msg[msgPos]; + msgPos++; + mSyslogBufFill++; + charsToCopy--; + } + mSyslogBuffer[mSyslogBufFill] = '\0'; + + bool isBufferFull = (mSyslogBufFill == SYSLOG_BUF_SIZE); + bool isEolFound = false; + if (mSyslogBufFill >= 2) { + isEolFound = (mSyslogBuffer[mSyslogBufFill-2] == '\r' && mSyslogBuffer[mSyslogBufFill-1] == '\n'); + } + // Get severity from input message + if (msgLength >= 2) { + if (':' == msg[1]) { + switch(msg[0]) { + case 'E': mSyslogSeverity = PRI_ERROR; break; + case 'W': mSyslogSeverity = PRI_WARNING; break; + case 'I': mSyslogSeverity = PRI_INFO; break; + case 'D': mSyslogSeverity = PRI_DEBUG; break; + default: mSyslogSeverity = PRI_NOTICE; break; + } + } + } + + if (isBufferFull || isEolFound) { + // Send mSyslogBuffer in chunks because mSyslogBuffer is larger than syslog packet size + int packetStart = 0; + int packetSize = 122; // syslog payload depends also on hostname and app + char saveChar; + if (isEolFound) { + mSyslogBuffer[mSyslogBufFill-2]=0; // skip \r\n + } + while(packetStart < mSyslogBufFill) { + saveChar = mSyslogBuffer[packetStart+packetSize]; + mSyslogBuffer[packetStart+packetSize] = 0; + log(mConfig->sys.deviceName,SYSLOG_FACILITY, mSyslogSeverity, &mSyslogBuffer[packetStart]); + mSyslogBuffer[packetStart+packetSize] = saveChar; + packetStart += packetSize; + } + mSyslogBufFill = 0; + } + + } while (msgPos < msgLength); // Message not completely processed + +} + +//----------------------------------------------------------------------------- +void DbgSyslog::log(const char *hostname, uint8_t facility, uint8_t severity, char* msg) { + // The PRI value is an integer number which calculates by the following metric: + uint8_t priority = (8 * facility) + severity; + + // This is a unit8 instead of a char because that's what udp.write() wants + uint8_t buffer[SYSLOG_MAX_PACKET_SIZE]; + int len = snprintf((char*)buffer, SYSLOG_MAX_PACKET_SIZE, "<%d>%s %s: %s", priority, hostname, SYSLOG_APP, msg); + //printf("syslog::log %s\n",mSyslogIP.toString().c_str()); + //printf("syslog::log %d %s\n",len,buffer); + // Send the raw UDP packet + mSyslogUdp.beginPacket(mSyslogIP, SYSLOG_PORT); + mSyslogUdp.write(buffer, len); + mSyslogUdp.endPacket(); +} + +#endif \ No newline at end of file diff --git a/src/utils/syslog.h b/src/utils/syslog.h new file mode 100644 index 00000000..aac9db14 --- /dev/null +++ b/src/utils/syslog.h @@ -0,0 +1,54 @@ + +#ifndef __SYSLOG_H__ +#define __SYSLOG_H__ + +#ifdef ESP8266 + #include +#elif defined(ESP32) + #include +#endif +#include +#include "../config/config.h" +#include "../config/settings.h" + +#ifdef ENABLE_SYSLOG + +#define SYSLOG_BUF_SIZE 255 + +#define PRI_EMERGENCY 0 +#define PRI_ALERT 1 +#define PRI_CRITICAL 2 +#define PRI_ERROR 3 +#define PRI_WARNING 4 +#define PRI_NOTICE 5 +#define PRI_INFO 6 +#define PRI_DEBUG 7 + +#define FAC_USER 1 +#define FAC_LOCAL0 16 +#define FAC_LOCAL1 17 +#define FAC_LOCAL2 18 +#define FAC_LOCAL3 19 +#define FAC_LOCAL4 20 +#define FAC_LOCAL5 21 +#define FAC_LOCAL6 22 +#define FAC_LOCAL7 23 + +class DbgSyslog { + public: + void setup (settings_t *config); + void syslogCb(String msg); + void log(const char *hostname, uint8_t facility, uint8_t severity, char* msg); + + private: + WiFiUDP mSyslogUdp; + IPAddress mSyslogIP; + settings_t *mConfig; + char mSyslogBuffer[SYSLOG_BUF_SIZE+1]; + uint16_t mSyslogBufFill = 0; + int mSyslogSeverity = PRI_NOTICE; +}; + +#endif + +#endif \ No newline at end of file From 21848bd5ae5f163e3add306db0163fbadf41567f Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 15 Dec 2023 11:33:48 +0100 Subject: [PATCH 2/2] Enhancement: log to syslog server instead of web-serial --- src/app.cpp | 3 +++ src/app.h | 4 ++++ src/config/config_override_example.h | 9 +++++++++ 3 files changed, 16 insertions(+) diff --git a/src/app.cpp b/src/app.cpp index d670c696..82e25724 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -82,6 +82,9 @@ void app::setup() { mApi.setup(this, &mSys, mWeb.getWebSrvPtr(), mConfig); + #ifdef ENABLE_SYSLOG + mDbgSyslog.setup(mConfig); // be sure to init after mWeb.setup (webSerial uses also debug callback) + #endif // Plugins #if defined(PLUGIN_DISPLAY) if (mConfig->plugin.display.type != 0) diff --git a/src/app.h b/src/app.h index a71ee03c..a24cccb3 100644 --- a/src/app.h +++ b/src/app.h @@ -22,6 +22,7 @@ #include "utils/crc.h" #include "utils/dbg.h" #include "utils/scheduler.h" +#include "utils/syslog.h" #include "web/RestApi.h" #include "web/web.h" #include "hm/Communication.h" @@ -311,6 +312,9 @@ class app : public IApp, public ah::Scheduler { #endif /* defined(ETHERNET) */ WebType mWeb; RestApiType mApi; + #ifdef ENABLE_SYSLOG + DbgSyslog mDbgSyslog; + #endif //PayloadType mPayload; //MiPayloadType mMiPayload; PubSerialType mPubSerial; diff --git a/src/config/config_override_example.h b/src/config/config_override_example.h index c653bf10..b90bbdbd 100644 --- a/src/config/config_override_example.h +++ b/src/config/config_override_example.h @@ -35,4 +35,13 @@ // #define ENABLE_PROMETHEUS_EP +// to enable the syslog logging (will disable web-serial) +//#define ENABLE_SYSLOG +#ifdef ENABLE_SYSLOG +#define SYSLOG_HOST "" +#define SYSLOG_APP "ahoy" +#define SYSLOG_FACILITY FAC_USER +#define SYSLOG_PORT 514 +#endif + #endif /*__CONFIG_OVERRIDE_H__*/