From 63f0375362c7437a1d924a6831815c2764f75362 Mon Sep 17 00:00:00 2001 From: Deosrc Date: Fri, 22 Jan 2021 21:45:11 +0000 Subject: [PATCH 1/4] Add mqtt output in JSON format --- glances/exports/glances_mqtt.py | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/glances/exports/glances_mqtt.py b/glances/exports/glances_mqtt.py index 2aa5b8b2..1b1dbf3c 100644 --- a/glances/exports/glances_mqtt.py +++ b/glances/exports/glances_mqtt.py @@ -21,6 +21,7 @@ import socket import string +import json from glances.logger import logger from glances.exports.glances_export import GlancesExport @@ -47,7 +48,7 @@ class Export(GlancesExport): # Load the MQTT configuration file self.export_enable = self.load_conf('mqtt', mandatories=['host', 'password'], - options=['port', 'user', 'topic', 'tls']) + options=['port', 'user', 'topic', 'tls', 'format']) if not self.export_enable: exit('Missing MQTT config') @@ -59,6 +60,11 @@ class Export(GlancesExport): self.user = self.user or 'glances' self.tls = (self.tls and self.tls.lower() == 'true') + self.format = self.format.lower() or 'simple' + if self.format not in ['simple', 'json']: + logger.critical("Format must be either 'simple' or 'json'.") + return None + # Init the MQTT client self.client = self.init() @@ -92,13 +98,23 @@ class Export(GlancesExport): substitute=SUBSTITUTE): return ''.join(c if c in whitelist else substitute for c in s) - for sensor, value in zip(columns, points): - try: - sensor = [whitelisted(name) for name in sensor.split('.')] - tobeexport = [self.topic, self.hostname, name] - tobeexport.extend(sensor) - topic = '/'.join(tobeexport) + if self.format == 'simple': + for sensor, value in zip(columns, points): + try: + sensor = [whitelisted(name) for name in sensor.split('.')] + tobeexport = [self.topic, self.hostname, name] + tobeexport.extend(sensor) + topic = '/'.join(tobeexport) - self.client.publish(topic, value) + self.client.publish(topic, value) + except Exception as e: + logger.error("Can not export stats to MQTT server (%s)" % e) + elif self.format == 'json': + try: + topic = '/'.join([self.topic, self.hostname, name]) + sensor_values = dict(zip(columns, points)) + json_values = json.dumps(sensor_values) + self.client.publish(topic, json_values) except Exception as e: logger.error("Can not export stats to MQTT server (%s)" % e) + From 6eaf0cb940e7e0a6a1b6e3475161b3764b5ceefc Mon Sep 17 00:00:00 2001 From: Deosrc Date: Fri, 22 Jan 2021 22:33:36 +0000 Subject: [PATCH 2/4] Reformat JSON output into hierarchy structure --- glances/exports/glances_mqtt.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/glances/exports/glances_mqtt.py b/glances/exports/glances_mqtt.py index 1b1dbf3c..4a20aaeb 100644 --- a/glances/exports/glances_mqtt.py +++ b/glances/exports/glances_mqtt.py @@ -113,8 +113,24 @@ class Export(GlancesExport): try: topic = '/'.join([self.topic, self.hostname, name]) sensor_values = dict(zip(columns, points)) - json_values = json.dumps(sensor_values) - self.client.publish(topic, json_values) + + # Build the value to output + output_value = dict() + for key in sensor_values: + split_key = key.split('.') + + # Add the parent keys if they don't exist + current_level = output_value + for depth in range(len(split_key) - 1): + if split_key[depth] not in current_level: + current_level[split_key[depth]] = dict() + current_level = current_level[split_key[depth]] + + # Add the value + current_level[split_key[len(split_key) - 1]] = sensor_values[key] + + json_value = json.dumps(output_value) + self.client.publish(topic, json_value) except Exception as e: logger.error("Can not export stats to MQTT server (%s)" % e) From e2da7734d40e679720fc9f25caa02d1fa81b2cef Mon Sep 17 00:00:00 2001 From: Deosrc Date: Mon, 25 Jan 2021 15:18:05 +0000 Subject: [PATCH 3/4] Rename parameter for topic structure --- docs/gw/mqtt.rst | 1 + glances/exports/glances_mqtt.py | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/gw/mqtt.rst b/docs/gw/mqtt.rst index 25f2b005..6b6b81e7 100644 --- a/docs/gw/mqtt.rst +++ b/docs/gw/mqtt.rst @@ -15,6 +15,7 @@ following: user=glances password=glances topic=glances + topic_structure=per-metric and run Glances with: diff --git a/glances/exports/glances_mqtt.py b/glances/exports/glances_mqtt.py index 4a20aaeb..513e91c1 100644 --- a/glances/exports/glances_mqtt.py +++ b/glances/exports/glances_mqtt.py @@ -48,7 +48,7 @@ class Export(GlancesExport): # Load the MQTT configuration file self.export_enable = self.load_conf('mqtt', mandatories=['host', 'password'], - options=['port', 'user', 'topic', 'tls', 'format']) + options=['port', 'user', 'topic', 'tls', 'topic_structure']) if not self.export_enable: exit('Missing MQTT config') @@ -60,9 +60,9 @@ class Export(GlancesExport): self.user = self.user or 'glances' self.tls = (self.tls and self.tls.lower() == 'true') - self.format = self.format.lower() or 'simple' - if self.format not in ['simple', 'json']: - logger.critical("Format must be either 'simple' or 'json'.") + self.topic_structure = self.topic_structure.lower() or 'per-metric' + if self.topic_structure not in ['per-metric', 'per-plugin']: + logger.critical("topic_structure must be either 'per-metric' or 'per-plugin'.") return None # Init the MQTT client @@ -98,7 +98,7 @@ class Export(GlancesExport): substitute=SUBSTITUTE): return ''.join(c if c in whitelist else substitute for c in s) - if self.format == 'simple': + if self.topic_structure == 'per-metric': for sensor, value in zip(columns, points): try: sensor = [whitelisted(name) for name in sensor.split('.')] @@ -109,7 +109,7 @@ class Export(GlancesExport): self.client.publish(topic, value) except Exception as e: logger.error("Can not export stats to MQTT server (%s)" % e) - elif self.format == 'json': + elif self.topic_structure == 'per-plugin': try: topic = '/'.join([self.topic, self.hostname, name]) sensor_values = dict(zip(columns, points)) From e6273ef69b9429b94575ad3ff5ae361fbffc2899 Mon Sep 17 00:00:00 2001 From: Deosrc Date: Fri, 29 Jan 2021 23:46:01 +0000 Subject: [PATCH 4/4] Fix omitted config value causing error --- glances/exports/glances_mqtt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glances/exports/glances_mqtt.py b/glances/exports/glances_mqtt.py index 513e91c1..e64088d4 100644 --- a/glances/exports/glances_mqtt.py +++ b/glances/exports/glances_mqtt.py @@ -60,7 +60,7 @@ class Export(GlancesExport): self.user = self.user or 'glances' self.tls = (self.tls and self.tls.lower() == 'true') - self.topic_structure = self.topic_structure.lower() or 'per-metric' + self.topic_structure = (self.topic_structure or 'per-metric').lower() if self.topic_structure not in ['per-metric', 'per-plugin']: logger.critical("topic_structure must be either 'per-metric' or 'per-plugin'.") return None