Logging

Logging categories

In addition to logging level, log messages can also be associated with some category name. Categories allow to organize system and application modules into namespaces, and are used for more selective filtering of the logging output.

One of the typical use cases for category filtering is suppressing of non-critical system messages while preserving application messages at lower logging levels. In the provided example, a message that is not associated with the app category will be logged only if its logging level is at or above the warning level (LOG_LEVEL_WARN).

// EXAMPLE - filtering out system messages

SerialLogHandler logHandler(LOG_LEVEL_WARN, { // Logging level for non-application messages
    { "app", LOG_LEVEL_ALL } // Logging level for application messages
});

Default Log logger uses app category for all messages generated via its logging methods. In order to log messages with different category name it is necessary to instantiate another logger, passing category name to its constructor.

// EXAMPLE - using custom loggers

void connect() {
    Logger log("app.network");
    log.trace("Connecting to server"); // Using local logger
}

SerialLogHandler logHandler(LOG_LEVEL_WARN, { // Logging level for non-application messages
    { "app", LOG_LEVEL_INFO }, // Default logging level for all application messages
    { "app.network", LOG_LEVEL_TRACE } // Logging level for networking messages
});

void setup() {
    Log.info("System started"); // Using default logger instance
    Log.trace("My device ID: %s", (const char*)System.deviceID());
    connect();
}

void loop() {
}

Category names are written in all lower case and may contain arbitrary number of subcategories separated by period character. In order to not interfere with the system logging, it is recommended to always add app prefix to all application-specific category names.

The example application generates the following logging output:

0000000044 [app] INFO: System started
0000000044 [app.network] TRACE: Connecting to server

Note that the trace message containing device ID has been filtered out according to the log handler settings, which prevent log messages with the app category from being logged if their logging level is below the LOG_LEVEL_INFO level.

Category filters are specified using initializer list syntax with each element of the list containing a filter string and a minimum logging level required for messages with matching category to be logged. Note that filter string matches not only exact category name but any of its subcategory names as well, for example:

  • a – matches a, a.b, a.b.c but not aaa or aaa.b
  • b.c – matches b.c, b.c.d but not a.b.c or b.ccc

If more than one filter matches a given category name, the most specific filter is used.