Logging

Since 0.6.0:

This object provides various classes for logging.

// EXAMPLE

// Use primary serial over USB interface for logging output
SerialLogHandler logHandler;

void setup() {
    // Log some messages with different logging levels
    Log.info("This is info message");
    Log.warn("This is warning message");
    Log.error("This is error message, error=%d", errCode);

    // Format text message
    Log.info("System version: %s", (const char*)System.version());
}

void loop() {
}

At higher level, the logging framework consists of two parts represented by their respective classes: loggers and log handlers. Most of the logging operations, such as generating a log message, are done through logger instances, while log handlers act as sinks for the overall logging output generated by the system and application modules.

The library provides default logger instance named Log, which can be used for all typical logging operations. Note that applications still need to instantiate at least one log handler in order to enable logging, otherwise most of the logging operations will have no effect. In the provided example, the application uses SerialLogHandler which sends the logging output to the primary serial over USB interface.

Consider the following logging output as generated by the example application:

0000000047 [app] INFO: This is info message
0000000050 [app] WARN: This is warning message
0000000100 [app] ERROR: This is error message, error=123
0000000149 [app] INFO: System version: 0.6.0

Here, each line starts with a timestamp (a number of milliseconds since the system startup), app is a default logging category, and INFO, WARN and ERROR are logging levels of the respective log messages.

All of the logging functions like Log.info() and Log.error() support sprintf-style argument formatting so you can use options like %d (integer), %.2f (2 decimal place floating point), or %s (c-string).

Sprintf-style formatting does not support 64-bit integers, such as %lld, %llu or Microsoft-style %I64d or %I64u. As a workaround you can use the Print64 firmware library in the community libraries. The source and instructions can be found in Github.

// Using the Print64 firmware library to format a 64-bit integer (uint64_t)
Log.info("millis=%s", toString(System.millis()).c_str());