From d5bcb860738df0c9702c2e6f6954cfa08e3c7153 Mon Sep 17 00:00:00 2001 From: Piotr Dobrowolski Date: Fri, 10 Feb 2017 20:12:39 +0100 Subject: [PATCH] Add $lastSeen and prometheus metrics endpoint --- main.py | 34 ++++++++++++++++++++++++++++++++++ spejsiot/manager.py | 12 ++++++++++++ 2 files changed, 46 insertions(+) diff --git a/main.py b/main.py index aed6a2c..d975eda 100644 --- a/main.py +++ b/main.py @@ -31,6 +31,40 @@ def index(): return flask.render_template('index.html', devices=manager.devices) +def prometheus_sanitize(v): + return v.encode('unicode_escape').decode('utf-8') + +def prometheus_value(v): + return float(v) + +@app.route('/metrics') +def metrics(): + proplist = [] + + for _, dev in manager.devices.items(): + if not dev.online: + continue + + for endpoint_id, props in dev.endpoints.items(): + for property_id, value in props.items(): + if property_id.startswith('$'): + continue + try: + proplist.append('spejsiot{node_id="%s", name="%s", ' \ + 'endpoint="%s", property="%s"} %s' % ( + prometheus_sanitize(dev.node_id), + prometheus_sanitize(dev.name), + prometheus_sanitize(endpoint_id), + prometheus_sanitize(property_id), + prometheus_value(value), + )) + except ValueError: + # This is most probably just a string value + continue + return '\n'.join(proplist), 200, { + 'Content-Type': 'text/plain; version=0.0.4', + } + @app.route('/api/1/devices/') def api_devices(): """Lists all known devices. diff --git a/spejsiot/manager.py b/spejsiot/manager.py index 852f93d..6c4e4c1 100644 --- a/spejsiot/manager.py +++ b/spejsiot/manager.py @@ -1,6 +1,7 @@ import paho.mqtt.client as mqtt from collections import defaultdict import logging +import time class SpejsiotDevice(object): node_id = None @@ -27,6 +28,15 @@ class SpejsiotDevice(object): return True + @property + def online(self): + return self.properties.get('$online', False) + + @property + def name(self): + return self.properties.get('$name', '') + + class SpejsiotManager(mqtt.Client): devices = dict() logger = logging.getLogger('manager') @@ -60,6 +70,8 @@ class SpejsiotManager(mqtt.Client): else: value = msg.payload.decode('utf-8') + self.devices[node_id].properties['$lastSeen'] = int(time.time()) + if topic.startswith('$'): self.devices[node_id].properties[topic] = value else: