Adding 'namespace' for prometheus metrics (#13738)

* Updating prometheus client version

* Using `entity_filter` as filter mechanism

* New optional `namespace` configuration
pull/15203/head
Alex Barcelo 2018-06-28 16:49:33 +02:00 committed by Pascal Vizeli
parent 19f2bbf52f
commit a277470363
4 changed files with 28 additions and 27 deletions

View File

@ -11,16 +11,15 @@ import voluptuous as vol
from aiohttp import web
from homeassistant.components.http import HomeAssistantView
from homeassistant.components import recorder
from homeassistant.const import (
CONF_DOMAINS, CONF_ENTITIES, CONF_EXCLUDE, CONF_INCLUDE,
EVENT_STATE_CHANGED, TEMP_FAHRENHEIT, CONTENT_TYPE_TEXT_PLAIN,
ATTR_TEMPERATURE, ATTR_UNIT_OF_MEASUREMENT)
from homeassistant import core as hacore
from homeassistant.helpers import state as state_helper
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers import entityfilter, state as state_helper
from homeassistant.util.temperature import fahrenheit_to_celsius
REQUIREMENTS = ['prometheus_client==0.1.0']
REQUIREMENTS = ['prometheus_client==0.2.0']
_LOGGER = logging.getLogger(__name__)
@ -29,8 +28,14 @@ API_ENDPOINT = '/api/prometheus'
DOMAIN = 'prometheus'
DEPENDENCIES = ['http']
CONF_FILTER = 'filter'
CONF_PROM_NAMESPACE = 'namespace'
CONFIG_SCHEMA = vol.Schema({
DOMAIN: recorder.FILTER_SCHEMA,
DOMAIN: vol.All({
vol.Optional(CONF_FILTER, default={}): entityfilter.FILTER_SCHEMA,
vol.Optional(CONF_PROM_NAMESPACE): cv.string,
})
}, extra=vol.ALLOW_EXTRA)
@ -40,25 +45,26 @@ def setup(hass, config):
hass.http.register_view(PrometheusView(prometheus_client))
conf = config.get(DOMAIN, {})
exclude = conf.get(CONF_EXCLUDE, {})
include = conf.get(CONF_INCLUDE, {})
metrics = Metrics(prometheus_client, exclude, include)
conf = config[DOMAIN]
entity_filter = conf[CONF_FILTER]
namespace = conf.get(CONF_PROM_NAMESPACE)
metrics = PrometheusMetrics(prometheus_client, entity_filter, namespace)
hass.bus.listen(EVENT_STATE_CHANGED, metrics.handle_event)
return True
class Metrics(object):
class PrometheusMetrics(object):
"""Model all of the metrics which should be exposed to Prometheus."""
def __init__(self, prometheus_client, exclude, include):
def __init__(self, prometheus_client, entity_filter, namespace):
"""Initialize Prometheus Metrics."""
self.prometheus_client = prometheus_client
self.exclude = exclude.get(CONF_ENTITIES, []) + \
exclude.get(CONF_DOMAINS, [])
self.include_domains = include.get(CONF_DOMAINS, [])
self.include_entities = include.get(CONF_ENTITIES, [])
self._filter = entity_filter
if namespace:
self.metrics_prefix = "{}_".format(namespace)
else:
self.metrics_prefix = ""
self._metrics = {}
def handle_event(self, event):
@ -71,14 +77,7 @@ class Metrics(object):
_LOGGER.debug("Handling state update for %s", entity_id)
domain, _ = hacore.split_entity_id(entity_id)
if entity_id in self.exclude:
return
if domain in self.exclude and entity_id not in self.include_entities:
return
if self.include_domains and domain not in self.include_domains:
return
if not self.exclude and (self.include_entities and
entity_id not in self.include_entities):
if not self._filter(state.entity_id):
return
handler = '_handle_{}'.format(domain)
@ -100,7 +99,9 @@ class Metrics(object):
try:
return self._metrics[metric]
except KeyError:
self._metrics[metric] = factory(metric, documentation, labels)
full_metric_name = "{}{}".format(self.metrics_prefix, metric)
self._metrics[metric] = factory(
full_metric_name, documentation, labels)
return self._metrics[metric]
@staticmethod

View File

@ -674,7 +674,7 @@ postnl_api==1.0.2
proliphix==0.4.1
# homeassistant.components.prometheus
prometheus_client==0.1.0
prometheus_client==0.2.0
# homeassistant.components.sensor.systemmonitor
psutil==5.4.6

View File

@ -120,7 +120,7 @@ pilight==0.1.1
pmsensor==0.4
# homeassistant.components.prometheus
prometheus_client==0.1.0
prometheus_client==0.2.0
# homeassistant.components.notify.pushbullet
# homeassistant.components.sensor.pushbullet

View File

@ -12,7 +12,7 @@ def prometheus_client(loop, hass, aiohttp_client):
assert loop.run_until_complete(async_setup_component(
hass,
prometheus.DOMAIN,
{},
{prometheus.DOMAIN: {}},
))
return loop.run_until_complete(aiohttp_client(hass.http.app))