This is a touch early but I am pretty excited about the new Logging feature and what it can do for users and lib maintainers. I will be updating the DS18B20 to take advantage of the Logging feature so that users can opt in to whatever level of info they choose. In working on that I learned (after opening a GitHub issue that was my own lack of knowledge, thanks @jvanier for setting me straight) how to use the logging feature from inside a lib/custom class. So the Particle crew doesn’t have to repeat themselves the below is a simple example of how to use the Logging/Logger feature in your own apps.
Loop/Main - Whatever you want to call it. This is simple example that outputs “Logged in loop.” and “Log from Custom Class” every 30 seconds. What to take note of here is that Log is a default Logger instance tied to the “app” category. In order to use Log you will need to create a logHandler as such SerialLogHandler logHandler;
as of today there is only a SerialLogHandler
but I hope that Particle will see fit to create a “Cloud” log handler as a bit of a shortcut to Publish…hint, hint. In the example below you can see three Log Levels being set: LOG_LEVEL_WARN
applies to non-application messages (I assume system firmware), app, LOG_LEVEL_TRACE
(this is the default Log instance with category app) applies to code within your ino and app.custom LOG_LEVEL_TRACE
in this instance applies to the Custom lib/class category. You can see how the Logger myLog instance from Custom.cpp “hooks” into this statement.
// This #include statement was automatically added by the Particle IDE.
#include "Custom.h"
#include "application.h"
#define LOGGING_ON TRUE
#if (LOGGING_ON)
SerialLogHandler logHandler(LOG_LEVEL_WARN, {
{ "app", LOG_LEVEL_TRACE },
{ "app.custom", LOG_LEVEL_TRACE }
});
#endif
Custom myObj;
const int myLog_tempo = 30000;
int next_log;
void setup() {
Log.trace("Logging Enabled, moving to Loop");
}
void loop() {
if (millis() > next_log){
Log.info("Logged in loop.");
myObj.some_function();
next_log = millis() + myLog_tempo;
}
}
Custom.cpp - Only the CPP really matters for this tutorial as that is where you should instantiate a Logger instance for a given class/lib. This is where I went wrong in trying to use the Logging feature. You can also place the static keyword in front of Logger myLog("app.whatever");
in order to reuse myLog in other CPP files.
#include "Custom.h"
Logger myLog("app.custom");
Custom::Custom() {
}
Custom::~Custom() {
}
void Custom::some_function(){
myLog.info("Log from custom class.");
}
As you can see above I use the myLog Logger instance to send a log message that is “tagged” as being an info level log. If you remember above myLog is associated with the app.custom category so the output from calling the some_function(); function would be as follows:
0000000044 [app.custom] INFO: Log from custom class.
Custom.h - Has no bearing on Logging.
#include "application.h"
#ifndef Custom_h
#define Custom_h
class Custom {
private:
public:
Custom();
~Custom();
void some_function();
};
#endif /* Custom_h */
Using the info from above you should be able to add custom logging categories and loggers to your favorite libs and classes. Go forth and destroy those Serial.print statements!!!