Hey, I’m just starting to play around with the new Logging interface that Particle Firmware provides since 0.6.0 and I am wondering if it is possible to change the Logging Level of a Logging Category within a Log Handler after it has been defined.
The use case I am thinking of is issuing a command via the serial monitor to change the Logging Level of a Logging Category on the fly.
Here is what I mean:
Lets say I declare a Log Handler containing a couple of Logging Categories as well as an instance of the Logger Class:
SerialLogHandler logHandler(LOG_LEVEL_WARN, //Default logging level for non-application messages
{
{ "app", LOG_LEVEL_INFO }, //Logging level for logs from "app" log category
{ "app.main", LOG_LEVEL_INFO}, //Logging level for logs from "app.main" log category
{ "app.adc", LOG_LEVEL_ALL} //Logging level for logs from "app.adc" log category
});
Logger myLogger("app.main");
Then somewhere in my main program I have code like this:
So, as it is, only the INFO message would be output to the serial monitor.
Now, let’s say I have a function that checks for serial input from the serial monitor. This function would check for a string like “app.main0” and parse the “0” from the string, which corresponds to the log level enum of LOG_LEVEL_ALL.
How do I go about changing the Logging Level for the “app.main” category within the logHandler object?
My understanding is that the Logging Levels and Logging Categories are hard coded when logHandler gets defined… but is there a way to change them after that?
Hi @jaza_tom. 0.6.0 supports only statically allocated log handlers, so you need at least 0.6.1 to configure and register log handlers dynamically. It’s not possible to change filtering for already existing handler, but you always can unregister current handler (or several handlers) and register another one with different settings:
#include "application.h"
SYSTEM_MODE(MANUAL)
void setup() {
// Configure serial interface
Serial1.begin(115200);
// Get log manager's instance
auto logManager = LogManager::instance();
// Configure and register log handler dynamically
LogCategoryFilters filters;
filters.append({ "app", LOG_LEVEL_INFO });
auto handler1 = new StreamLogHandler(Serial1, LOG_LEVEL_WARN /* Default level */, filters);
logManager->addHandler(handler1);
Log.trace("Trace message 1"); // Filtered out
// Unregister and destroy log handler
logManager->removeHandler(handler1);
delete handler1;
// Register another log handler with different settings
filters.clear();
filters.append({ "app", LOG_LEVEL_TRACE });
auto handler2 = new StreamLogHandler(Serial1, LOG_LEVEL_WARN, filters);
logManager->addHandler(handler2);
Log.trace("Trace message 2"); // Gets logged
// Unregister and destroy log handler
logManager->removeHandler(handler2);
delete handler2;
}
void loop() {
}