Files
2023-11-06 18:17:45 +01:00

2.9 KiB

Logging and Debugging Messages

The logging system is designed to make log messages clearer and improve their uniformity across the project. It makes it easier to see where a log message comes from and what its verbosity is.

To use the logging system, include log.h in your source file, and use the following macros to print log messages:

LOG_DEBUG(TAG, fmt, ...)
LOG_INFO(TAG, fmt, ...)
LOG_WARN(TAG, fmt, ...)
LOG_CRIT(TAG, fmt, ...)
LOG_FATAL(TAG, fmt, ...)

The same format specifiers as in printf can be used.

The TAG parameter is a string that identifies the source of the log message. It is recommended to use one tag for each source file / module, and to name the tag after the source file / module. See the example below.

Global Log Level

You can control the verbosity of the logging output by setting a global log level in log.h. This log level filters out messages with a lower priority.

Custom Log Levels

before you include log.h, you can define custom log levels by defining the following macros:

// All log messages will be printed
#define LOGGER_LEVEL_ALL
#include "log.h"
// Info and higher priority messages will be printed
#define LOGGER_LEVEL_INFO
#include "log.h"
// Only warnings and errors will be printed
#define LOGGER_LEVEL_WARN
#include "log.h"
// Only log messages with level ERROR will be printed
#define LOGGER_LEVEL_CRITICAL
#include "log.h"
// Only log messages with level ERROR will be printed
#define LOGGER_LEVEL_FATAL
#include "log.h"

Colorful Log Messages

For improved readability, log messages can be printed in color by defining LOGGER_USE_COLOR in log.h or before you include log.h.
Default is 0

Log Output Format

Each log entry is formatted to include the following information:

  • Log level ([Debug], [Info], [Warn], [Critical], [Fatal])
  • Timestamp (in milliseconds since boot)
  • Tag
  • The log message

For instance, a log entry may look like this:

[Info] (2009) [LTDC]: This is a log message

Example

#define LOGGER_LEVEL_INFO
#include "log.h"

// Don't use a define for the tag, as the pointer to the tag is used
static const char *TAG = "main";

int main(void) {
    
    LOG_DEBUG(TAG, "This message will not be printed");
    LOG_INFO(TAG, "This message will be printed");
    LOG_WARN(TAG, "This message will be printed");
    LOG_CRIT(TAG, "This message will be printed");
    LOG_FATAL(TAG, "This message will be printed");
    
    for (int i = 0; i < 3; i++) {
        LOG_INFO(TAG, "Iteration %d of %d", i, 3);
    }
    
    return 0;
}

Result:

[Info]     (2009) [main]: This message will be printed
[Warning]  (2026) [main]: This message will be printed
[CRITICAL] (2033) [main]: This message will be printed
[FATAL]    (2040) [main]: This message will be printed
[Info]     (2040) [main]: Iteration 0 of 3
[Info]     (2047) [main]: Iteration 1 of 3
[Info]     (2054) [main]: Iteration 2 of 3