Logging APIs
Format
Format is a simple component which exposes libfmt for use within esp-idf as a single include.
Logger
The logger provides a cross-platform wrapper around libfmt for providing configurable log output with different levels that can be turned on / off at runtime.
Code examples for the logging API are provided in the logger example folder.
API Reference
Header File
Macros
-
ESPP_LOGGER_LOG_LEVEL_NONE
-
ESPP_LOGGER_LOG_LEVEL_ERROR
-
ESPP_LOGGER_LOG_LEVEL_WARN
-
ESPP_LOGGER_LOG_LEVEL_INFO
-
ESPP_LOGGER_LOG_LEVEL_DEBUG
-
CONFIG_ESPP_LOGGER_LOG_LEVEL
-
ESPP_LOGGER_DEBUG_ENABLED
-
ESPP_LOGGER_INFO_ENABLED
-
ESPP_LOGGER_WARN_ENABLED
-
ESPP_LOGGER_ERROR_ENABLED
-
ESPP_LOGGER_CURSOR_COMMANDS_ENABLED
Classes
-
class Logger
Logger provides a wrapper around nicer / more robust formatting than standard ESP_LOG* macros with the ability to change the log level at run-time. Logger currently is a light wrapper around libfmt (future std::format).
To save on code size, the logger has the ability to be compiled out based on the log level set in the sdkconfig. This means that if the log level is set to ERROR, all debug, info, and warn logs will be compiled out. This is done by checking the log level at compile time and only compiling in the functions that are needed.
The logger can also be compiled with support for cursor commands. This allows the logger to move the cursor up, down, clear the line, clear the screen, and move the cursor to a specific position. This can be useful for creating various types of interactive output or to maintian context with long-running logs.
Basic Example
float num_seconds_to_run = 10.0f; // create loggers auto logger = espp::Logger({.tag = "Cool Logger", .level = espp::Logger::Verbosity::DEBUG}); auto start = std::chrono::high_resolution_clock::now(); auto now = std::chrono::high_resolution_clock::now(); float elapsed = std::chrono::duration<float>(now - start).count(); while (elapsed < num_seconds_to_run) { now = std::chrono::high_resolution_clock::now(); elapsed = std::chrono::duration<float>(now - start).count(); auto remaining = num_seconds_to_run - elapsed; logger.debug("debug: {:%Y-%m-%d %H:%M:%S} - {:%Y-%m-%d %H:%M:%S} = {}", now, start, elapsed); logger.info("elapsed: {:.3f}s", elapsed); logger.warn("remaining: {:.3f}s", remaining); if (remaining < 0) { logger.error("You overstayed your welcome by {:.03}s!", -remaining); } std::this_thread::sleep_for(500ms); }
Threaded Logging and Verbosity Example
// create loggers auto logger1 = espp::Logger( {.tag = "Thread 1", .rate_limit = 500ms, .level = espp::Logger::Verbosity::INFO}); auto logger2 = espp::Logger( {.tag = "Thread 2", .rate_limit = 1s, .level = espp::Logger::Verbosity::DEBUG}); // lambda for logging to those two loggers from multiple threads auto logger_fn = [](espp::Logger *logger) { size_t loop_iteration{0}; while (true) { // log - note: debug shouldn't be shown! logger->debug("some debug info: {}", loop_iteration); logger->info("some info: {}", loop_iteration); logger->warn("some warning: {}", loop_iteration); logger->error("some error: {}", loop_iteration); logger->info_rate_limited("some rate limited info: {}", loop_iteration); // update loop variables loop_iteration++; // sleep std::this_thread::sleep_for(300ms); } }; // start two threads, binding the lambda to each logger auto logger1_thread = std::thread(std::bind(logger_fn, &logger1)); auto logger2_thread = std::thread(std::bind(logger_fn, &logger2)); uint8_t level{static_cast<uint8_t>(espp::Logger::Verbosity::DEBUG)}; // every 1 second, change the loggers' verbosity while (true) { // update the loggers' verbosity level++; if (level > static_cast<uint8_t>(espp::Logger::Verbosity::NONE)) { level = static_cast<uint8_t>(espp::Logger::Verbosity::DEBUG); } espp::Logger::Verbosity verbosity = static_cast<espp::Logger::Verbosity>(level); logger1.set_verbosity(verbosity); logger2.set_verbosity(verbosity); // sleep std::this_thread::sleep_for(1s); }
Cursor Commands Example
float num_seconds_to_run = 10.0f; // create loggers auto logger = espp::Logger({.tag = "Cursor Commands", .level = espp::Logger::Verbosity::DEBUG}); auto start = std::chrono::high_resolution_clock::now(); auto now = std::chrono::high_resolution_clock::now(); float elapsed = std::chrono::duration<float>(now - start).count(); logger.info("Long running log... {}", elapsed); while (elapsed < num_seconds_to_run) { now = std::chrono::high_resolution_clock::now(); elapsed = std::chrono::duration<float>(now - start).count(); auto remaining = num_seconds_to_run - elapsed; logger.move_up(); logger.clear_line(); logger.info("Long running log... {}", remaining); std::this_thread::sleep_for(100ms); }
Public Types
-
enum class Verbosity
Verbosity levels for the logger, in order of increasing priority.
Values:
-
enumerator DEBUG
Debug level verbosity.
-
enumerator INFO
Info level verbosity.
-
enumerator WARN
Warn level verbosity.
-
enumerator ERROR
Error level verbosity.
-
enumerator NONE
No verbosity - logger will not print anything.
-
enumerator DEBUG
Public Functions
-
inline explicit Logger(const Config &config)
Construct a new Logger object.
- Parameters
config – configuration for the logger.
-
inline espp::Logger::Verbosity get_verbosity() const
Get the current verbosity for the logger.
See also
- Returns
The current verbosity level.
-
inline void set_verbosity(const espp::Logger::Verbosity level)
Change the verbosity for the logger.
See also
- Parameters
level – new verbosity level
-
inline void set_tag(const std::string_view tag)
Change the tag for the logger.
- Parameters
tag – The new tag.
-
inline const std::string &get_tag() const
Get the current tag for the logger.
- Returns
A const reference to the current tag.
-
inline void set_include_time(bool include_time)
Whether to include the time in the log.
Note
The time is in seconds since boot and is represented as a floating point number with precision to the millisecond.
- Parameters
include_time – Whether to include the time in the log.
-
inline void set_rate_limit(const std::chrono::duration<float> rate_limit)
Change the rate limit for the logger.
Note
Only calls that have _rate_limited suffixed will be rate limited.
- Parameters
rate_limit – The new rate limit.
-
inline std::chrono::duration<float> get_rate_limit() const
Get the current rate limit for the logger.
- Returns
The current rate limit.
-
template<typename ...Args>
inline std::string format(std::string_view rt_fmt_str, Args&&... args) Format args into string according to format string. From: https://en.cppreference.com/w/cpp/utility/format/format.
- Parameters
rt_fmt_str – format string
args – optional arguments passed to be formatted.
- Returns
formatted std::string
-
template<typename ...Args>
inline void debug(std::string_view rt_fmt_str, Args&&... args) Print log in GRAY if level is Verbosity::DEBUG or greater.
- Parameters
rt_fmt_str – format string
args – optional arguments passed to be formatted.
-
template<typename ...Args>
inline void info(std::string_view rt_fmt_str, Args&&... args) Print log in GREEN if level is Verbosity::INFO or greater.
- Parameters
rt_fmt_str – format string
args – optional arguments passed to be formatted.
-
template<typename ...Args>
inline void warn(std::string_view rt_fmt_str, Args&&... args) Print log in YELLOW if level is Verbosity::WARN or greater.
- Parameters
rt_fmt_str – format string
args – optional arguments passed to be formatted.
-
template<typename ...Args>
inline void error(std::string_view rt_fmt_str, Args&&... args) Print log in RED if level is Verbosity::ERROR or greater.
- Parameters
rt_fmt_str – format string
args – optional arguments passed to be formatted.
-
template<typename ...Args>
inline void debug_rate_limited(std::string_view rt_fmt_str, Args&&... args) Print log in GRAY if level is Verbosity::DEBUG or greater. This function is rate limited by the rate specified in the constructor.
- Parameters
rt_fmt_str – format string
args – optional arguments passed to be formatted.
-
template<typename ...Args>
inline void info_rate_limited(std::string_view rt_fmt_str, Args&&... args) Print log in GREEN if level is Verbosity::INFO or greater This function is rate limited by the rate specified in the constructor.
- Parameters
rt_fmt_str – format string
args – optional arguments passed to be formatted.
-
template<typename ...Args>
inline void warn_rate_limited(std::string_view rt_fmt_str, Args&&... args) Print log in YELLOW if level is Verbosity::WARN or greater This function is rate limited by the rate specified in the constructor.
- Parameters
rt_fmt_str – format string
args – optional arguments passed to be formatted.
-
template<typename ...Args>
inline void error_rate_limited(std::string_view rt_fmt_str, Args&&... args) Print log in RED if level is Verbosity::ERROR or greater This function is rate limited by the rate specified in the constructor.
- Parameters
rt_fmt_str – format string
args – optional arguments passed to be formatted.
Public Static Functions
-
static inline void move_up()
Move the cursor up one line.
-
static inline void move_up(int lines)
Move the cursor up a number of lines.
- Parameters
lines – The number of lines to move up.
-
static inline void move_down()
Move the cursor down one line.
-
static inline void move_down(int lines)
Move the cursor down a number of lines.
- Parameters
lines – The number of lines to move down.
-
static inline void move_to_start()
Move the cursor to the beginning of the line.
-
static inline void clear_line()
Clear the line.
-
static inline void clear_screen()
Clear the screen and move the cursor to the top left.
-
static inline void move_to(int x, int y)
Move the cursor to a specific position.
- Parameters
x – The x position to move to.
y – The y position to move to.
-
static inline std::string get_time()
Get the current time in seconds since the start of the logging system.
- Returns
time in seconds since the start of the logging system.
-
struct Config
Configuration struct for the logger.
Public Members
-
std::string_view tag
The TAG that will be prepended to all logs.
-
bool include_time = {true}
Include the time in the log.
-
std::chrono::duration<float> rate_limit = std::chrono::duration<float>(0)
The rate limit for the logger. Optional, if <= 0 no rate limit.
Note
Only calls that have _rate_limited suffixed will be rate limited.
-
std::string_view tag
-
enum class Verbosity