Enumerate available states in Prometheus startup (#97993)

pull/99567/head
Russell Cloran 2023-09-04 00:30:56 -07:00 committed by GitHub
parent 69117cb8e3
commit 9144ef7ed8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 7 deletions

View File

@ -120,10 +120,15 @@ def setup(hass: HomeAssistant, config: ConfigType) -> bool:
default_metric,
)
hass.bus.listen(EVENT_STATE_CHANGED, metrics.handle_state_changed)
hass.bus.listen(EVENT_STATE_CHANGED, metrics.handle_state_changed_event)
hass.bus.listen(
EVENT_ENTITY_REGISTRY_UPDATED, metrics.handle_entity_registry_updated
)
for state in hass.states.all():
if entity_filter(state.entity_id):
metrics.handle_state(state)
return True
@ -162,16 +167,13 @@ class PrometheusMetrics:
self._metrics = {}
self._climate_units = climate_units
def handle_state_changed(self, event):
"""Listen for new messages on the bus, and add them to Prometheus."""
def handle_state_changed_event(self, event):
"""Handle new messages from the bus."""
if (state := event.data.get("new_state")) is None:
return
entity_id = state.entity_id
_LOGGER.debug("Handling state update for %s", entity_id)
domain, _ = hacore.split_entity_id(entity_id)
if not self._filter(state.entity_id):
_LOGGER.debug("Filtered out entity %s", state.entity_id)
return
if (old_state := event.data.get("old_state")) is not None and (
@ -179,6 +181,14 @@ class PrometheusMetrics:
) != state.attributes.get(ATTR_FRIENDLY_NAME):
self._remove_labelsets(old_state.entity_id, old_friendly_name)
self.handle_state(state)
def handle_state(self, state):
"""Add/update a state in Prometheus."""
entity_id = state.entity_id
_LOGGER.debug("Handling state update for %s", entity_id)
domain, _ = hacore.split_entity_id(entity_id)
ignored_states = (STATE_UNAVAILABLE, STATE_UNKNOWN)
handler = f"_handle_{domain}"

View File

@ -107,6 +107,34 @@ async def generate_latest_metrics(client):
return body
@pytest.mark.parametrize("namespace", [""])
async def test_setup_enumeration(hass, hass_client, entity_registry, namespace):
"""Test that setup enumerates existing states/entities."""
# The order of when things are created must be carefully controlled in
# this test, so we don't use fixtures.
sensor_1 = entity_registry.async_get_or_create(
domain=sensor.DOMAIN,
platform="test",
unique_id="sensor_1",
unit_of_measurement=UnitOfTemperature.CELSIUS,
original_device_class=SensorDeviceClass.TEMPERATURE,
suggested_object_id="outside_temperature",
original_name="Outside Temperature",
)
set_state_with_entry(hass, sensor_1, 12.3, {})
assert await async_setup_component(hass, prometheus.DOMAIN, {prometheus.DOMAIN: {}})
client = await hass_client()
body = await generate_latest_metrics(client)
assert (
'homeassistant_sensor_temperature_celsius{domain="sensor",'
'entity="sensor.outside_temperature",'
'friendly_name="Outside Temperature"} 12.3' in body
)
@pytest.mark.parametrize("namespace", [""])
async def test_view_empty_namespace(client, sensor_entities) -> None:
"""Test prometheus metrics view."""