From 761036985a543b71f6d7ccfea28a74343965c954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20Nagy?= Date: Fri, 25 Mar 2016 11:06:25 +0100 Subject: [PATCH] exports: riemann export implemented and documented MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch introduces a new export method for sending metrics to __Riemann__ server using _TCP_ protocol. The module can be enabled like all the other exports in __Glances__, specifying the `--export-riemann` option. Sending metrics to Riemann requires [bernhard](https://github.com/banjiewen/bernhard) that is the most popular _Riemann client_ written in python. In the configuration file you can only specify the `host` and `port` that riemann is listening for new connections on. Later new options are planned to be added like __SSL__ support and __UDP__. Documentation and manpages are refreshed according to the modifications in the config options and introducing the usage of Riemann export. Signed-off-by: Gergő Nagy --- README.rst | 25 +++++++- docs/cmds.rst | 4 ++ docs/gw/riemann.rst | 20 +++++++ docs/man/glances.1 | 5 ++ glances/exports/glances_riemann.py | 93 ++++++++++++++++++++++++++++++ glances/main.py | 2 + 6 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 docs/gw/riemann.rst create mode 100644 glances/exports/glances_riemann.py diff --git a/README.rst b/README.rst index 73e39deb..f5fdd494 100644 --- a/README.rst +++ b/README.rst @@ -50,6 +50,7 @@ Optional dependencies: - ``docker-py`` (for the Docker monitoring support) [Linux-only] - ``matplotlib`` (for graphical/chart support) - ``pika`` (for the RabbitMQ/ActiveMQ export module) +- ``bernhard`` (for the Riemann export module) - ``py-cpuinfo`` (for the Quicklook CPU info module) - ``scandir`` (for the Folders plugin) [Only for Python < 3.5] @@ -223,6 +224,28 @@ Puppet You can install Glances using ``Puppet``: https://github.com/rverchere/puppet-glances +Known issue on RHEL/CentOS/Fedora installation +============================================== + +For Python 2.6 RedHat-based distros there might be an issue with starting Glances: + +``` +Traceback (most recent call last): +File "/usr/bin/glances", line 5, in +from pkg_resources import load_entry_point +File "/usr/lib/python2.6/site-packages/pkg_resources.py", line 2655, in +workingset.require(_requires) +File "/usr/lib/python2.6/site-packages/pkg_resources.py", line 648, in require +needed = self.resolve(parse_requirements(requirements)) +File "/usr/lib/python2.6/site-packages/pkg_resources.py", line 546, in resolve +raise DistributionNotFound(req) +pkg_resources.DistributionNotFound: argparse +``` + +Try upgrading setuptools, has been proven to solve the problem: + + sudo pip install -U setuptools + Usage ===== @@ -274,7 +297,7 @@ Gateway to other services ========================= Glances can export stats to: ``CSV`` file, ``InfluxDB``, ``OpenTSDB``, -``StatsD``, ``ElasticSearch`` and ``RabbitMQ`` server. +``StatsD``, ``RabbitMQ`` and ``Riemann`` server. How to contribute ? =================== diff --git a/docs/cmds.rst b/docs/cmds.rst index b473f066..cfd51115 100644 --- a/docs/cmds.rst +++ b/docs/cmds.rst @@ -139,6 +139,10 @@ Command-Line Options export stats to RabbitMQ broker (pika lib needed) +.. option:: --export-riemann + + export stats to Riemann server (bernhard lib needed) + .. option:: --export-elasticsearch export stats to an Elasticsearch server (elasticsearch lib needed) diff --git a/docs/gw/riemann.rst b/docs/gw/riemann.rst new file mode 100644 index 00000000..d620ca87 --- /dev/null +++ b/docs/gw/riemann.rst @@ -0,0 +1,20 @@ +.. _riemann: + +Riemann +======== + +You can export statistics to an ``Riemann`` server (using TCP protocol). The +connection should be defined in the Glances configuration file as +following: + +.. code-block:: ini + + [rabbitmq] + host=localhost + port=5555 + +and run Glances with: + +.. code-block:: console + + $ glances --export-riemann diff --git a/docs/man/glances.1 b/docs/man/glances.1 index 0018d8a1..81505cd9 100644 --- a/docs/man/glances.1 +++ b/docs/man/glances.1 @@ -214,6 +214,11 @@ export stats to RabbitMQ broker (pika lib needed) .UNINDENT .INDENT 0.0 .TP +.B \-\-export\-riemann +export stats to Riemann server (bernhard lib needed) +.UNINDENT +.INDENT 0.0 +.TP .B \-\-export\-elasticsearch export stats to an Elasticsearch server (elasticsearch lib needed) .UNINDENT diff --git a/glances/exports/glances_riemann.py b/glances/exports/glances_riemann.py new file mode 100644 index 00000000..06266908 --- /dev/null +++ b/glances/exports/glances_riemann.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +# +# This file is part of Glances. +# +# Copyright (C) 2015 Nicolargo +# +# 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 . + +"""JMS interface class.""" + +import socket +import sys +from numbers import Number + +from glances.compat import NoOptionError, NoSectionError, range +from glances.logger import logger +from glances.exports.glances_export import GlancesExport + +# Import pika for Riemann +import bernhard + + +class Export(GlancesExport): + + """This class manages the Riemann export module.""" + + def __init__(self, config=None, args=None): + """Init the Riemann export IF.""" + super(Export, self).__init__(config=config, args=args) + + # Load the rabbitMQ configuration file + self.riemann_host = None + self.riemann_port = None + self.hostname = socket.gethostname() + self.export_enable = self.load_conf() + if not self.export_enable: + sys.exit(2) + + # Init the rabbitmq client + self.client = self.init() + + def load_conf(self, section="riemann"): + """Load the Riemann configuration in the Glances configuration file.""" + if self.config is None: + return False + try: + self.riemann_host = self.config.get_value(section, 'host') + self.riemann_port = int(self.config.get_value(section, 'port')) + except NoSectionError: + logger.critical("No riemann configuration found") + return False + except NoOptionError as e: + logger.critical("Error in the Riemann configuration (%s)" % e) + return False + else: + logger.debug("Load Riemann from the Glances configuration file") + return True + + def init(self): + """Init the connection to the Riemann server.""" + if not self.export_enable: + return None + try: + client = bernhard.Client(host=self.riemann_host, port=self.riemann_port) + return client + except Exception as e: + logger.critical("Connection to Riemann failed : %s " % e) + return None + + def export(self, name, columns, points): + """Write the points in Riemann.""" + for i in range(len(columns)): + if not isinstance(points[i], Number): + continue + else: + data = { 'host': self.hostname, 'service': name + " " + columns[i], 'metric': points[i] } + logger.debug(data) + try: + self.client.send(data) + except Exception as e: + logger.error("Can not export stats to Riemann (%s)" % e) + diff --git a/glances/main.py b/glances/main.py index c7f28d9d..9be00fcb 100644 --- a/glances/main.py +++ b/glances/main.py @@ -163,6 +163,8 @@ Start the client browser (browser mode):\n\ dest='export_elasticsearch', help='export stats to an ElasticSearch server (elasticsearch lib needed)') parser.add_argument('--export-rabbitmq', action='store_true', default=False, dest='export_rabbitmq', help='export stats to rabbitmq broker (pika lib needed)') + parser.add_argument('--export-riemann', action='store_true', default=False, + dest='export_riemann', help='export stats to riemann broker (bernhard lib needed)') # Client/Server option parser.add_argument('-c', '--client', dest='client', help='connect to a Glances server by IPv4/IPv6 address or hostname')