mcu-uuid-log
Description
Microcontroller logging framework library
Purpose
Provides a framework for handling log messages. Thread-safe on the ESP32 but cannot be used from an interrupt context.
Dependencies
Refer to the library.json
file for more
details.
Contents
Usage
#include <uuid/log.h>
Create a uuid::log::Logger
and call its functions for logging
messages.
Create a class that implements uuid::log::Handler
and registers
to handle log messages. Output those messages by whatever means is
appropriate for your application (e.g. serial console, over the WiFi
network, by email).
There is no option to exclude compilation of debug-level messages, the expectation is that these will be disabled at runtime. If your program cannot fit in flash with the debug messages enabled or run with sufficient performance then there’s no benefit in having them.
The performance impact of disabled debug logging can be limited by using
the Logger::enabled(LogLevel)
function (but messages will not be
formatted if the level isn’t enabled).
Example
#include <Arduino.h>
#include <uuid/common.h>
#include <uuid/log.h>
class SerialLogHandler: public uuid::log::Handler {
public:
SerialLogHandler() = default;
void start() {
uuid::log::Logger::register_handler(this, uuid::log::Level::ALL);
}
/*
* It is not recommended to directly output from this function,
* this is only a simple example. Messages should normally be
* queued for later output when the application is less busy.
*/
void operator<<(std::shared_ptr<uuid::log::Message> message) {
char temp[100] = { 0 };
int ret = snprintf_P(temp, sizeof(temp), PSTR("%s %c [%S] %s\r\n"),
uuid::log::format_timestamp_ms(message->uptime_ms).c_str(),
uuid::log::format_level_char(message->level),
message->name, message->text.c_str());
if (ret > 0) {
Serial.print(temp);
}
}
};
static SerialLogHandler log_handler;
void setup() {
static uuid::log::Logger logger{F("setup")};
Serial.begin(115200);
log_handler.start();
logger.info(F("Application started"));
}
void loop() {
static uuid::log::Logger logger{F("loop")};
static unsigned int i = 0;
uuid::loop();
logger.debug(F("Hello %u World!"), i++);
delay(1000);
}
Output
0+00:00:00.000 I [setup] Application started
0+00:00:00.000 D [loop] Hello 0 World!
0+00:00:01.000 D [loop] Hello 1 World!
0+00:00:02.000 D [loop] Hello 2 World!
0+00:00:03.000 D [loop] Hello 3 World!
0+00:00:04.000 D [loop] Hello 4 World!
0+00:00:05.000 D [loop] Hello 5 World!
0+00:00:06.000 D [loop] Hello 6 World!
0+00:00:07.000 D [loop] Hello 7 World!
0+00:00:08.000 D [loop] Hello 8 World!
0+00:00:09.000 D [loop] Hello 9 World!
0+00:00:10.000 D [loop] Hello 10 World!
Resources
Change log
Unreleased
3.1.0 – 2024-03-17
Support forwarding plain and formatted messages to the Logger
.
Added
Make the
vlog()
functions public so that a variable number of arguments can be passed directly to the logger.Add
logp()
functions that allow plain text to be passed directly to the logger without using formatting.
3.0.0 – 2022-11-03
Support setting a level on each Logger
.
Added
Support setting a level on each
Logger
.Function to get the global log level.
Function to get the effective log level on a
Logger
.Support logging messages at a specific level without providing the facility.
Changed
Make
PrintHandler
more efficient by removing the log message before printing it.Use
PSTR_ALIGN
for flash strings.
2.3.0 – 2022-10-25
Be thread-safe where possible.
Added
Function to get a
Logger
’s default facility for new messages.Indicate whether this version of the library is thread-safe or not (
UUID_LOG_THREAD_SAFE
anduuid::log::thread_safe
).
Changed
Make the library thread-safe when supported by the platform.
2.2.0 – 2022-01-29
Add a basic log handler for the Print interface.
Added
Basic log handler for writing messages to any object supporting the
Print
interface (PrintHandler
).
2.1.4 – 2021-06-02
Fix for compile failure with newer GCC in espressif8266 3.0.0.
Fixed
Compile failure with newer GCC in espressif8266 3.0.0 using
reinterpret_cast
for aconstexpr
value.
2.1.3 – 2021-04-18
Upgrade to PlatformIO 5.
Changed
Use PlatformIO 5 dependency specification.
2.1.2 – 2020-01-17
Fixes for uncontrolled ordering of static object lifetimes.
Changed
Automatically unregister handlers when they are destroyed.
Fixed
Make registration of log handlers safe during static initialization and unregistration safe during static deinitialization.
2.1.1 – 2019-09-15
Fix to use less memory.
Fixed
Use a flash string for the format string in
format_timestamp_ms()
.
2.1.0 – 2019-09-07
Add functions to get levels, format them as strings and parse them
Added
Functions to get a list of all levels, format them as uppercase or lowercase strings and then parse them back again.
2.0.4 – 2019-08-26
Fix uptime format string.
Changed
Put formatting functions in a separate file to improve linker behaviour.
Fixed
Uptime format string should use the unsigned conversion specifier for all values.
2.0.3 – 2019-08-17
Make get_log_level()
accept a const Handler
.
Fixed
Make
get_log_level()
accept aconst Handler
.
2.0.2 – 2019-08-17
Make logging functions const
so that a const Logger
can be used.
Changed
Make all of the logging functions
const
.
2.0.1 – 2019-08-16
Fix ESP32 builds and the example.
Fixed
Workaround incorrect definition of
FPSTR()
on ESP32 (#1371).Remove use of
Serial.printf_P()
from the example (which does not exist in the standard Arduino library).Add missing
Serial.begin()
to the example.
2.0.0 – 2019-08-12
Improve names of types, data members and interfaces.
Changed
The names of
Message
data members no longer have trailing underscores.Rename log
Receiver
type toHandler
.Use operator
<<
instead ofadd_log_message()
as the interface for log handlers.
1.0.1 – 2019-08-12
Fix uptime text formatting.
Changed
The size of the
Level
andFacility
enums is now 1 byte.
Fixed
The width of the days part when formatting uptimes now has an upper bound of 10 instead of a lower bound of 10.
1.0.0 – 2019-08-11
First stable release.
Added
Support for logging messages at all syslog levels and facilities.
Support for registering receivers to handle log messages.