[prometheus] Add event and text base components metrics (#10240)

Co-authored-by: Jordan Zucker <jordan@Jordans-MacBook-Pro.local>
Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
Jordan Zucker
2025-11-24 09:42:07 -08:00
committed by GitHub
parent d7da559885
commit b820e67616
3 changed files with 150 additions and 0 deletions

View File

@@ -53,6 +53,18 @@ void PrometheusHandler::handleRequest(AsyncWebServerRequest *req) {
this->lock_row_(stream, obj, area, node, friendly_name); this->lock_row_(stream, obj, area, node, friendly_name);
#endif #endif
#ifdef USE_EVENT
this->event_type_(stream);
for (auto *obj : App.get_events())
this->event_row_(stream, obj, area, node, friendly_name);
#endif
#ifdef USE_TEXT
this->text_type_(stream);
for (auto *obj : App.get_texts())
this->text_row_(stream, obj, area, node, friendly_name);
#endif
#ifdef USE_TEXT_SENSOR #ifdef USE_TEXT_SENSOR
this->text_sensor_type_(stream); this->text_sensor_type_(stream);
for (auto *obj : App.get_text_sensors()) for (auto *obj : App.get_text_sensors())
@@ -547,6 +559,100 @@ void PrometheusHandler::text_sensor_row_(AsyncResponseStream *stream, text_senso
} }
#endif #endif
// Type-specific implementation
#ifdef USE_TEXT
void PrometheusHandler::text_type_(AsyncResponseStream *stream) {
stream->print(ESPHOME_F("#TYPE esphome_text_value gauge\n"));
stream->print(ESPHOME_F("#TYPE esphome_text_failed gauge\n"));
}
void PrometheusHandler::text_row_(AsyncResponseStream *stream, text::Text *obj, std::string &area, std::string &node,
std::string &friendly_name) {
if (obj->is_internal() && !this->include_internal_)
return;
if (obj->has_state()) {
// We have a valid value, output this value
stream->print(ESPHOME_F("esphome_text_failed{id=\""));
stream->print(relabel_id_(obj).c_str());
add_area_label_(stream, area);
add_node_label_(stream, node);
add_friendly_name_label_(stream, friendly_name);
stream->print(ESPHOME_F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(ESPHOME_F("\"} 0\n"));
// Data itself
stream->print(ESPHOME_F("esphome_text_value{id=\""));
stream->print(relabel_id_(obj).c_str());
add_area_label_(stream, area);
add_node_label_(stream, node);
add_friendly_name_label_(stream, friendly_name);
stream->print(ESPHOME_F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(ESPHOME_F("\",value=\""));
stream->print(obj->state.c_str());
stream->print(ESPHOME_F("\"} "));
stream->print(ESPHOME_F("1.0"));
stream->print(ESPHOME_F("\n"));
} else {
// Invalid state
stream->print(ESPHOME_F("esphome_text_failed{id=\""));
stream->print(relabel_id_(obj).c_str());
add_area_label_(stream, area);
add_node_label_(stream, node);
add_friendly_name_label_(stream, friendly_name);
stream->print(ESPHOME_F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(ESPHOME_F("\"} 1\n"));
}
}
#endif
// Type-specific implementation
#ifdef USE_EVENT
void PrometheusHandler::event_type_(AsyncResponseStream *stream) {
stream->print(ESPHOME_F("#TYPE esphome_event_value gauge\n"));
stream->print(ESPHOME_F("#TYPE esphome_event_failed gauge\n"));
}
void PrometheusHandler::event_row_(AsyncResponseStream *stream, event::Event *obj, std::string &area, std::string &node,
std::string &friendly_name) {
if (obj->is_internal() && !this->include_internal_)
return;
if (obj->get_last_event_type() != nullptr) {
// We have a valid event type, output this value
stream->print(ESPHOME_F("esphome_event_failed{id=\""));
stream->print(relabel_id_(obj).c_str());
add_area_label_(stream, area);
add_node_label_(stream, node);
add_friendly_name_label_(stream, friendly_name);
stream->print(ESPHOME_F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(ESPHOME_F("\"} 0\n"));
// Data itself
stream->print(ESPHOME_F("esphome_event_value{id=\""));
stream->print(relabel_id_(obj).c_str());
add_area_label_(stream, area);
add_node_label_(stream, node);
add_friendly_name_label_(stream, friendly_name);
stream->print(ESPHOME_F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(ESPHOME_F("\",last_event_type=\""));
stream->print(obj->get_last_event_type());
stream->print(ESPHOME_F("\"} "));
stream->print(ESPHOME_F("1.0"));
stream->print(ESPHOME_F("\n"));
} else {
// No event triggered yet
stream->print(ESPHOME_F("esphome_event_failed{id=\""));
stream->print(relabel_id_(obj).c_str());
add_area_label_(stream, area);
add_node_label_(stream, node);
add_friendly_name_label_(stream, friendly_name);
stream->print(ESPHOME_F("\",name=\""));
stream->print(relabel_name_(obj).c_str());
stream->print(ESPHOME_F("\"} 1\n"));
}
}
#endif
// Type-specific implementation // Type-specific implementation
#ifdef USE_NUMBER #ifdef USE_NUMBER
void PrometheusHandler::number_type_(AsyncResponseStream *stream) { void PrometheusHandler::number_type_(AsyncResponseStream *stream) {

View File

@@ -123,6 +123,22 @@ class PrometheusHandler : public AsyncWebHandler, public Component {
std::string &friendly_name); std::string &friendly_name);
#endif #endif
#ifdef USE_EVENT
/// Return the type for prometheus
void event_type_(AsyncResponseStream *stream);
/// Return the event values state as prometheus data point
void event_row_(AsyncResponseStream *stream, event::Event *obj, std::string &area, std::string &node,
std::string &friendly_name);
#endif
#ifdef USE_TEXT
/// Return the type for prometheus
void text_type_(AsyncResponseStream *stream);
/// Return the text values state as prometheus data point
void text_row_(AsyncResponseStream *stream, text::Text *obj, std::string &area, std::string &node,
std::string &friendly_name);
#endif
#ifdef USE_TEXT_SENSOR #ifdef USE_TEXT_SENSOR
/// Return the type for prometheus /// Return the type for prometheus
void text_sensor_type_(AsyncResponseStream *stream); void text_sensor_type_(AsyncResponseStream *stream);

View File

@@ -39,6 +39,15 @@ sensor:
return 0.0; return 0.0;
update_interval: 60s update_interval: 60s
text:
- platform: template
name: "Template text"
optimistic: true
min_length: 0
max_length: 100
mode: text
initial_value: "Hello World"
text_sensor: text_sensor:
- platform: version - platform: version
name: "ESPHome Version" name: "ESPHome Version"
@@ -52,6 +61,25 @@ text_sensor:
return {"Goodbye (cruel) World"}; return {"Goodbye (cruel) World"};
update_interval: 60s update_interval: 60s
event:
- platform: template
name: "Template Event"
id: template_event1
event_types:
- "custom_event_1"
- "custom_event_2"
button:
- platform: template
name: "Template Event Button"
on_press:
- logger.log: "Template Event Button pressed"
- lambda: |-
ESP_LOGD("template_event_button", "Template Event Button pressed");
- event.trigger:
id: template_event1
event_type: custom_event_1
binary_sensor: binary_sensor:
- platform: template - platform: template
id: template_binary_sensor1 id: template_binary_sensor1