summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Eriksson <molobrakos@users.noreply.github.com>2018-08-13 12:51:15 +0200
committerErik Eriksson <molobrakos@users.noreply.github.com>2018-08-13 13:00:42 +0200
commita83c74e6131ebf8f8558cc3213e0376425a0f85b (patch)
tree67c0a9464198d2fe8eca3e8324e39de9a5ab464c
parentd608ef3e4d27bfb62ef6a611612dcf7f25000f2b (diff)
Support for exporting data to a MQTT server
-rw-r--r--conf/glances.conf8
-rw-r--r--docs/gw/index.rst1
-rw-r--r--docs/gw/mqtt.rst23
-rw-r--r--glances/README.txt1
-rw-r--r--glances/exports/glances_mqtt.py98
-rw-r--r--optional-requirements.txt1
-rwxr-xr-xsetup.py2
7 files changed, 133 insertions, 1 deletions
diff --git a/conf/glances.conf b/conf/glances.conf
index 65057946..78564ce9 100644
--- a/conf/glances.conf
+++ b/conf/glances.conf
@@ -399,6 +399,14 @@ user=guest
password=guest
queue=glances_queue
+[mqtt]
+# Configuration for the --export mqtt option
+host=localhost
+port=8883
+user=guest
+password=guest
+topic=glances
+
[couchdb]
# Configuration for the --export couchdb option
# https://www.couchdb.org
diff --git a/docs/gw/index.rst b/docs/gw/index.rst
index 7f587a4f..82d875f1 100644
--- a/docs/gw/index.rst
+++ b/docs/gw/index.rst
@@ -18,6 +18,7 @@ to providing stats to multiple services (see list below).
influxdb
json
kafka
+ mqtt
opentsdb
prometheus
rabbitmq
diff --git a/docs/gw/mqtt.rst b/docs/gw/mqtt.rst
new file mode 100644
index 00000000..25f2b005
--- /dev/null
+++ b/docs/gw/mqtt.rst
@@ -0,0 +1,23 @@
+.. _mqtt:
+
+MQTT
+========
+
+You can export statistics to an ``MQTT`` server. The
+connection should be defined in the Glances configuration file as
+following:
+
+.. code-block:: ini
+
+ [mqtt]
+ host=localhost
+ port=883
+ user=glances
+ password=glances
+ topic=glances
+
+and run Glances with:
+
+.. code-block:: console
+
+ $ glances --export mqtt
diff --git a/glances/README.txt b/glances/README.txt
index bbf94ebf..f7ba0575 100644
--- a/glances/README.txt
+++ b/glances/README.txt
@@ -44,6 +44,7 @@ exports
=> Glances export interfaces
glances_csv.py The CSV export module
glances_influxdb.py The InfluxDB export module
+ glances_mqtt.py The MQTT export module
glances_opentsdb.py The OpenTSDB export module
glances_rabbitmq.py The RabbitMQ export module
glances_statsd.py The StatsD export module
diff --git a/glances/exports/glances_mqtt.py b/glances/exports/glances_mqtt.py
new file mode 100644
index 00000000..017e33c8
--- /dev/null
+++ b/glances/exports/glances_mqtt.py
@@ -0,0 +1,98 @@
+# -*- coding: utf-8 -*-
+#
+# This file is part of Glances.
+#
+# Copyright (C) 2018 Nicolargo <nicolas@nicolargo.com>
+#
+# Glances is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Glances is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""MQTT interface class."""
+
+import socket
+import string
+
+from glances.logger import logger
+from glances.exports.glances_export import GlancesExport
+
+# Import paho for MQTT
+from requests import certs
+import paho.mqtt.client as paho
+
+
+class Export(GlancesExport):
+
+ """This class manages the MQTT export module."""
+
+ def __init__(self, config=None, args=None):
+ """Init the MQTT export IF."""
+ super(Export, self).__init__(config=config, args=args)
+
+ # Mandatories configuration keys (additional to host and port)
+ self.user = None
+ self.password = None
+ self.topic = None
+
+ # Load the MQTT configuration file
+ self.export_enable = self.load_conf('mqtt',
+ mandatories=['host', 'password'],
+ options=['port', 'user', 'topic'])
+ if not self.export_enable:
+ exit('Missing MQTT config')
+
+ # Get the current hostname
+ self.hostname = socket.gethostname()
+
+ self.port = self.port or 8883
+ self.topic = self.topic or 'glances'
+ self.user = self.user or 'glances'
+
+ # Init the MQTT client
+ self.client = self.init()
+
+ def init(self):
+ """Init the connection to the MQTT server."""
+ if not self.export_enable:
+ return None
+ try:
+ client = paho.Client(client_id='glances_' + self.hostname,
+ clean_session=False)
+ client.username_pw_set(username=self.user,
+ password=self.password)
+ client.tls_set(certs.where())
+ client.connect(host=self.host,
+ port=self.port)
+ client.loop_start()
+ return client
+ except Exception as e:
+ logger.critical("Connection to MQTT server failed : %s " % e)
+ return None
+
+ def export(self, name, columns, points):
+ """Write the points in MQTT."""
+
+ WHITELIST='_-' + string.ascii_letters + string.digits
+ SUBSTITUTE='_'
+
+ def whitelisted(s,
+ whitelist=WHITELIST,
+ 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('.')]
+ topic = '/'.join([self.topic, self.hostname, name, *sensor])
+ self.client.publish(topic, value)
+ except Exception as e:
+ logger.error("Can not export stats to MQTT server (%s)" % e)
diff --git a/optional-requirements.txt b/optional-requirements.txt
index a3abd92d..65dc7f14 100644
--- a/optional-requirements.txt
+++ b/optional-requirements.txt
@@ -8,6 +8,7 @@ influxdb
kafka-python
netifaces
nvidia-ml-py3
+paho-mqtt
pika
potsdb
prometheus_client
diff --git a/setup.py b/setup.py
index c72a0ec8..d66fd93d 100755
--- a/setup.py
+++ b/setup.py
@@ -89,7 +89,7 @@ setup(
'cpuinfo': ['py-cpuinfo'],
'docker': ['docker>=2.0.0'],
'export': ['bernhard', 'cassandra-driver', 'couchdb', 'elasticsearch',
- 'influxdb>=1.0.0', 'kafka-python', 'pika', 'potsdb',
+ 'influxdb>=1.0.0', 'kafka-python', 'pika', 'paho-mqtt', 'potsdb',
'prometheus_client', 'pyzmq', 'statsd'],
'folders': ['scandir'], # python_version<"3.5"
'gpu': ['nvidia-ml-py3'], # python_version=="2.7"