From a0b5982f1dd71ad47c5b91a372a62efc9e82139a Mon Sep 17 00:00:00 2001 From: nicolargo Date: Sat, 4 Sep 2021 16:46:20 +0200 Subject: [PATCH] Refactor exports modules loading --- Makefile | 3 + glances/__init__.py | 4 +- .../__init__.py} | 2 +- .../__init__.py} | 2 +- .../{glances_csv.py => csv/__init__.py} | 2 +- .../__init__.py} | 2 +- .../exports/{glances_export.py => export.py} | 0 .../__init__.py} | 2 +- .../{glances_graph.py => graph/__init__.py} | 2 +- .../__init__.py} | 2 +- .../__init__.py} | 2 +- .../{glances_json.py => json/__init__.py} | 2 +- .../{glances_kafka.py => kafka/__init__.py} | 2 +- .../{glances_mqtt.py => mqtt/__init__.py} | 8 +- .../__init__.py} | 2 +- .../__init__.py} | 2 +- .../__init__.py} | 2 +- .../__init__.py} | 2 +- .../__init__.py} | 2 +- .../{glances_statsd.py => statsd/__init__.py} | 2 +- .../{glances_zeromq.py => zeromq/__init__.py} | 2 +- glances/plugins/cpu/__init__.py | 126 ++++++++++++------ glances/stats.py | 108 +++++---------- unitest-restful.py | 6 + unitest-xmlrpc.py | 6 + unitest.py | 6 + 26 files changed, 163 insertions(+), 138 deletions(-) rename glances/exports/{glances_cassandra.py => cassandra/__init__.py} (98%) rename glances/exports/{glances_couchdb.py => couchdb/__init__.py} (98%) rename glances/exports/{glances_csv.py => csv/__init__.py} (98%) rename glances/exports/{glances_elasticsearch.py => elasticsearch/__init__.py} (98%) rename glances/exports/{glances_export.py => export.py} (100%) rename glances/exports/{glances_influxdb.py => glances_influxdb/__init__.py} (99%) rename glances/exports/{glances_graph.py => graph/__init__.py} (98%) rename glances/exports/{glances_graphite.py => graphite/__init__.py} (98%) rename glances/exports/{glances_influxdb2.py => influxdb2/__init__.py} (99%) rename glances/exports/{glances_json.py => json/__init__.py} (97%) rename glances/exports/{glances_kafka.py => kafka/__init__.py} (98%) rename glances/exports/{glances_mqtt.py => mqtt/__init__.py} (97%) rename glances/exports/{glances_opentsdb.py => opentsdb/__init__.py} (98%) rename glances/exports/{glances_prometheus.py => prometheus/__init__.py} (98%) rename glances/exports/{glances_rabbitmq.py => rabbitmq/__init__.py} (98%) rename glances/exports/{glances_restful.py => restful/__init__.py} (98%) rename glances/exports/{glances_riemann.py => riemann/__init__.py} (97%) rename glances/exports/{glances_statsd.py => statsd/__init__.py} (98%) rename glances/exports/{glances_zeromq.py => zeromq/__init__.py} (98%) diff --git a/Makefile b/Makefile index 2d194a12..c046bb1b 100644 --- a/Makefile +++ b/Makefile @@ -62,6 +62,9 @@ run-client: venv run-browser: venv ./venv/bin/python -m glances -C ./conf/glances.conf --browser +run-export-influxdb: venv + ./venv/bin/python -m glances -C ./conf/glances.conf --export influxdb + show-version: venv ./venv/bin/python -m glances -C ./conf/glances.conf -V diff --git a/glances/__init__.py b/glances/__init__.py index 68083222..bd2e39c5 100644 --- a/glances/__init__.py +++ b/glances/__init__.py @@ -52,8 +52,8 @@ except locale.Error: print("Warning: Unable to set locale. Expect encoding problems.") # Check Python version -if sys.version_info < (2, 7) or (3, 0) <= sys.version_info < (3, 4): - print('Glances requires at least Python 2.7 or 3.4 to run.') +if sys.version_info < (3, 4): + print('Glances requires at least Python 3.4 to run.') sys.exit(1) # Check psutil version diff --git a/glances/exports/glances_cassandra.py b/glances/exports/cassandra/__init__.py similarity index 98% rename from glances/exports/glances_cassandra.py rename to glances/exports/cassandra/__init__.py index 1249dba0..6dcbe09a 100644 --- a/glances/exports/glances_cassandra.py +++ b/glances/exports/cassandra/__init__.py @@ -24,7 +24,7 @@ from datetime import datetime from numbers import Number from glances.logger import logger -from glances.exports.glances_export import GlancesExport +from glances.exports.export import GlancesExport from glances.globals import iteritems from cassandra.auth import PlainTextAuthProvider diff --git a/glances/exports/glances_couchdb.py b/glances/exports/couchdb/__init__.py similarity index 98% rename from glances/exports/glances_couchdb.py rename to glances/exports/couchdb/__init__.py index 03e88318..c9fd72ed 100644 --- a/glances/exports/glances_couchdb.py +++ b/glances/exports/couchdb/__init__.py @@ -23,7 +23,7 @@ import sys from datetime import datetime from glances.logger import logger -from glances.exports.glances_export import GlancesExport +from glances.exports.export import GlancesExport import couchdb import couchdb.mapping diff --git a/glances/exports/glances_csv.py b/glances/exports/csv/__init__.py similarity index 98% rename from glances/exports/glances_csv.py rename to glances/exports/csv/__init__.py index 6814adaa..c7c7ff7b 100644 --- a/glances/exports/glances_csv.py +++ b/glances/exports/csv/__init__.py @@ -26,7 +26,7 @@ import time from glances.globals import PY3, iterkeys, itervalues from glances.logger import logger -from glances.exports.glances_export import GlancesExport +from glances.exports.export import GlancesExport class Export(GlancesExport): diff --git a/glances/exports/glances_elasticsearch.py b/glances/exports/elasticsearch/__init__.py similarity index 98% rename from glances/exports/glances_elasticsearch.py rename to glances/exports/elasticsearch/__init__.py index 62cce9fb..31dcb852 100644 --- a/glances/exports/glances_elasticsearch.py +++ b/glances/exports/elasticsearch/__init__.py @@ -23,7 +23,7 @@ import sys from datetime import datetime from glances.logger import logger -from glances.exports.glances_export import GlancesExport +from glances.exports.export import GlancesExport from elasticsearch import Elasticsearch, helpers from elasticsearch import __version__ as elk_version diff --git a/glances/exports/glances_export.py b/glances/exports/export.py similarity index 100% rename from glances/exports/glances_export.py rename to glances/exports/export.py diff --git a/glances/exports/glances_influxdb.py b/glances/exports/glances_influxdb/__init__.py similarity index 99% rename from glances/exports/glances_influxdb.py rename to glances/exports/glances_influxdb/__init__.py index 705c4e9e..71f19287 100644 --- a/glances/exports/glances_influxdb.py +++ b/glances/exports/glances_influxdb/__init__.py @@ -23,7 +23,7 @@ import sys from platform import node from glances.logger import logger -from glances.exports.glances_export import GlancesExport +from glances.exports.export import GlancesExport from influxdb import InfluxDBClient from influxdb.client import InfluxDBClientError diff --git a/glances/exports/glances_graph.py b/glances/exports/graph/__init__.py similarity index 98% rename from glances/exports/glances_graph.py rename to glances/exports/graph/__init__.py index 0ac79db8..1e071061 100644 --- a/glances/exports/glances_graph.py +++ b/glances/exports/graph/__init__.py @@ -29,7 +29,7 @@ import errno from glances.logger import logger from glances.timer import Timer from glances.globals import iteritems, time_serie_subsample -from glances.exports.glances_export import GlancesExport +from glances.exports.export import GlancesExport class Export(GlancesExport): diff --git a/glances/exports/glances_graphite.py b/glances/exports/graphite/__init__.py similarity index 98% rename from glances/exports/glances_graphite.py rename to glances/exports/graphite/__init__.py index 2b577e3a..1968f08d 100644 --- a/glances/exports/glances_graphite.py +++ b/glances/exports/graphite/__init__.py @@ -23,7 +23,7 @@ import sys from numbers import Number from glances.logger import logger -from glances.exports.glances_export import GlancesExport +from glances.exports.export import GlancesExport from graphitesend import GraphiteClient diff --git a/glances/exports/glances_influxdb2.py b/glances/exports/influxdb2/__init__.py similarity index 99% rename from glances/exports/glances_influxdb2.py rename to glances/exports/influxdb2/__init__.py index 87a6c3bc..f72bd927 100644 --- a/glances/exports/glances_influxdb2.py +++ b/glances/exports/influxdb2/__init__.py @@ -23,7 +23,7 @@ import sys from platform import node from glances.logger import logger -from glances.exports.glances_export import GlancesExport +from glances.exports.export import GlancesExport from influxdb_client import InfluxDBClient, WriteOptions diff --git a/glances/exports/glances_json.py b/glances/exports/json/__init__.py similarity index 97% rename from glances/exports/glances_json.py rename to glances/exports/json/__init__.py index acc5ea5f..3d1d4dbc 100644 --- a/glances/exports/glances_json.py +++ b/glances/exports/json/__init__.py @@ -5,7 +5,7 @@ import json from glances.globals import PY3, listkeys from glances.logger import logger -from glances.exports.glances_export import GlancesExport +from glances.exports.export import GlancesExport class Export(GlancesExport): diff --git a/glances/exports/glances_kafka.py b/glances/exports/kafka/__init__.py similarity index 98% rename from glances/exports/glances_kafka.py rename to glances/exports/kafka/__init__.py index 2e2e3a20..814a0594 100644 --- a/glances/exports/glances_kafka.py +++ b/glances/exports/kafka/__init__.py @@ -23,7 +23,7 @@ import sys from glances.logger import logger from glances.globals import iteritems -from glances.exports.glances_export import GlancesExport +from glances.exports.export import GlancesExport from kafka import KafkaProducer import json diff --git a/glances/exports/glances_mqtt.py b/glances/exports/mqtt/__init__.py similarity index 97% rename from glances/exports/glances_mqtt.py rename to glances/exports/mqtt/__init__.py index c4dc98ef..63ec1525 100644 --- a/glances/exports/glances_mqtt.py +++ b/glances/exports/mqtt/__init__.py @@ -24,7 +24,7 @@ import string import json from glances.logger import logger -from glances.exports.glances_export import GlancesExport +from glances.exports.export import GlancesExport # Import paho for MQTT from requests import certs @@ -118,14 +118,14 @@ class Export(GlancesExport): 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] @@ -133,4 +133,4 @@ class Export(GlancesExport): self.client.publish(topic, json_value) except Exception as e: logger.error("Can not export stats to MQTT server (%s)" % e) - + diff --git a/glances/exports/glances_opentsdb.py b/glances/exports/opentsdb/__init__.py similarity index 98% rename from glances/exports/glances_opentsdb.py rename to glances/exports/opentsdb/__init__.py index f73c6312..ec203194 100644 --- a/glances/exports/glances_opentsdb.py +++ b/glances/exports/opentsdb/__init__.py @@ -23,7 +23,7 @@ import sys from numbers import Number from glances.logger import logger -from glances.exports.glances_export import GlancesExport +from glances.exports.export import GlancesExport import potsdb diff --git a/glances/exports/glances_prometheus.py b/glances/exports/prometheus/__init__.py similarity index 98% rename from glances/exports/glances_prometheus.py rename to glances/exports/prometheus/__init__.py index cef67bf4..af869558 100644 --- a/glances/exports/glances_prometheus.py +++ b/glances/exports/prometheus/__init__.py @@ -23,7 +23,7 @@ import sys from numbers import Number from glances.logger import logger -from glances.exports.glances_export import GlancesExport +from glances.exports.export import GlancesExport from glances.globals import iteritems, listkeys from prometheus_client import start_http_server, Gauge diff --git a/glances/exports/glances_rabbitmq.py b/glances/exports/rabbitmq/__init__.py similarity index 98% rename from glances/exports/glances_rabbitmq.py rename to glances/exports/rabbitmq/__init__.py index 538fc42c..f47366fc 100644 --- a/glances/exports/glances_rabbitmq.py +++ b/glances/exports/rabbitmq/__init__.py @@ -25,7 +25,7 @@ import sys from numbers import Number from glances.logger import logger -from glances.exports.glances_export import GlancesExport +from glances.exports.export import GlancesExport # Import pika for RabbitMQ import pika diff --git a/glances/exports/glances_restful.py b/glances/exports/restful/__init__.py similarity index 98% rename from glances/exports/glances_restful.py rename to glances/exports/restful/__init__.py index c18ee6b1..bc4970bf 100644 --- a/glances/exports/glances_restful.py +++ b/glances/exports/restful/__init__.py @@ -23,7 +23,7 @@ import sys from glances.globals import listkeys from glances.logger import logger -from glances.exports.glances_export import GlancesExport +from glances.exports.export import GlancesExport from requests import post diff --git a/glances/exports/glances_riemann.py b/glances/exports/riemann/__init__.py similarity index 97% rename from glances/exports/glances_riemann.py rename to glances/exports/riemann/__init__.py index 8062ab12..eff9a230 100644 --- a/glances/exports/glances_riemann.py +++ b/glances/exports/riemann/__init__.py @@ -24,7 +24,7 @@ import sys from numbers import Number from glances.logger import logger -from glances.exports.glances_export import GlancesExport +from glances.exports.export import GlancesExport # Import bernhard for Riemann import bernhard diff --git a/glances/exports/glances_statsd.py b/glances/exports/statsd/__init__.py similarity index 98% rename from glances/exports/glances_statsd.py rename to glances/exports/statsd/__init__.py index 8ebe168f..5956cce9 100644 --- a/glances/exports/glances_statsd.py +++ b/glances/exports/statsd/__init__.py @@ -23,7 +23,7 @@ import sys from numbers import Number from glances.logger import logger -from glances.exports.glances_export import GlancesExport +from glances.exports.export import GlancesExport from statsd import StatsClient diff --git a/glances/exports/glances_zeromq.py b/glances/exports/zeromq/__init__.py similarity index 98% rename from glances/exports/glances_zeromq.py rename to glances/exports/zeromq/__init__.py index 57e30af0..739d6d77 100644 --- a/glances/exports/glances_zeromq.py +++ b/glances/exports/zeromq/__init__.py @@ -24,7 +24,7 @@ import json from glances.globals import b from glances.logger import logger -from glances.exports.glances_export import GlancesExport +from glances.exports.export import GlancesExport import zmq from zmq.utils.strtypes import asbytes diff --git a/glances/plugins/cpu/__init__.py b/glances/plugins/cpu/__init__.py index 0bdc05bf..8410150c 100644 --- a/glances/plugins/cpu/__init__.py +++ b/glances/plugins/cpu/__init__.py @@ -29,11 +29,6 @@ from glances.plugins.plugin import GlancesPlugin import psutil # Fields description -# description: human readable description -# short_name: shortname to use un UI -# unit: unit type -# rate: is it a rate ? If yes, // by time_since_update when displayed, -# min_symbol: Auto unit should be used if value > than 1 'X' (K, M, G)... fields_description = { 'total': {'description': 'Sum of all CPU percentages (except idle).', 'unit': 'percent'}, @@ -65,21 +60,12 @@ CPU while the hypervisor is servicing another virtual processor.', second. A context switch is a procedure that a computer\'s CPU (central \ processing unit) follows to change from one task (or process) to \ another while ensuring that the tasks do not conflict.', - 'unit': 'number', - 'rate': True, - 'min_symbol': 'K', - 'short_name': 'ctx_sw'}, + 'unit': 'percent'}, 'interrupts': {'description': 'number of interrupts per second.', - 'unit': 'number', - 'rate': True, - 'min_symbol': 'K', - 'short_name': 'inter'}, + 'unit': 'percent'}, 'soft_interrupts': {'description': 'number of software interrupts per second. Always set to \ 0 on Windows and SunOS.', - 'unit': 'number', - 'rate': True, - 'min_symbol': 'K', - 'short_name': 'sw_int'}, + 'unit': 'percent'}, 'cpucore': {'description': 'Total number of CPU core.', 'unit': 'number'}, 'time_since_update': {'description': 'Number of seconds since last update.', @@ -281,12 +267,12 @@ class Plugin(GlancesPlugin): if not self.stats or self.args.percpu or self.is_disable(): return ret + # Build the string message # If user stat is not here, display only idle / total CPU usage (for # exemple on Windows OS) idle_tag = 'user' not in self.stats - # First line - # Total + (idle) + ctx_sw + # Header msg = '{}'.format('CPU') ret.append(self.curse_add_line(msg, "TITLE")) trend_user = self.get_trend('user') @@ -302,47 +288,103 @@ class Plugin(GlancesPlugin): ret.append(self.curse_add_line( msg, self.get_views(key='total', option='decoration'))) # Idle CPU - if not idle_tag: - ret.extend(self.curse_add_stat('idle', width=15, header=' ')) + if 'idle' in self.stats and not idle_tag: + msg = ' {:8}'.format('idle:') + ret.append(self.curse_add_line(msg)) + msg = '{:5.1f}%'.format(self.stats['idle']) + ret.append(self.curse_add_line(msg)) # ctx_switches - ret.extend(self.curse_add_stat('ctx_switches', width=15, header=' ')) + if 'ctx_switches' in self.stats: + msg = ' {:8}'.format('ctx_sw:') + ret.append(self.curse_add_line(msg, optional=self.get_views(key='ctx_switches', option='optional'))) + msg = '{:>5}'.format(self.auto_unit(int(self.stats['ctx_switches'] // self.stats['time_since_update']), + min_symbol='K')) + ret.append(self.curse_add_line( + msg, self.get_views(key='ctx_switches', option='decoration'), + optional=self.get_views(key='ctx_switches', option='optional'))) - # Second line - # user|idle + irq + interrupts + # New line ret.append(self.curse_new_line()) # User CPU - if not idle_tag: - ret.extend(self.curse_add_stat('user', width=15)) + if 'user' in self.stats: + msg = '{:8}'.format('user:') + ret.append(self.curse_add_line(msg)) + msg = '{:5.1f}%'.format(self.stats['user']) + ret.append(self.curse_add_line( + msg, self.get_views(key='user', option='decoration'))) elif 'idle' in self.stats: - ret.extend(self.curse_add_stat('idle', width=15)) + msg = '{:8}'.format('idle:') + ret.append(self.curse_add_line(msg)) + msg = '{:5.1f}%'.format(self.stats['idle']) + ret.append(self.curse_add_line(msg)) # IRQ CPU - ret.extend(self.curse_add_stat('irq', width=15, header=' ')) + if 'irq' in self.stats: + msg = ' {:8}'.format('irq:') + ret.append(self.curse_add_line(msg, optional=self.get_views(key='irq', option='optional'))) + msg = '{:5.1f}%'.format(self.stats['irq']) + ret.append(self.curse_add_line(msg, optional=self.get_views(key='irq', option='optional'))) # interrupts - ret.extend(self.curse_add_stat('interrupts', width=15, header=' ')) + if 'interrupts' in self.stats: + msg = ' {:8}'.format('inter:') + ret.append(self.curse_add_line(msg, optional=self.get_views(key='interrupts', option='optional'))) + msg = '{:>5}'.format(int(self.stats['interrupts'] // self.stats['time_since_update'])) + ret.append(self.curse_add_line(msg, optional=self.get_views(key='interrupts', option='optional'))) - # Third line - # system|core + nice + sw_int + # New line ret.append(self.curse_new_line()) # System CPU - if not idle_tag: - ret.extend(self.curse_add_stat('system', width=15)) + if 'system' in self.stats and not idle_tag: + msg = '{:8}'.format('system:') + ret.append(self.curse_add_line(msg)) + msg = '{:5.1f}%'.format(self.stats['system']) + ret.append(self.curse_add_line( + msg, self.get_views(key='system', option='decoration'))) else: - ret.extend(self.curse_add_stat('core', width=15)) + msg = '{:8}'.format('core:') + ret.append(self.curse_add_line(msg)) + msg = '{:>6}'.format(self.stats['nb_log_core']) + ret.append(self.curse_add_line(msg)) # Nice CPU - ret.extend(self.curse_add_stat('nice', width=15, header=' ')) + if 'nice' in self.stats: + msg = ' {:8}'.format('nice:') + ret.append(self.curse_add_line( + msg, optional=self.get_views(key='nice', option='optional'))) + msg = '{:5.1f}%'.format(self.stats['nice']) + ret.append(self.curse_add_line( + msg, optional=self.get_views(key='nice', option='optional'))) # soft_interrupts - ret.extend(self.curse_add_stat('soft_interrupts', width=15, header=' ')) + if 'soft_interrupts' in self.stats: + msg = ' {:8}'.format('sw_int:') + ret.append(self.curse_add_line(msg, optional=self.get_views(key='soft_interrupts', option='optional'))) + msg = '{:>5}'.format(int(self.stats['soft_interrupts'] // self.stats['time_since_update'])) + ret.append(self.curse_add_line(msg, optional=self.get_views(key='soft_interrupts', option='optional'))) - # Fourth line - # iowat + steal + syscalls + # New line ret.append(self.curse_new_line()) # IOWait CPU - ret.extend(self.curse_add_stat('iowait', width=15)) + if 'iowait' in self.stats: + msg = '{:8}'.format('iowait:') + ret.append(self.curse_add_line( + msg, optional=self.get_views(key='iowait', option='optional'))) + msg = '{:5.1f}%'.format(self.stats['iowait']) + ret.append(self.curse_add_line( + msg, self.get_views(key='iowait', option='decoration'), + optional=self.get_views(key='iowait', option='optional'))) # Steal CPU usage - ret.extend(self.curse_add_stat('steal', width=15, header=' ')) + if 'steal' in self.stats: + msg = ' {:8}'.format('steal:') + ret.append(self.curse_add_line(msg, optional=self.get_views(key='steal', option='optional'))) + msg = '{:5.1f}%'.format(self.stats['steal']) + ret.append(self.curse_add_line( + msg, self.get_views(key='steal', option='decoration'), + optional=self.get_views(key='steal', option='optional'))) + # syscalls # syscalls: number of system calls since boot. Always set to 0 on Linux. (do not display) - if not LINUX: - ret.extend(self.curse_add_stat('syscalls', width=15, header=' ')) + if 'syscalls' in self.stats and not LINUX: + msg = ' {:8}'.format('syscal:') + ret.append(self.curse_add_line(msg, optional=self.get_views(key='syscalls', option='optional'))) + msg = '{:>5}'.format(int(self.stats['syscalls'] // self.stats['time_since_update'])) + ret.append(self.curse_add_line(msg, optional=self.get_views(key='syscalls', option='optional'))) # Return the message with decoration return ret diff --git a/glances/stats.py b/glances/stats.py index c2e9de0b..085ad0ca 100644 --- a/glances/stats.py +++ b/glances/stats.py @@ -103,39 +103,7 @@ class GlancesStats(object): # Restoring system path sys.path = sys_path - # TODO: To be removed and replace by the _load_plugin_v4 - def _load_plugin(self, plugin_script, args=None, config=None): - """Load the plugin (script), init it and add to the _plugin dict.""" - # The key is the plugin name - # for example, the file glances_xxx.py - # generate self._plugins_list["xxx"] = ... - name = plugin_script[len(self.header):-3].lower() - - # Loaf the plugin class - try: - # Import the plugin - plugin = import_module(plugin_script[:-3]) - # Init and add the plugin to the dictionary - self._plugins[name] = plugin.Plugin(args=args, config=config) - except Exception as e: - # If a plugin can not be loaded, display a critical message - # on the console but do not crash - logger.critical("Error while initializing the {} plugin ({})".format(name, e)) - logger.error(traceback.format_exc()) - # Disable the plugin - if args is not None: - setattr(args, - 'disable_' + name, - False) - else: - # Set the disable_ to False by default - if args is not None: - setattr(args, - 'disable_' + name, - getattr(args, 'disable_' + name, False)) - - # TODO: To be rename to _load_plugin - def _load_plugin_v4(self, plugin_path, args=None, config=None): + def _load_plugin(self, plugin_path, args=None, config=None): """Load the plugin, init it and add to the _plugin dict.""" # The key is the plugin name = plugin_path # for example, the path ./glances/plugins/xxx @@ -173,24 +141,14 @@ class GlancesStats(object): def load_plugins(self, args=None): """Load all plugins in the 'plugins' folder.""" start_duration = Counter() + for item in os.listdir(plugins_path): - if (item.startswith(self.header) and - item.endswith(".py") and - item != (self.header + "plugin.py")): + if os.path.isdir(os.path.join(plugins_path, item)) and \ + not item.startswith('__'): # Load the plugin start_duration.reset() self._load_plugin(os.path.basename(item), args=args, config=self.config) - logger.debug("Plugin {} started in {} seconds".format(item, - start_duration.get())) - for item in os.listdir(plugins_path): - if os.path.isdir(os.path.join(plugins_path, item)) and \ - not item.startswith('__') and \ - item != "plugin": - # Load the plugin - start_duration.reset() - self._load_plugin_v4(os.path.basename(item), - args=args, config=self.config) logger.debug("Plugin {} started in {} seconds".format(item, start_duration.get())) @@ -198,36 +156,40 @@ class GlancesStats(object): logger.debug("Active plugins list: {}".format(self.getPluginsList())) def load_exports(self, args=None): - """Load all export modules in the 'exports' folder.""" - if args is None: - return False - header = "glances_" - # Build the export module available list - args_var = vars(locals()['args']) + """Load all exporters in the 'exports' folder.""" + start_duration = Counter() + + if args is None: return False + for item in os.listdir(exports_path): - export_name = os.path.basename(item)[len(header):-3].lower() - if (item.startswith(header) and - item.endswith(".py") and - item != (header + "export.py") and - item != (header + "history.py")): - self._exports_all[export_name] = os.path.basename(item)[:-3] + if os.path.isdir(os.path.join(exports_path, item)) and \ + not item.startswith('__'): + # Load the exporter + start_duration.reset() + if item.startswith('glances_'): + # Avoid circular loop when Glances exporter uses lib with same name + # Example: influxdb should be named to glances_influxdb + exporter_name = os.path.basename(item).split('glances_')[1] + else: + exporter_name = os.path.basename(item) # Set the disable_ to False by default setattr(self.args, - 'export_' + export_name, - getattr(self.args, 'export_' + export_name, False)) - - # Aim is to check if the export module should be loaded - for export_name in self._exports_all: - if getattr(self.args, 'export_' + export_name, False): - # Import the export module - export_module = __import__(self._exports_all[export_name]) - # Add the export to the dictionary - # The key is the module name - # for example, the file glances_xxx.py - # generate self._exports_list["xxx"] = ... - self._exports[export_name] = export_module.Export(args=args, - config=self.config) - self._exports_all[export_name] = self._exports[export_name] + 'export_' + exporter_name, + getattr(self.args, 'export_' + exporter_name, False)) + # We should import the module + if getattr(self.args, 'export_' + exporter_name, False): + # Import the export module + export_module = import_module(item) + # Add the exporter instance to the active exporters dictionary + self._exports[exporter_name] = export_module.Export(args=args, + config=self.config) + # Add the exporter instance to the available exporters dictionary + self._exports_all[exporter_name] = self._exports[exporter_name] + else: + # Add the exporter name to the available exporters dictionary + self._exports_all[exporter_name] = exporter_name + logger.debug("Exporter {} started in {} seconds".format(exporter_name, + start_duration.get())) # Log plugins list logger.debug("Active exports modules list: {}".format(self.getExportsList())) diff --git a/unitest-restful.py b/unitest-restful.py index b6e5332a..4cd9a193 100755 --- a/unitest-restful.py +++ b/unitest-restful.py @@ -26,6 +26,12 @@ import subprocess import time import numbers import unittest +import sys + +# Check Python version +if sys.version_info < (3, 4): + print('Glances requires at least Python 3.4 to run.') + sys.exit(1) from glances import __version__ from glances.globals import text_type diff --git a/unitest-xmlrpc.py b/unitest-xmlrpc.py index 581bc38a..60129cde 100755 --- a/unitest-xmlrpc.py +++ b/unitest-xmlrpc.py @@ -26,6 +26,12 @@ import shlex import subprocess import time import unittest +import sys + +# Check Python version +if sys.version_info < (3, 4): + print('Glances requires at least Python 3.4 to run.') + sys.exit(1) from glances import __version__ from glances.globals import ServerProxy diff --git a/unitest.py b/unitest.py index f39525e8..14bcb185 100755 --- a/unitest.py +++ b/unitest.py @@ -22,6 +22,12 @@ import time import unittest +import sys + +# Check Python version +if sys.version_info < (3, 4): + print('Glances requires at least Python 3.4 to run.') + sys.exit(1) from glances.main import GlancesMain from glances.stats import GlancesStats