Implement ok of the Promotheus Exporter, need to add the plugin documentation

This commit is contained in:
nicolargo 2017-03-19 10:42:01 +01:00
parent c41f74f579
commit 021d460326
7 changed files with 153 additions and 9 deletions

View File

@ -361,6 +361,22 @@ port=5678
# - Third frame with the Glances plugin stats (JSON)
prefix=G
[prometheus]
# Configuration for the --export-prometheus option
# https://prometheus.io
# Create a Prometheus exporter listening on localhost:9091 (default configuration)
# Metric are exporter using the following name:
# <prefix>_<plugin>_<stats> (all specials character are replaced by '_')
# Note: You should add this exporter to your Prometheus server configuration:
# scrape_configs:
# - job_name: 'glances_exporter'
# scrape_interval: 5s
# static_configs:
# - targets: ['localhost:9091']
host=localhost
port=9091
prefix=glances
##############################################################################
# AMPS
# * enable: Enable (true) or disable (false) the AMP

34
docs/gw/prometheus.rst Normal file
View File

@ -0,0 +1,34 @@
.. _cassandra:
Cassandra
=========
You can export statistics to a ``Cassandra`` or ``Scylla`` server.
The connection should be defined in the Glances configuration file as
following:
.. code-block:: ini
[cassandra]
host=localhost
port=9042
protocol_version=3
keyspace=glances
replication_factor=2
table=localhost
and run Glances with:
.. code-block:: console
$ glances --export-cassandra
The data model is the following:
.. code-block:: ini
CREATE TABLE <table> (plugin text, time timeuuid, stat map<text,float>, PRIMARY KEY (plugin, time))
Only numerical stats are stored in the Cassandra table. All the stats
are converted to float. If a stat cannot be converted to float, it is
not stored in the database.

View File

@ -25,6 +25,7 @@ from numbers import Number
from glances.logger import logger
from glances.exports.glances_export import GlancesExport
from glances.compat import iteritems
from cassandra.cluster import Cluster
from cassandra.util import uuid_from_time

View File

@ -0,0 +1,89 @@
# -*- coding: utf-8 -*-
#
# This file is part of Glances.
#
# Copyright (C) 2017 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/>.
"""Prometheus interface class."""
import sys
from datetime import datetime
from numbers import Number
from glances.logger import logger
from glances.exports.glances_export import GlancesExport
from glances.compat import iteritems
from prometheus_client import start_http_server, Gauge
class Export(GlancesExport):
"""This class manages the Prometheus export module."""
METRIC_SEPARATOR = '_'
def __init__(self, config=None, args=None):
"""Init the Prometheus export IF."""
super(Export, self).__init__(config=config, args=args)
# Optionals configuration keys
self.prefix = 'glances'
# Load the Prometheus configuration file section
self.export_enable = self.load_conf('prometheus',
mandatories=['host', 'port'],
options=['prefix'])
if not self.export_enable:
sys.exit(2)
# Init the metric dict
# Perhaps a better method is possible...
self._metric_dict = {}
# Init the Prometheus Exporter
self.init()
def init(self):
"""Init the Prometheus Exporter"""
try:
start_http_server(port=int(self.port), addr=self.host)
except Exception as e:
logger.critical("Can not start Prometheus exporter on {}:{} ({})".format(self.host, self.port, e))
sys.exit(2)
else:
logger.info("Start Prometheus exporter on {}:{}".format(self.host, self.port))
def export(self, name, columns, points):
"""Write the points to the Prometheus exporter using Gauge."""
logger.debug("Export {} stats to Prometheus exporter".format(name))
# Remove non number stats and convert all to float (for Boolean)
data = {k: float(v) for (k, v) in iteritems(dict(zip(columns, points))) if isinstance(v, Number)}
# Write metrics to the Prometheus exporter
for k, v in iteritems(data):
# Prometheus metric name: prefix_<glances stats name>
metric_name = self.prefix + self.METRIC_SEPARATOR + name + self.METRIC_SEPARATOR + k
# Prometheus is very sensible to the metric name
# See: https://prometheus.io/docs/practices/naming/
for c in ['.', '-', '/', ' ']:
metric_name = metric_name.replace(c, self.METRIC_SEPARATOR)
# Manage an internal dict between metric name and Gauge
if metric_name not in self._metric_dict:
self._metric_dict[metric_name] = Gauge(metric_name, k)
# Write the value
self._metric_dict[metric_name].set(v)

View File

@ -173,22 +173,24 @@ Examples of use:
dest='path_graph', help='set the export path for graphs (default is {})'.format(tempfile.gettempdir()))
parser.add_argument('--export-csv', default=None,
dest='export_csv', help='export stats to a CSV file')
parser.add_argument('--export-influxdb', action='store_true', default=False,
dest='export_influxdb', help='export stats to an InfluxDB server (influxdb lib needed)')
parser.add_argument('--export-cassandra', action='store_true', default=False,
dest='export_cassandra', help='export stats to a Cassandra or Scylla server (cassandra lib needed)')
parser.add_argument('--export-opentsdb', action='store_true', default=False,
dest='export_opentsdb', help='export stats to an OpenTSDB server (potsdb lib needed)')
parser.add_argument('--export-statsd', action='store_true', default=False,
dest='export_statsd', help='export stats to a StatsD server (statsd lib needed)')
parser.add_argument('--export-couchdb', action='store_true', default=False,
dest='export_couchdb', help='export stats to a CouchDB server (couch lib needed)')
parser.add_argument('--export-elasticsearch', action='store_true', default=False,
dest='export_elasticsearch', help='export stats to an ElasticSearch server (elasticsearch lib needed)')
parser.add_argument('--export-influxdb', action='store_true', default=False,
dest='export_influxdb', help='export stats to an InfluxDB server (influxdb lib needed)')
parser.add_argument('--export-opentsdb', action='store_true', default=False,
dest='export_opentsdb', help='export stats to an OpenTSDB server (potsdb lib needed)')
parser.add_argument('--export-prometheus', action='store_true', default=False,
dest='export_prometheus', help='export stats to a Prometheus exporter (prometheus_client 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)')
parser.add_argument('--export-couchdb', action='store_true', default=False,
dest='export_couchdb', help='export stats to a CouchDB server (couch lib needed)')
parser.add_argument('--export-statsd', action='store_true', default=False,
dest='export_statsd', help='export stats to a StatsD server (statsd lib needed)')
parser.add_argument('--export-zeromq', action='store_true', default=False,
dest='export_zeromq', help='export stats to a ZeroMQ server (pyzmq lib needed)')
# Client/Server option

View File

@ -10,6 +10,7 @@ netifaces
nvidia-ml-py; python_version == "2.7"
pika
potsdb
prometheus_client
py-cpuinfo
pymdstat
pysnmp

View File

@ -85,7 +85,8 @@ setup(
'chart': ['matplotlib'],
'docker': ['docker>=2.0.0'],
'export': ['bernhard', 'cassandra-driver', 'couchdb', 'elasticsearch',
'influxdb>=1.0.0', 'pika', 'potsdb', 'pyzmq', 'statsd'],
'influxdb>=1.0.0', 'pika', 'potsdb', 'prometheus_client',
'pyzmq', 'statsd'],
'folders:python_version<"3.5"': ['scandir'],
'gpu:python_version=="2.7"': ['nvidia-ml-py'],
'ip': ['netifaces'],