summaryrefslogtreecommitdiffstats
path: root/glances/exports
diff options
context:
space:
mode:
Diffstat (limited to 'glances/exports')
-rw-r--r--glances/exports/export.py42
-rw-r--r--glances/exports/glances_cassandra/__init__.py43
-rw-r--r--glances/exports/glances_couchdb/__init__.py24
-rw-r--r--glances/exports/glances_csv/__init__.py26
-rw-r--r--glances/exports/glances_elasticsearch/__init__.py30
-rw-r--r--glances/exports/glances_graph/__init__.py29
-rw-r--r--glances/exports/glances_graphite/__init__.py24
-rw-r--r--glances/exports/glances_influxdb/__init__.py34
-rw-r--r--glances/exports/glances_influxdb2/__init__.py39
-rw-r--r--glances/exports/glances_json/__init__.py19
-rw-r--r--glances/exports/glances_kafka/__init__.py24
-rw-r--r--glances/exports/glances_mongodb/__init__.py22
-rwxr-xr-xglances/exports/glances_mqtt/__init__.py34
-rw-r--r--glances/exports/glances_opentsdb/__init__.py20
-rw-r--r--glances/exports/glances_prometheus/__init__.py16
-rw-r--r--glances/exports/glances_rabbitmq/__init__.py21
-rw-r--r--glances/exports/glances_restful/__init__.py15
-rw-r--r--glances/exports/glances_riemann/__init__.py29
-rw-r--r--glances/exports/glances_statsd/__init__.py22
-rw-r--r--glances/exports/glances_zeromq/__init__.py23
20 files changed, 258 insertions, 278 deletions
diff --git a/glances/exports/export.py b/glances/exports/export.py
index aaa6e045..0241e1b8 100644
--- a/glances/exports/export.py
+++ b/glances/exports/export.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# This file is part of Glances.
#
@@ -13,14 +12,12 @@ I am your father...
...for all Glances exports IF.
"""
-from glances.globals import json_dumps
-
-from glances.globals import NoOptionError, NoSectionError, iteritems, iterkeys
+from glances.globals import NoOptionError, NoSectionError, iteritems, iterkeys, json_dumps
from glances.logger import logger
+from glances.timer import Counter
-class GlancesExport(object):
-
+class GlancesExport:
"""Main class for Glances export IF."""
# List of non exportable plugins
@@ -41,7 +38,7 @@ class GlancesExport(object):
"""Init the export class."""
# Export name
self.export_name = self.__class__.__module__
- logger.debug("Init export module %s" % self.export_name)
+ logger.debug(f"Init export module {self.export_name}")
# Init the config & args
self.config = config
@@ -58,9 +55,23 @@ class GlancesExport(object):
# Save last export list
self._last_exported_list = None
+ def _log_result_decorator(fct):
+ """Log (DEBUG) the result of the function fct."""
+
+ def wrapper(*args, **kw):
+ counter = Counter()
+ ret = fct(*args, **kw)
+ duration = counter.get()
+ class_name = args[0].__class__.__name__
+ class_module = args[0].__class__.__module__
+ logger.debug(f"{class_name} {class_module} {fct.__name__} return {ret} in {duration} seconds")
+ return ret
+
+ return wrapper
+
def exit(self):
"""Close the export module."""
- logger.debug("Finalise export interface %s" % self.export_name)
+ logger.debug(f"Finalise export interface {self.export_name}")
def load_conf(self, section, mandatories=['host', 'port'], options=None):
"""Load the export <section> configuration in the Glances configuration file.
@@ -81,10 +92,10 @@ class GlancesExport(object):
for opt in mandatories:
setattr(self, opt, self.config.get_value(section, opt))
except NoSectionError:
- logger.error("No {} configuration found".format(section))
+ logger.error(f"No {section} configuration found")
return False
except NoOptionError as e:
- logger.error("Error in the {} configuration ({})".format(section, e))
+ logger.error(f"Error in the {section} configuration ({e})")
return False
# Load options
@@ -94,8 +105,8 @@ class GlancesExport(object):
except NoOptionError:
pass
- logger.debug("Load {} from the Glances configuration file".format(section))
- logger.debug("{} parameters: {}".format(section, {opt: getattr(self, opt) for opt in mandatories + options}))
+ logger.debug(f"Load {section} from the Glances configuration file")
+ logger.debug(f"{section} parameters: {({opt: getattr(self, opt) for opt in mandatories + options})}")
return True
@@ -105,11 +116,10 @@ class GlancesExport(object):
try:
ret = item[item['key']]
except KeyError:
- logger.error("No 'key' available in {}".format(item))
+ logger.error(f"No 'key' available in {item}")
if isinstance(ret, list):
return ret[0]
- else:
- return ret
+ return ret
def parse_tags(self, tags):
"""Parse tags into a dict.
@@ -183,7 +193,7 @@ class GlancesExport(object):
else:
pre_key = ''
# Walk through the dict
- for key, value in iteritems(stats):
+ for key, value in sorted(iteritems(stats)):
if isinstance(value, bool):
value = json_dumps(value)
if isinstance(value, list):
diff --git a/glances/exports/glances_cassandra/__init__.py b/glances/exports/glances_cassandra/__init__.py
index aa88eb13..4325a63b 100644
--- a/glances/exports/glances_cassandra/__init__.py
+++ b/glances/exports/glances_cassandra/__init__.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# This file is part of Glances.
#
@@ -13,22 +12,21 @@ import sys
from datetime import datetime
from numbers import Number
-from glances.logger import logger
-from glances.exports.export import GlancesExport
-
+from cassandra import InvalidRequest
from cassandra.auth import PlainTextAuthProvider
from cassandra.cluster import Cluster
from cassandra.util import uuid_from_time
-from cassandra import InvalidRequest
+from glances.exports.export import GlancesExport
+from glances.logger import logger
-class Export(GlancesExport):
+class Export(GlancesExport):
"""This class manages the Cassandra/Scylla export module."""
def __init__(self, config=None, args=None):
"""Init the Cassandra export IF."""
- super(Export, self).__init__(config=config, args=args)
+ super().__init__(config=config, args=args)
# Mandatory configuration keys (additional to host and port)
self.keyspace = None
@@ -70,53 +68,52 @@ class Export(GlancesExport):
)
session = cluster.connect()
except Exception as e:
- logger.critical("Cannot connect to Cassandra cluster '%s:%s' (%s)" % (self.host, self.port, e))
+ logger.critical(f"Cannot connect to Cassandra cluster '{self.host}:{self.port}' ({e})")
sys.exit(2)
# Keyspace
try:
session.set_keyspace(self.keyspace)
except InvalidRequest:
- logger.info("Create keyspace {} on the Cassandra cluster".format(self.keyspace))
- c = "CREATE KEYSPACE %s WITH replication = { 'class': 'SimpleStrategy', 'replication_factor': '%s' }" % (
- self.keyspace,
- self.replication_factor,
+ logger.info(f"Create keyspace {self.keyspace} on the Cassandra cluster")
+ c = (
+ f"CREATE KEYSPACE {self.keyspace} WITH "
+ f"replication = {{ 'class': 'SimpleStrategy', 'replication_factor': '{self.replication_factor}' }}"
)
session.execute(c)
session.set_keyspace(self.keyspace)
logger.info(
- "Stats will be exported to Cassandra cluster {} ({}) in keyspace {}".format(
- cluster.metadata.cluster_name, cluster.metadata.all_hosts(), self.keyspace
- )
+ f"Stats will be exported to Cassandra cluster {cluster.metadata.cluster_name} "
+ f"({cluster.metadata.all_hosts()}) in keyspace {self.keyspace}"
)
# Table
try:
session.execute(
- "CREATE TABLE %s (plugin text, time timeuuid, stat map<text,float>, PRIMARY KEY (plugin, time)) \
- WITH CLUSTERING ORDER BY (time DESC)"
- % self.table
+ f"CREATE TABLE {self.table} "
+ f"(plugin text, time timeuuid, stat map<text,float>, PRIMARY KEY (plugin, time)) "
+ f"WITH CLUSTERING ORDER BY (time DESC)"
)
except Exception:
- logger.debug("Cassandra table %s already exist" % self.table)
+ logger.debug(f"Cassandra table {self.table} already exist")
return cluster, session
def export(self, name, columns, points):
"""Write the points to the Cassandra cluster."""
- logger.debug("Export {} stats to Cassandra".format(name))
+ logger.debug(f"Export {name} stats to Cassandra")
# Remove non number stats and convert all to float (for Boolean)
data = {k: float(v) for (k, v) in dict(zip(columns, points)).iteritems() if isinstance(v, Number)}
# Write input to the Cassandra table
try:
- stmt = "INSERT INTO {} (plugin, time, stat) VALUES (?, ?, ?)".format(self.table)
+ stmt = f"INSERT INTO {self.table} (plugin, time, stat) VALUES (?, ?, ?)"
query = self.session.prepare(stmt)
self.session.execute(query, (name, uuid_from_time(datetime.now()), data))
except Exception as e:
- logger.error("Cannot export {} stats to Cassandra ({})".format(name, e))
+ logger.error(f"Cannot export {name} stats to Cassandra ({e})")
def exit(self):
"""Close the Cassandra export module."""
@@ -124,4 +121,4 @@ class Export(GlancesExport):
self.session.shutdown()
self.cluster.shutdown()
# Call the father method
- super(Export, self).exit()
+ super().exit()
diff --git a/glances/exports/glances_couchdb/__init__.py b/glances/exports/glances_couchdb/__init__.py
index 5cc65529..4bedf4f3 100644
--- a/glances/exports/glances_couchdb/__init__.py
+++ b/glances/exports/glances_couchdb/__init__.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# This file is part of Glances.
#
@@ -20,19 +19,18 @@
import sys
from datetime import datetime
-from glances.logger import logger
-from glances.exports.export import GlancesExport
-
import pycouchdb
+from glances.exports.export import GlancesExport
+from glances.logger import logger
-class Export(GlancesExport):
+class Export(GlancesExport):
"""This class manages the CouchDB export module."""
def __init__(self, config=None, args=None):
"""Init the CouchDB export IF."""
- super(Export, self).__init__(config=config, args=args)
+ super().__init__(config=config, args=args)
# Load the CouchDB configuration file section
# User and Password are mandatory with CouchDB 3.0 and higher
@@ -49,15 +47,15 @@ class Export(GlancesExport):
return None
# @TODO: https
- server_uri = 'http://{}:{}@{}:{}/'.format(self.user, self.password, self.host, self.port)
+ server_uri = f'http://{self.user}:{self.password}@{self.host}:{self.port}/'
try:
s = pycouchdb.Server(server_uri)
except Exception as e:
- logger.critical("Cannot connect to CouchDB server (%s)" % e)
+ logger.critical(f"Cannot connect to CouchDB server ({e})")
sys.exit(2)
else:
- logger.info("Connected to the CouchDB server version %s" % s.info()['version'])
+ logger.info("Connected to the CouchDB server version {}".format(s.info()['version']))
try:
s.database(self.db)
@@ -65,15 +63,15 @@ class Export(GlancesExport):
# Database did not exist
# Create it...
s.create(self.db)
- logger.info("Create CouchDB database %s" % self.db)
+ logger.info(f"Create CouchDB database {self.db}")
else:
- logger.info("CouchDB database %s already exist" % self.db)
+ logger.info(f"CouchDB database {self.db} already exist")
return s.database(self.db)
def export(self, name, columns, points):
"""Write the points to the CouchDB server."""
- logger.debug("Export {} stats to CouchDB".format(name))
+ logger.debug(f"Export {name} stats to CouchDB")
# Create DB input
data = dict(zip(columns, points))
@@ -86,4 +84,4 @@ class Export(GlancesExport):
try:
self.client.save(data)
except Exception as e:
- logger.error("Cannot export {} stats to CouchDB ({})".format(name, e))
+ logger.error(f"Cannot export {name} stats to CouchDB ({e})")
diff --git a/glances/exports/glances_csv/__init__.py b/glances/exports/glances_csv/__init__.py
index 3324cbf9..0e4ca387 100644
--- a/glances/exports/glances_csv/__init__.py
+++ b/glances/exports/glances_csv/__init__.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# This file is part of Glances.
#
@@ -9,23 +8,21 @@
"""CSV interface class."""
-import os.path
import csv
+import os.path
import sys
import time
-from glances.globals import iterkeys, itervalues
-from glances.logger import logger
from glances.exports.export import GlancesExport
+from glances.logger import logger
class Export(GlancesExport):
-
"""This class manages the CSV export module."""
def __init__(self, config=None, args=None):
"""Init the CSV export IF."""
- super(Export, self).__init__(config=config, args=args)
+ super().__init__(config=config, args=args)
# CSV file name
self.csv_filename = args.export_csv_file
@@ -44,8 +41,8 @@ class Export(GlancesExport):
try:
self.csv_file = open_csv_file(self.csv_filename, 'r')
reader = csv.reader(self.csv_file)
- except IOError as e:
- logger.critical("Cannot open existing CSV file: {}".format(e))
+ except OSError as e:
+ logger.critical(f"Cannot open existing CSV file: {e}")
sys.exit(2)
self.old_header = next(reader, None)
self.csv_file.close()
@@ -53,11 +50,11 @@ class Export(GlancesExport):
try:
self.csv_file = open_csv_file(self.csv_filename, file_mode)
self.writer = csv.writer(self.csv_file)
- except IOError as e:
- logger.critical("Cannot create the CSV file: {}".format(e))
+ except OSError as e:
+ logger.critical(f"Cannot create the CSV file: {e}")
sys.exit(2)
- logger.info("Stats exported to CSV file: {}".format(self.csv_filename))
+ logger.info(f"Stats exported to CSV file: {self.csv_filename}")
self.export_enable = True
@@ -65,7 +62,7 @@ class Export(GlancesExport):
def exit(self):
"""Close the CSV file."""
- logger.debug("Finalise export interface %s" % self.export_name)
+ logger.debug(f"Finalise export interface {self.export_name}")
self.csv_file.close()
def update(self, stats):
@@ -97,8 +94,8 @@ class Export(GlancesExport):
if self.old_header != csv_header and self.old_header is not None:
# Header are different, log an error and do not write data
logger.error("Cannot append data to existing CSV file. Headers are different.")
- logger.debug("Old header: {}".format(self.old_header))
- logger.debug("New header: {}".format(csv_header))
+ logger.debug(f"Old header: {self.old_header}")
+ logger.debug(f"New header: {csv_header}")
else:
# Header are equals, ready to write data
self.old_header = None
@@ -112,7 +109,6 @@ class Export(GlancesExport):
def export(self, name, columns, points):
"""Export the stats to the CSV file.
For the moment everything is done in the update method."""
- pass
def open_csv_file(file_name, file_mode):
diff --git a/glances/exports/glances_elasticsearch/__init__.py b/glances/exports/glances_elasticsearch/__init__.py
index 83e5dc98..395f9def 100644
--- a/glances/exports/glances_elasticsearch/__init__.py
+++ b/glances/exports/glances_elasticsearch/__init__.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# This file is part of Glances.
#
@@ -12,19 +11,18 @@
import sys
from datetime import datetime
-from glances.logger import logger
-from glances.exports.export import GlancesExport
-
from elasticsearch import Elasticsearch, helpers
+from glances.exports.export import GlancesExport
+from glances.logger import logger
-class Export(GlancesExport):
+class Export(GlancesExport):
"""This class manages the ElasticSearch (ES) export module."""
def __init__(self, config=None, args=None):
"""Init the ES export IF."""
- super(Export, self).__init__(config=config, args=args)
+ super().__init__(config=config, args=args)
# Mandatory configuration keys (additional to host and port)
self.index = None
@@ -45,24 +43,22 @@ class Export(GlancesExport):
return None
try:
- es = Elasticsearch(hosts=['{}://{}:{}'.format(self.scheme, self.host, self.port)])
+ es = Elasticsearch(hosts=[f'{self.scheme}://{self.host}:{self.port}'])
except Exception as e:
- logger.critical(
- "Cannot connect to ElasticSearch server %s://%s:%s (%s)" % (self.scheme, self.host, self.port, e)
- )
+ logger.critical(f"Cannot connect to ElasticSearch server {self.scheme}://{self.host}:{self.port} ({e})")
sys.exit(2)
if not es.ping():
- logger.critical("Cannot ping the ElasticSearch server %s://%s:%s" % (self.scheme, self.host, self.port))
+ logger.critical(f"Cannot ping the ElasticSearch server {self.scheme}://{self.host}:{self.port}")
sys.exit(2)
else:
- logger.info("Connected to the ElasticSearch server %s://%s:%s" % (self.scheme, self.host, self.port))
+ logger.info(f"Connected to the ElasticSearch server {self.scheme}://{self.host}:{self.port}")
return es
def export(self, name, columns, points):
"""Write the points to the ES server."""
- logger.debug("Export {} stats to ElasticSearch".format(name))
+ logger.debug(f"Export {name} stats to ElasticSearch")
# Generate index name with the index field + current day
index = '{}-{}'.format(self.index, datetime.utcnow().strftime("%Y.%m.%d"))
@@ -73,17 +69,17 @@ class Export(GlancesExport):
dt_now = datetime.utcnow().isoformat('T')
action = {
"_index": index,
- "_id": '{}.{}'.format(name, dt_now),
- "_type": 'glances-{}'.format(name),
+ "_id": f'{name}.{dt_now}',
+ "_type": f'glances-{name}',
"_source": {"plugin": name, "timestamp": dt_now},
}
action['_source'].update(zip(columns, [str(p) for p in points]))
actions.append(action)
- logger.debug("Exporting the following object to elasticsearch: {}".format(action))
+ logger.debug(f"Exporting the following object to elasticsearch: {action}")
# Write input to the ES index
try:
helpers.bulk(self.client, actions)
except Exception as e:
- logger.error("Cannot export {} stats to ElasticSearch ({})".format(name, e))
+ logger.error(f"Cannot export {name} stats to ElasticSearch ({e})")
diff --git a/glances/exports/glances_graph/__init__.py b/glances/exports/glances_graph/__init__.py
index 24d4a98a..542be577 100644
--- a/glances/exports/glances_graph/__init__.py
+++ b/glances/exports/glances_graph/__init__.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# This file is part of Glances.
#
@@ -9,26 +8,26 @@
"""Graph exporter interface class."""
-from pygal import DateTimeLine
-import pygal.style
-import sys
+import errno
import os
+import sys
import tempfile
-import errno
+import pygal.style
+from pygal import DateTimeLine
+
+from glances.exports.export import GlancesExport
+from glances.globals import iteritems, time_serie_subsample
from glances.logger import logger
from glances.timer import Timer
-from glances.globals import iteritems, time_serie_subsample
-from glances.exports.export import GlancesExport
class Export(GlancesExport):
-
"""This class manages the Graph export module."""
def __init__(self, config=None, args=None):
"""Init the export IF."""
- super(Export, self).__init__(config=config, args=args)
+ super().__init__(config=config, args=args)
# Load the Graph configuration file section (is exists)
self.export_enable = self.load_conf('graph', options=['path', 'generate_every', 'width', 'height', 'style'])
@@ -45,19 +44,19 @@ class Export(GlancesExport):
os.makedirs(self.path)
except OSError as e:
if e.errno != errno.EEXIST:
- logger.critical("Cannot create the Graph output folder {} ({})".format(self.path, e))
+ logger.critical(f"Cannot create the Graph output folder {self.path} ({e})")
sys.exit(2)
# Check if output folder is writeable
try:
tempfile.TemporaryFile(dir=self.path)
except OSError:
- logger.critical("Graph output folder {} is not writeable".format(self.path))
+ logger.critical(f"Graph output folder {self.path} is not writeable")
sys.exit(2)
- logger.info("Graphs will be created in the {} folder".format(self.path))
+ logger.info(f"Graphs will be created in the {self.path} folder")
if self.generate_every != 0:
- logger.info("Graphs will be created automatically every {} seconds".format(self.generate_every))
+ logger.info(f"Graphs will be created automatically every {self.generate_every} seconds")
logger.info("or when 'g' key is pressed (only through the CLI interface)")
# Start the timer
self._timer = Timer(self.generate_every)
@@ -67,7 +66,7 @@ class Export(GlancesExport):
def exit(self):
"""Close the files."""
- logger.debug("Finalise export interface %s" % self.export_name)
+ logger.debug(f"Finalise export interface {self.export_name}")
def update(self, stats):
"""Generate Graph file in the output folder."""
@@ -85,7 +84,7 @@ class Export(GlancesExport):
if plugin_name in self.plugins_to_export(stats):
self.export(plugin_name, plugin.get_export_history())
- logger.info("Graphs created in {}".format(self.path))
+ logger.info(f"Graphs created in {self.path}")
self.args.generate_graph = False
def export(self, title, data):
diff --git a/glances/exports/glances_graphite/__init__.py b/glances/exports/glances_graphite/__init__.py
index 19c42da8..708e23db 100644
--- a/glances/exports/glances_graphite/__init__.py
+++ b/glances/exports/glances_graphite/__init__.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# This file is part of Glances.
#
@@ -12,19 +11,18 @@
import sys
from numbers import Number
-from glances.logger import logger
-from glances.exports.export import GlancesExport
-
from graphitesend import GraphiteClient
+from glances.exports.export import GlancesExport
+from glances.logger import logger
+
class Export(GlancesExport):
-
"""This class manages the Graphite export module."""
def __init__(self, config=None, args=None):
"""Init the Graphite export IF."""
- super(Export, self).__init__(config=config, args=args)
+ super().__init__(config=config, args=args)
# Mandatory configuration keys (additional to host and port)
# N/A
@@ -75,25 +73,25 @@ class Export(GlancesExport):
debug=self.debug,
)
except Exception as e:
- logger.error("Can not write data to Graphite server: {}:{} ({})".format(self.host, self.port, e))
+ logger.error(f"Can not write data to Graphite server: {self.host}:{self.port} ({e})")
client = None
else:
- logger.info("Stats will be exported to Graphite server: {}:{}".format(self.host, self.port))
+ logger.info(f"Stats will be exported to Graphite server: {self.host}:{self.port}")
return client
def export(self, name, columns, points):
"""Export the stats to the Graphite server."""
if self.client is None:
return False
- before_filtering_dict = dict(zip([normalize('{}.{}'.format(name, i)) for i in columns], points))
+ before_filtering_dict = dict(zip([normalize(f'{name}.{i}') for i in columns], points))
after_filtering_dict = dict(filter(lambda i: isinstance(i[1], Number), before_filtering_dict.items()))
try:
self.client.send_dict(after_filtering_dict)
except Exception as e:
- logger.error("Can not export stats to Graphite (%s)" % e)
+ logger.error(f"Can not export stats to Graphite ({e})")
return False
else:
- logger.debug("Export {} stats to Graphite".format(name))
+ logger.debug(f"Export {name} stats to Graphite")
return True
@@ -101,6 +99,4 @@ def normalize(name):
"""Normalize name for the Graphite convention"""
# Name should not contain space
- ret = name.replace(' ', '_')
-
- return ret
+ return name.replace(' ', '_')
diff --git a/glances/exports/glances_influxdb/__init__.py b/glances/exports/glances_influxdb/__init__.py
index a69bfb81..e2e5c6ca 100644
--- a/glances/exports/glances_influxdb/__init__.py
+++ b/glances/exports/glances_influxdb/__init__.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# This file is part of Glances.
#
@@ -12,19 +11,21 @@
import sys
from platform import node
-from glances.logger import logger
-from glances.exports.export import GlancesExport
-
from influxdb import InfluxDBClient
from influxdb.client import InfluxDBClientError
+from glances.exports.export import GlancesExport
+from glances.logger import logger
+
+FIELD_TO_TAG = ['name', 'cmdline', 'type']
+
class Export(GlancesExport):
"""This class manages the InfluxDB export module."""
def __init__(self, config=None, args=None):
"""Init the InfluxDB export IF."""
- super(Export, self).__init__(config=config, args=args)
+ super().__init__(config=config, args=args)
# Mandatory configuration keys (additional to host and port)
self.user = None
@@ -73,13 +74,13 @@ class Export(GlancesExport):
)
get_all_db = [i['name'] for i in db.get_list_database()]
except InfluxDBClientError as e:
- logger.critical("Cannot connect to InfluxDB database '%s' (%s)" % (self.db, e))
+ logger.critical(f"Cannot connect to InfluxDB database '{self.db}' ({e})")
sys.exit(2)
if self.db in get_all_db:
- logger.info("Stats will be exported to InfluxDB server: {}".format(db._baseurl))
+ logger.info(f"Stats will be exported to InfluxDB server: {db._baseurl}")
else:
- logger.critical("InfluxDB database '%s' did not exist. Please create it" % self.db)
+ logger.critical(f"InfluxDB database '{self.db}' did not exist. Please create it")
sys.exit(2)
return db
@@ -104,9 +105,7 @@ class Export(GlancesExport):
# Manage field
if measurement is not None:
fields = {
- k.replace('{}.'.format(measurement), ''): data_dict[k]
- for k in data_dict
- if k.startswith('{}.'.format(measurement))
+ k.replace(f'{measurement}.', ''): data_dict[k] for k in data_dict if k.startswith(f'{measurement}.')
}
else:
fields = data_dict
@@ -135,6 +134,13 @@ class Export(GlancesExport):
fields.pop(fields['key'])
# Add the hostname as a tag
tags['hostname'] = self.hostname
+ # Add name as a tag (example for the process list)
+ for k in FIELD_TO_TAG:
+ if k in fields:
+ tags[k] = str(fields[k])
+ # Remove it from the field list (can not be a field and a tag)
+ if k in fields:
+ fields.pop(fields[k])
# Add the measurement to the list
ret.append({'measurement': name, 'tags': tags, 'fields': fields})
return ret
@@ -146,12 +152,12 @@ class Export(GlancesExport):
name = self.prefix + '.' + name
# Write input to the InfluxDB database
if len(points) == 0:
- logger.debug("Cannot export empty {} stats to InfluxDB".format(name))
+ logger.debug(f"Cannot export empty {name} stats to InfluxDB")
else:
try:
self.client.write_points(self._normalize(name, columns, points), time_precision="s")
except Exception as e:
# Log level set to debug instead of error (see: issue #1561)
- logger.debug("Cannot export {} stats to InfluxDB ({})".format(name, e))
+ logger.debug(f"Cannot export {name} stats to InfluxDB ({e})")
else:
- logger.debug("Export {} stats to InfluxDB".format(name))
+ logger.debug(f"Export {name} stats to InfluxDB")
diff --git a/glances/exports/glances_influxdb2/__init__.py b/glances/exports/glances_influxdb2/__init__.py
index 1c33da73..625b9987 100644
--- a/glances/exports/glances_influxdb2/__init__.py
+++ b/glances/exports/glances_influxdb2/__init__.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# This file is part of Glances.
#
@@ -12,10 +11,12 @@
import sys
from platform import node
-from glances.logger import logger
+from influxdb_client import InfluxDBClient, WriteOptions
+
from glances.exports.export import GlancesExport
+from glances.logger import logger
-from influxdb_client import InfluxDBClient, WriteOptions
+FIELD_TO_TAG = ['name', 'cmdline', 'type']
class Export(GlancesExport):
@@ -23,7 +24,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None):
"""Init the InfluxDB export IF."""
- super(Export, self).__init__(config=config, args=args)
+ super().__init__(config=config, args=args)
# Mandatory configuration keys (additional to host and port)
self.org = None
@@ -56,7 +57,7 @@ class Export(GlancesExport):
self.interval = 0
# and should be set to the Glances refresh time if the value is 0
self.interval = self.interval if self.interval > 0 else self.args.time