Monitoring APIs
Heap Monitor
The heap monitor provides some simple utilities for monitoring and printing out the state of the heap memory in the system. It uses various heap_caps_get_* functions to provide information about a memory region specified by a bitmask of capabilities defining the region:
minimum free bytes: The minimum free bytes available in the region over the lifetime of the region.
free bytes: The current number of free bytes available in the region.
allocated bytes: The current number of allocated bytes in the region.
largest free block: The size of the current largest free block (in bytes) in the region. Any mallocs over the size will fail.
total size: The size (in bytes) of the memory region.
It provides some utilities for formatting the output as single line output, CSV output, or a nice table.
Finally, the class provides some static methods for some common use cases to quickly get the available memory for various regions as well as easily format them into csv/table output.
Code examples for the monitor API are provided in the monitor example folder.
Heap Monitor API Reference
Header File
Classes
-
class HeapMonitor : public espp::BaseComponent
HeapMonitor class This class provides functionality to monitor and report heap memory usage in ESP32 systems. It can be used to get information about different heap regions based on their flags (e.g., MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL, etc.).
It provides methods to retrieve heap information, format it as a string, and log it. The class can be configured with specific heap flags and a name for the monitor.
Heap Monitor Example
Public Functions
-
inline explicit HeapMonitor(const Config &config)
Constructor.
- Parameters:
config – Configuration for heap monitor
-
inline HeapInfo get_info() const
Get heap info for the configured heap region.
- Returns:
HeapInfo structure with heap information
-
inline const std::string &get_name() const
Get the name of the component
Note
This is the tag of the logger
- Returns:
A const reference to the name of the component
-
inline void set_log_tag(const std::string_view &tag)
Set the tag for the logger
- Parameters:
tag – The tag to use for the logger
-
inline espp::Logger::Verbosity get_log_level() const
Get the log level for the logger
See also
See also
- Returns:
The verbosity level of the logger
-
inline void set_log_level(espp::Logger::Verbosity level)
Set the log level for the logger
See also
See also
- Parameters:
level – The verbosity level to use for the logger
-
inline void set_log_verbosity(espp::Logger::Verbosity level)
Set the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls set_log_level
- Parameters:
level – The verbosity level to use for the logger
-
inline espp::Logger::Verbosity get_log_verbosity() const
Get the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls get_log_level
- Returns:
The verbosity level of the logger
-
inline void set_log_rate_limit(std::chrono::duration<float> rate_limit)
Set the rate limit for the logger
See also
Note
Only calls to the logger that have _rate_limit suffix will be rate limited
- Parameters:
rate_limit – The rate limit to use for the logger
Public Static Functions
-
static std::string get_region_name(int heap_flags)
Get the name of the heap region based on the heap flags.
- Parameters:
heap_flags – Heap region flags bitmask (e.g., MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL, etc.)
- Returns:
Name of the heap region as a string
-
static HeapInfo get_info(int heap_flags)
Get heap info for a specific heap region.
- Parameters:
heap_flags – Heap region flags bitmask (e.g., MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL, etc.)
- Returns:
HeapInfo structure with heap information
-
static std::vector<HeapInfo> get_info(const std::vector<int> &heap_flags)
Get heap info for a specific heap region.
- Parameters:
heap_flags – Vector of heap region flags bitmasks (e.g., MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL, etc.)
- Returns:
Vector of HeapInfo structures with heap information for each region
-
static inline const std::string get_csv_header()
Get the header for the CSV output.
- Returns:
CSV header string
-
static inline const std::string get_table_header()
Get the header for the table output.
- Returns:
Table header string
-
static std::string get_table(const std::vector<int> &heap_flags)
Get a string representation of the heap info in table format.
- Parameters:
heap_flags – Heap region flags bitmask(s) (e.g., MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL, etc.)
- Returns:
Table string representation of the heap info, each line representing a heap region (entry in heap_flags vector)
-
static std::string get_csv(const std::vector<int> &heap_flags)
Get a string representation of the heap info in CSV format.
- Parameters:
heap_flags – Heap region flags bitmask(s) (e.g., MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL, etc.)
- Returns:
CSV string representation of the heap info, each line representing a heap region (entry in heap_flags vector)
-
struct Config
Configuration for HeapMonitor.
-
struct HeapInfo
Info about a heap region.
Public Members
-
int heap_flags
Heap region flags bitmask (e.g., MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL, etc.)
-
size_t free_bytes
Total free heap in bytes.
-
size_t min_free_bytes
Minimum free heap in bytes.
-
size_t largest_free_block
Largest free block in bytes.
-
size_t allocated_bytes
Total allocated heap in bytes.
-
size_t total_size
Total heap size in bytes.
-
int heap_flags
-
inline explicit HeapMonitor(const Config &config)
Task Monitor
The task monitor provides the ability to use the FreeRTOS trace facility to output information about the CPU utilization (%), stack high water mark (bytes), and priority of all the tasks running on the system.
There is an associated task-monitor python gui which can parse the output of this component and render it as a chart or into a table for visualization.
Code examples for the monitor API are provided in the monitor example folder.
Task Monitor API Reference
Header File
Classes
-
class TaskMonitor : public espp::BaseComponent
Class which monitors the currently running tasks in the system and periodically logs their states. See also FreeRTOS::vTaskGetInfo().
Basic Task Monitor Example
// create the monitor espp::TaskMonitor tm({.period = 500ms}); // create threads auto start = std::chrono::high_resolution_clock::now(); auto task_fn = [&start](int task_id, auto &, auto &, auto &) { auto now = std::chrono::high_resolution_clock::now(); auto seconds_since_start = std::chrono::duration<float>(now - start).count(); // do some work float x = 2.0f * M_PI * sin(exp(task_id) * seconds_since_start); // sleep std::this_thread::sleep_for((10ms * std::abs(x)) + 1ms); // don't want to stop the task return false; }; std::vector<std::unique_ptr<espp::Task>> tasks; size_t num_tasks = 10; tasks.resize(num_tasks); for (size_t i = 0; i < num_tasks; i++) { std::string task_name = fmt::format("Task {}", i); auto task = espp::Task::make_unique( {.callback = std::bind(task_fn, i, _1, _2, _3), .task_config = {.name = task_name, .stack_size_bytes = 5 * 1024}}); tasks[i] = std::move(task); tasks[i]->start(); } // now sleep for a while to let the monitor do its thing std::this_thread::sleep_for(5s);
get_latest_info_vector() Example
// create threads auto start = std::chrono::high_resolution_clock::now(); auto task_fn = [&start](int task_id, auto &, auto &, auto &) { auto now = std::chrono::high_resolution_clock::now(); auto seconds_since_start = std::chrono::duration<float>(now - start).count(); // do some work float x = 2.0f * M_PI * sin(exp(task_id) * seconds_since_start); // sleep std::this_thread::sleep_for((10ms * std::abs(x)) + 1ms); // don't want to stop the task return false; }; std::vector<std::unique_ptr<espp::Task>> tasks; size_t num_tasks = 10; tasks.resize(num_tasks); for (size_t i = 0; i < num_tasks; i++) { std::string task_name = fmt::format("Task {}", i); auto task = espp::Task::make_unique( {.callback = std::bind(task_fn, i, _1, _2, _3), .task_config = {.name = task_name, .stack_size_bytes = 5 * 1024}}); tasks[i] = std::move(task); tasks[i]->start(); } // now sleep for a while to let the monitor do its thing std::this_thread::sleep_for(1s); auto task_info = espp::TaskMonitor::get_latest_info_vector(); for (const auto &info : task_info) { fmt::print("{}\n", info); }
get_latest_info_*() Example
// create threads auto start = std::chrono::high_resolution_clock::now(); auto task_fn = [&start](int task_id, auto &, auto &, auto &) { auto now = std::chrono::high_resolution_clock::now(); auto seconds_since_start = std::chrono::duration<float>(now - start).count(); // do some work float x = 2.0f * M_PI * sin(exp(task_id) * seconds_since_start); // sleep std::this_thread::sleep_for((10ms * std::abs(x)) + 1ms); // don't want to stop the task return false; }; std::vector<std::unique_ptr<espp::Task>> tasks; size_t num_tasks = 10; tasks.resize(num_tasks); for (size_t i = 0; i < num_tasks; i++) { std::string task_name = fmt::format("Task {}", i); auto task = espp::Task::make_unique( {.callback = std::bind(task_fn, i, _1, _2, _3), .task_config = {.name = task_name, .stack_size_bytes = 5 * 1024}}); tasks[i] = std::move(task); tasks[i]->start(); } // now sleep for a while to let the monitor do its thing std::this_thread::sleep_for(1s); // single line string fmt::print("Task Monitor Info (single line):\n"); fmt::print("{}\n", espp::TaskMonitor::get_latest_info_string()); // pretty table fmt::print("Task Monitor Info (pretty table):\n"); auto task_table = espp::TaskMonitor::get_latest_info_table(); std::cout << task_table << std::endl;
Note
you must enable CONFIG_FREERTOS_USE_TRACE_FACILITY and CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS for this class to do anything. This means that you can always instantiate this class in your app_main, and then based on those two config settings it will either do nothing (default) or print out the stats for you to analyze. Finally, the monitoring period can be configured as well.
Note
If you wish to also get the core id of the task, you must enable CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID. If you do not enable this option, the core id will be -2.
Public Functions
-
inline const std::string &get_name() const
Get the name of the component
Note
This is the tag of the logger
- Returns:
A const reference to the name of the component
-
inline void set_log_tag(const std::string_view &tag)
Set the tag for the logger
- Parameters:
tag – The tag to use for the logger
-
inline espp::Logger::Verbosity get_log_level() const
Get the log level for the logger
See also
See also
- Returns:
The verbosity level of the logger
-
inline void set_log_level(espp::Logger::Verbosity level)
Set the log level for the logger
See also
See also
- Parameters:
level – The verbosity level to use for the logger
-
inline void set_log_verbosity(espp::Logger::Verbosity level)
Set the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls set_log_level
- Parameters:
level – The verbosity level to use for the logger
-
inline espp::Logger::Verbosity get_log_verbosity() const
Get the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls get_log_level
- Returns:
The verbosity level of the logger
-
inline void set_log_rate_limit(std::chrono::duration<float> rate_limit)
Set the rate limit for the logger
See also
Note
Only calls to the logger that have _rate_limit suffix will be rate limited
- Parameters:
rate_limit – The rate limit to use for the logger
Public Static Functions
-
static inline std::vector<TaskInfo> get_latest_info_vector()
Get information about all the tasks running. Will provide for each task the following information:
name
% CPU run time the task has used
stack high water mark (bytes)
current priority of the task
- Returns:
std::vector<TaskInfo> vector containing info for each task.
-
static inline std::string get_latest_info_string()
Get information about all the tasks running. Will provide for each task the following information:
name
% CPU run time the task has used
stack high water mark (bytes)
current priority of the task
core the task is running on
Where each entry is separated by ‘,’ and each set of task data is separated by ‘;’.
This is a static function, so it can be called without having to instantiate a TaskMonitor object.
Note
There is no newline returned.
Note
This function calls TaskMonitor::get_latest_info_vector() and then formats the data into a single line string separated by , and ;.
- Returns:
std::string containing sequence of entries, formatted:
name, cpu%, high_water_mark, priority, core_id;;
-
static inline auto get_latest_info_table()
Print the latest task information in a nice table format. This is a static function, so it can be called without having to instantiate a TaskMonitor object.
Note
This function calls TaskMonitor::get_latest_info_vector() and then formats the data into a table using the libfmt library.
- Returns:
A string containing the information in a table format.
-
struct Config
Config structure for TaskMonitor object.
-
struct TaskInfo
Info structure for each task monitored.
Public Members
-
std::string name
Name of the task.
-
uint32_t cpu_percent
% CPU run time the task has used.
-
uint32_t high_water_mark
Stack high water mark (bytes).
-
uint32_t priority
Current priority of the task.
-
int core_id
Core the task is running on. Will be 0,1, or -1 if task is not pinned to a core. Only valid if CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID is set to y, otherwise will be -2.
-
std::string name
-
inline const std::string &get_name() const