ESPHome 2025.9.0-dev
Loading...
Searching...
No Matches
runtime_stats.cpp
Go to the documentation of this file.
1#include "runtime_stats.h"
2
3#ifdef USE_RUNTIME_STATS
4
6#include <algorithm>
7
8namespace esphome {
9
10namespace runtime_stats {
11
12RuntimeStatsCollector::RuntimeStatsCollector() : log_interval_(60000), next_log_time_(0) {
14}
15
16void RuntimeStatsCollector::record_component_time(Component *component, uint32_t duration_ms, uint32_t current_time) {
17 if (component == nullptr)
18 return;
19
20 // Check if we have cached the name for this component
21 auto name_it = this->component_names_cache_.find(component);
22 if (name_it == this->component_names_cache_.end()) {
23 // First time seeing this component, cache its name
24 const char *source = component->get_component_source();
25 this->component_names_cache_[component] = source;
26 this->component_stats_[source].record_time(duration_ms);
27 } else {
28 this->component_stats_[name_it->second].record_time(duration_ms);
29 }
30
31 if (this->next_log_time_ == 0) {
32 this->next_log_time_ = current_time + this->log_interval_;
33 return;
34 }
35}
36
38 ESP_LOGI(TAG, "Component Runtime Statistics");
39 ESP_LOGI(TAG, "Period stats (last %" PRIu32 "ms):", this->log_interval_);
40
41 // First collect stats we want to display
42 std::vector<ComponentStatPair> stats_to_display;
43
44 for (const auto &it : this->component_stats_) {
45 const ComponentRuntimeStats &stats = it.second;
46 if (stats.get_period_count() > 0) {
47 ComponentStatPair pair = {it.first, &stats};
48 stats_to_display.push_back(pair);
49 }
50 }
51
52 // Sort by period runtime (descending)
53 std::sort(stats_to_display.begin(), stats_to_display.end(), std::greater<ComponentStatPair>());
54
55 // Log top components by period runtime
56 for (const auto &it : stats_to_display) {
57 const char *source = it.name;
58 const ComponentRuntimeStats *stats = it.stats;
59
60 ESP_LOGI(TAG, " %s: count=%" PRIu32 ", avg=%.2fms, max=%" PRIu32 "ms, total=%" PRIu32 "ms", source,
62 stats->get_period_time_ms());
63 }
64
65 // Log total stats since boot
66 ESP_LOGI(TAG, "Total stats (since boot):");
67
68 // Re-sort by total runtime for all-time stats
69 std::sort(stats_to_display.begin(), stats_to_display.end(),
70 [](const ComponentStatPair &a, const ComponentStatPair &b) {
71 return a.stats->get_total_time_ms() > b.stats->get_total_time_ms();
72 });
73
74 for (const auto &it : stats_to_display) {
75 const char *source = it.name;
76 const ComponentRuntimeStats *stats = it.stats;
77
78 ESP_LOGI(TAG, " %s: count=%" PRIu32 ", avg=%.2fms, max=%" PRIu32 "ms, total=%" PRIu32 "ms", source,
80 stats->get_total_time_ms());
81 }
82}
83
85 if (this->next_log_time_ == 0)
86 return;
87
88 if (current_time >= this->next_log_time_) {
89 this->log_stats_();
90 this->reset_stats_();
91 this->next_log_time_ = current_time + this->log_interval_;
92 }
93}
94
95} // namespace runtime_stats
96
98 nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
99
100} // namespace esphome
101
102#endif // USE_RUNTIME_STATS
const char * get_component_source() const
Get the integration where this component was declared as a string.
std::map< const char *, ComponentRuntimeStats, CStrCompare > component_stats_
void record_component_time(Component *component, uint32_t duration_ms, uint32_t current_time)
std::map< Component *, const char * > component_names_cache_
void process_pending_stats(uint32_t current_time)
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
runtime_stats::RuntimeStatsCollector * global_runtime_stats