From 046b77d90af83d415a91b65561726046f7152a8f Mon Sep 17 00:00:00 2001 From: Christopher LaPointe Date: Fri, 23 Nov 2018 13:26:19 -0500 Subject: [PATCH 1/4] Logging framework first pass --- examples/unix/main.cpp | 7 +++ src/ubsub_log.h | 103 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 src/ubsub_log.h diff --git a/examples/unix/main.cpp b/examples/unix/main.cpp index 0732a8b..28c22c2 100644 --- a/examples/unix/main.cpp +++ b/examples/unix/main.cpp @@ -1,6 +1,7 @@ #include #include #include "../../src/ubsub.h" +#include "../../src/ubsub_log.h" void myMethod(const char* arg) { std::cout << "RECEIVED: " << arg << std::endl; @@ -13,8 +14,12 @@ int main() { if (!client.connect(2)) { std::cout << "Failed to connect" << std::endl; } + initUbsubLogger(&client); + // setLoggerDeviceId("test"); // client.enableAutoRetry(false); + UINFO("Welcome to the logging test!"); + client.listenToTopic("testy", myMethod); client.publishEvent("Byg2kKB3SZ", "HJ3ytS3SW", "Hi there"); @@ -27,6 +32,8 @@ int main() { client.watchVariable("other", &test); client.watchVariable("var", &test); // Any time this value changes, an event will be emitted + UWARN("Done with watch %d", test); + while(true) { test++; client.processEvents(); diff --git a/src/ubsub_log.h b/src/ubsub_log.h new file mode 100644 index 0000000..cc00782 --- /dev/null +++ b/src/ubsub_log.h @@ -0,0 +1,103 @@ +/** +Ubsub log wrapper to send log events to ubsub (or other sources) +**/ + +#ifndef ubsub_log_h +#define ubsub_log_h + +#ifndef UBSUB_LOG_DISABLE + + #if (!ARDUINO || PARTICLE) + #include + #include + #include + #else + #warning Logs are enabled on IoT device, may consume extra string memory! + #include + #endif + #include + #include "ubsub.h" + #include "minijson.h" + + #ifndef ULOG_BUF_SIZE + #define ULOG_BUF_SIZE 512 + #endif + + #ifndef ULOG_TOPIC + #define ULOG_TOPIC "log" + #endif + + static const char* _deviceId = NULL; + static Ubsub* _conn = NULL; + + void initUbsubLogger(const char *deviceId, const char *deviceKey) { + if (_conn == NULL) { + _conn = new Ubsub(deviceId, deviceKey); + _conn->enableAutoRetry(false); + _conn->connect(); + } + } + void initUbsubLogger(Ubsub* conn) { + _conn = conn; + } + void setLoggerDeviceId(const char* deviceId) { + _deviceId = strdup(deviceId); + } + void shutdownLogger() { + if (_conn != NULL) { + delete _conn; + _conn = NULL; + } + } + + static void writeULog(const char* level, const char* filename, int line, const char* msg, ...) { + static char logbuf[ULOG_BUF_SIZE]; + va_list argptr; + va_start(argptr, msg); + vsnprintf(logbuf, sizeof(logbuf), msg, argptr); + va_end(argptr); + + #ifdef UBSUB_LOG_SERIAL + #if ARDUINO || PARTICLE + Serial.printf("[%s] (%s:%d) %s\n", level, filename, line, logbuf); + Serial.flush(); + #else + std::cerr << "[" << level << "] (" << filename << ":" << line << ") " << logbuf << std::endl; + #endif + #endif + + if (_conn != NULL) { + char jsonBuf[ULOG_BUF_SIZE]; // Buffer on stack + MiniJsonBuilder json(jsonBuf, ULOG_BUF_SIZE); + json.open() + .write("level", level) + .write("filename", filename) + .write("line", line) + .write("msg", logbuf); + if (_deviceId != NULL) { + json.write("device", _deviceId); + } + json.close(); + + _conn->callFunction(ULOG_TOPIC, json.c_str()); + } + } + + #define UINFO(msg, ...) writeULog("INFO", __FILE__, __LINE__, msg, ## __VA_ARGS__) + #define UWARN(msg, ...) writeULog("WARN", __FILE__, __LINE__, msg, ## __VA_ARGS__) + #define UERROR(msg, ...) writeULog("ERROR", __FILE__, __LINE__, msg, ## __VA_ARGS__) + #define UDEBUG(msg, ...) writeULog("DEBUG", __FILE__, __LINE__, msg, ## __VA_ARGS__) + +#else + // Ubsub log disabled, nullify log statements + #define initUbsubLogger + #define setLoggerDeviceId + #define shutdownLogger + + #define UINFO(msg, ...) + #define UWARN(msg, ...) + #define UERROR(msg, ...) + #define UDEBUG(msg, ...) +#endif + +#endif From 87799f4fcd6ba7e419d3b949db73beacb2ceb2a3 Mon Sep 17 00:00:00 2001 From: Christopher LaPointe Date: Fri, 23 Nov 2018 16:50:52 -0500 Subject: [PATCH 2/4] Add some documentation to ULOG --- README.md | 30 ++++++++++++++++++++++++++++++ src/ubsub_log.h | 10 ++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ce233ce..f1bbd3b 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,36 @@ void loop() { } ``` +## Using the logging API + +As an addon to the Ubsub API, there is also a simple logging API +to help you send out log messages to ubsub (in additional to serial/stdout). + +### Configuration +``` +ULOG_DISABLE Disable all logging if defined (macro to nothing) +ULOG_BUF_SIZE Override default buffer size (default: 512) +ULOG_TOPIC Override topic to write log messages to (default: "log") +ULOG_SERIAL Enable serial output (or stdout if unix) +``` + +### Example +```cpp +#include "ubsub_log.h" + +void setup() { + initUbsubLogger("id", "key"); + + // If you already have an ubsub instance: + // initUbsubLogger(&ubsub); + + ULOG("hi there %s", "name"); + UWARN("..."); + UERROR("..."); + UDEBUG("..."); +} +``` + # API ## Ubsub(const char* deviceId, const char* deviceKey) diff --git a/src/ubsub_log.h b/src/ubsub_log.h index cc00782..769f4d2 100644 --- a/src/ubsub_log.h +++ b/src/ubsub_log.h @@ -1,11 +1,17 @@ /** Ubsub log wrapper to send log events to ubsub (or other sources) + +Configuration: +ULOG_DISABLE Disable all logging if defined (macro to nothing) +ULOG_BUF_SIZE Override default buffer size (default: 512) +ULOG_TOPIC Override topic to write log messages to (default: "log") +ULOG_SERIAL Enable serial output (or stdout if unix) **/ #ifndef ubsub_log_h #define ubsub_log_h -#ifndef UBSUB_LOG_DISABLE +#ifndef ULOG_DISABLE #if (!ARDUINO || PARTICLE) #include @@ -57,7 +63,7 @@ Ubsub log wrapper to send log events to ubsub (or other sources) vsnprintf(logbuf, sizeof(logbuf), msg, argptr); va_end(argptr); - #ifdef UBSUB_LOG_SERIAL + #ifdef ULOG_SERIAL #if ARDUINO || PARTICLE Serial.printf("[%s] (%s:%d) %s\n", level, filename, line, logbuf); Serial.flush(); From 481966a59caf17e6b70a317b0fc42ede673940c6 Mon Sep 17 00:00:00 2001 From: Christopher LaPointe Date: Fri, 23 Nov 2018 17:18:08 -0500 Subject: [PATCH 3/4] Disable debug macro by default --- README.md | 1 + src/ubsub_log.h | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f1bbd3b..6a32fd8 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,7 @@ ULOG_DISABLE Disable all logging if defined (macro to nothing) ULOG_BUF_SIZE Override default buffer size (default: 512) ULOG_TOPIC Override topic to write log messages to (default: "log") ULOG_SERIAL Enable serial output (or stdout if unix) +ULOG_DEBUG If defined, will enable UDEBUG macro output ``` ### Example diff --git a/src/ubsub_log.h b/src/ubsub_log.h index 769f4d2..a385310 100644 --- a/src/ubsub_log.h +++ b/src/ubsub_log.h @@ -6,6 +6,7 @@ ULOG_DISABLE Disable all logging if defined (macro to nothing) ULOG_BUF_SIZE Override default buffer size (default: 512) ULOG_TOPIC Override topic to write log messages to (default: "log") ULOG_SERIAL Enable serial output (or stdout if unix) +ULOG_DEBUG If defined, will enable UDEBUG macro output **/ #ifndef ubsub_log_h @@ -92,7 +93,9 @@ ULOG_SERIAL Enable serial output (or stdout if unix) #define UINFO(msg, ...) writeULog("INFO", __FILE__, __LINE__, msg, ## __VA_ARGS__) #define UWARN(msg, ...) writeULog("WARN", __FILE__, __LINE__, msg, ## __VA_ARGS__) #define UERROR(msg, ...) writeULog("ERROR", __FILE__, __LINE__, msg, ## __VA_ARGS__) - #define UDEBUG(msg, ...) writeULog("DEBUG", __FILE__, __LINE__, msg, ## __VA_ARGS__) + #ifdef ULOG_DEBUG + #define UDEBUG(msg, ...) writeULog("DEBUG", __FILE__, __LINE__, msg, ## __VA_ARGS__) + #endif #else // Ubsub log disabled, nullify log statements From 7382912869c9f4eb9f284fe1f86296253b743685 Mon Sep 17 00:00:00 2001 From: Christopher LaPointe Date: Fri, 23 Nov 2018 18:01:20 -0500 Subject: [PATCH 4/4] Make sure to define UDEBUG --- src/ubsub_log.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ubsub_log.h b/src/ubsub_log.h index a385310..bfbb18b 100644 --- a/src/ubsub_log.h +++ b/src/ubsub_log.h @@ -95,6 +95,8 @@ ULOG_DEBUG If defined, will enable UDEBUG macro output #define UERROR(msg, ...) writeULog("ERROR", __FILE__, __LINE__, msg, ## __VA_ARGS__) #ifdef ULOG_DEBUG #define UDEBUG(msg, ...) writeULog("DEBUG", __FILE__, __LINE__, msg, ## __VA_ARGS__) + #else + #define UDEBUG(msg, ...) #endif #else