From 35414e9a3c819954943832ccd50dc0b6530fab26 Mon Sep 17 00:00:00 2001 From: Nicolargo Date: Thu, 1 Jan 2015 22:34:55 +0100 Subject: [PATCH 1/7] Add GlancesActions class. Actions are run every refresh time... It sucks... --- conf/glances-test.conf | 1 + glances/__init__.py | 2 +- glances/__main__.py | 2 +- glances/core/glances_actions.py | 40 ++++++++ glances/core/glances_autodiscover.py | 2 +- glances/core/glances_client.py | 2 +- glances/core/glances_client_browser.py | 2 +- glances/core/glances_config.py | 2 +- glances/core/glances_globals.py | 2 +- glances/core/glances_logging.py | 2 +- glances/core/glances_logs.py | 2 +- glances/core/glances_main.py | 2 +- glances/core/glances_monitor_list.py | 2 +- glances/core/glances_password.py | 2 +- glances/core/glances_processes.py | 2 +- glances/core/glances_server.py | 2 +- glances/core/glances_snmp.py | 2 +- glances/core/glances_standalone.py | 2 +- glances/core/glances_staticlist.py | 2 +- glances/core/glances_stats.py | 2 +- glances/core/glances_timer.py | 2 +- glances/core/glances_webserver.py | 2 +- glances/exports/glances_csv.py | 2 +- glances/exports/glances_export.py | 2 +- glances/exports/glances_history.py | 2 +- glances/exports/glances_influxdb.py | 2 +- glances/exports/glances_statsd.py | 125 +++++++++++++++++++++++ glances/outputs/glances_bottle.py | 2 +- glances/outputs/glances_colorconsole.py | 2 +- glances/outputs/glances_curses.py | 2 +- glances/plugins/glances_alert.py | 2 +- glances/plugins/glances_batpercent.py | 2 +- glances/plugins/glances_core.py | 2 +- glances/plugins/glances_cpu.py | 2 +- glances/plugins/glances_diskio.py | 2 +- glances/plugins/glances_fs.py | 2 +- glances/plugins/glances_hddtemp.py | 2 +- glances/plugins/glances_help.py | 2 +- glances/plugins/glances_load.py | 2 +- glances/plugins/glances_mem.py | 2 +- glances/plugins/glances_memswap.py | 2 +- glances/plugins/glances_monitor.py | 2 +- glances/plugins/glances_network.py | 2 +- glances/plugins/glances_now.py | 2 +- glances/plugins/glances_percpu.py | 2 +- glances/plugins/glances_plugin.py | 73 +++++++++---- glances/plugins/glances_processcount.py | 2 +- glances/plugins/glances_processlist.py | 2 +- glances/plugins/glances_psutilversion.py | 2 +- glances/plugins/glances_raid.py | 2 +- glances/plugins/glances_sensors.py | 2 +- glances/plugins/glances_system.py | 2 +- glances/plugins/glances_uptime.py | 2 +- 53 files changed, 268 insertions(+), 69 deletions(-) create mode 100644 glances/core/glances_actions.py create mode 100644 glances/exports/glances_statsd.py diff --git a/conf/glances-test.conf b/conf/glances-test.conf index 0e141fe2..d4f9dbdc 100644 --- a/conf/glances-test.conf +++ b/conf/glances-test.conf @@ -3,6 +3,7 @@ user_careful=50 user_warning=70 user_critical=90 +user_critical_action=touch /tmp/glances.alert iowait_careful=50 iowait_warning=70 iowait_critical=90 diff --git a/glances/__init__.py b/glances/__init__.py index c5c0200f..7b14b3f3 100644 --- a/glances/__init__.py +++ b/glances/__init__.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/__main__.py b/glances/__main__.py index 9aeb86f2..871dea89 100644 --- a/glances/__main__.py +++ b/glances/__main__.py @@ -3,7 +3,7 @@ # # Glances - An eye on your system # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/core/glances_actions.py b/glances/core/glances_actions.py new file mode 100644 index 00000000..9ee947b2 --- /dev/null +++ b/glances/core/glances_actions.py @@ -0,0 +1,40 @@ +# -*- 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 . + +"""Manage on alert actions.""" + +# Import system lib +from subprocess import Popen + +# Import Glances lib +from glances.core.glances_logging import logger + + +class GlancesActions(object): + + """This class manage action if an alert is reached""" + + def run(self, commands): + """Run the commands (in background) + - commands: a list of command line""" + + for cmd in commands: + logger.info("Action triggered: {0}".format(cmd)) + splitted_cmd = cmd.split() + Popen(splitted_cmd) diff --git a/glances/core/glances_autodiscover.py b/glances/core/glances_autodiscover.py index 62d627b1..f9659f08 100644 --- a/glances/core/glances_autodiscover.py +++ b/glances/core/glances_autodiscover.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/core/glances_client.py b/glances/core/glances_client.py index a903cf4d..755b88c0 100644 --- a/glances/core/glances_client.py +++ b/glances/core/glances_client.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/core/glances_client_browser.py b/glances/core/glances_client_browser.py index e54c0849..a198399b 100644 --- a/glances/core/glances_client_browser.py +++ b/glances/core/glances_client_browser.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/core/glances_config.py b/glances/core/glances_config.py index 2b690836..935f08e3 100644 --- a/glances/core/glances_config.py +++ b/glances/core/glances_config.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/core/glances_globals.py b/glances/core/glances_globals.py index e2f8878e..3cf9fa51 100644 --- a/glances/core/glances_globals.py +++ b/glances/core/glances_globals.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/core/glances_logging.py b/glances/core/glances_logging.py index f1e0e5d4..74518f3e 100644 --- a/glances/core/glances_logging.py +++ b/glances/core/glances_logging.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/core/glances_logs.py b/glances/core/glances_logs.py index 577e4601..7d6a10b6 100644 --- a/glances/core/glances_logs.py +++ b/glances/core/glances_logs.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/core/glances_main.py b/glances/core/glances_main.py index 86dac256..7a5b016f 100644 --- a/glances/core/glances_main.py +++ b/glances/core/glances_main.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/core/glances_monitor_list.py b/glances/core/glances_monitor_list.py index 5bc20e12..98b0604f 100644 --- a/glances/core/glances_monitor_list.py +++ b/glances/core/glances_monitor_list.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/core/glances_password.py b/glances/core/glances_password.py index 87e6d137..3ec9179c 100644 --- a/glances/core/glances_password.py +++ b/glances/core/glances_password.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/core/glances_processes.py b/glances/core/glances_processes.py index 62637914..6584a3d0 100644 --- a/glances/core/glances_processes.py +++ b/glances/core/glances_processes.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/core/glances_server.py b/glances/core/glances_server.py index f4ecd07c..91d627bb 100644 --- a/glances/core/glances_server.py +++ b/glances/core/glances_server.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/core/glances_snmp.py b/glances/core/glances_snmp.py index 67cfd3ef..95e1e602 100644 --- a/glances/core/glances_snmp.py +++ b/glances/core/glances_snmp.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/core/glances_standalone.py b/glances/core/glances_standalone.py index 12a3daf2..50170a97 100644 --- a/glances/core/glances_standalone.py +++ b/glances/core/glances_standalone.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/core/glances_staticlist.py b/glances/core/glances_staticlist.py index 56db4d22..1ff942a7 100644 --- a/glances/core/glances_staticlist.py +++ b/glances/core/glances_staticlist.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/core/glances_stats.py b/glances/core/glances_stats.py index 64da8919..b9e98288 100644 --- a/glances/core/glances_stats.py +++ b/glances/core/glances_stats.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/core/glances_timer.py b/glances/core/glances_timer.py index 8b21d8d4..71fd4667 100644 --- a/glances/core/glances_timer.py +++ b/glances/core/glances_timer.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/core/glances_webserver.py b/glances/core/glances_webserver.py index f83793a6..39c477cc 100644 --- a/glances/core/glances_webserver.py +++ b/glances/core/glances_webserver.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/exports/glances_csv.py b/glances/exports/glances_csv.py index d3cb452d..a71e492b 100644 --- a/glances/exports/glances_csv.py +++ b/glances/exports/glances_csv.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/exports/glances_export.py b/glances/exports/glances_export.py index 5e52f237..a4d219f1 100644 --- a/glances/exports/glances_export.py +++ b/glances/exports/glances_export.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/exports/glances_history.py b/glances/exports/glances_history.py index 36217897..674bdb5c 100644 --- a/glances/exports/glances_history.py +++ b/glances/exports/glances_history.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/exports/glances_influxdb.py b/glances/exports/glances_influxdb.py index 057fa456..801fb962 100644 --- a/glances/exports/glances_influxdb.py +++ b/glances/exports/glances_influxdb.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/exports/glances_statsd.py b/glances/exports/glances_statsd.py new file mode 100644 index 00000000..63a9e1fc --- /dev/null +++ b/glances/exports/glances_statsd.py @@ -0,0 +1,125 @@ +# -*- 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 . + +"""Statsd interface class.""" + +# Import sys libs +from statsd import StatsClient +from numbers import Number +import sys + +# Import Glances lib +from glances.core.glances_logging import logger +from ConfigParser import NoSectionError, NoOptionError +from glances.exports.glances_export import GlancesExport + + +class Export(GlancesExport): + + """This class manages the Statsd export module.""" + + def __init__(self, config=None, args=None): + """Init the Statsd export IF.""" + GlancesExport.__init__(self, config=config, args=args) + + # Load the InfluxDB configuration file + self.host = None + self.port = None + self.prefix = None + self.export_enable = self.load_conf() + if not self.export_enable: + sys.exit(2) + + # Default prefix for stats is 'glances' + if self.prefix is None: + self.prefix = 'glances' + + # Init the Statsd client + self.client = StatsClient(self.host, + int(self.port), + prefix=self.prefix) + + def load_conf(self, section="statsd"): + """Load the Statsd configuration in the Glances configuration file""" + if self.config is None: + return False + try: + self.host = self.config.get_raw_option(section, "host") + self.port = self.config.get_raw_option(section, "port") + except NoSectionError: + logger.critical("No Statsd configuration found") + return False + except NoOptionError as e: + logger.critical("Error in the Statsd configuration (%s)" % e) + return False + else: + logger.debug("Load Statsd from the Glances configuration file") + # Prefix is optional + try: + self.prefix = self.config.get_raw_option(section, "prefix") + except NoOptionError as e: + pass + return True + + def init(self, prefix='glances'): + """Init the connection to the Statsd server""" + if not self.export_enable: + return None + return StatsClient(self.host, + self.port, + prefix=prefix) + + def update(self, stats): + """Update stats to the InfluxDB server.""" + if not self.export_enable: + return False + + # Get the stats + all_stats = stats.getAll() + plugins = stats.getAllPlugins() + + # Loop over available plugin + i = 0 + for plugin in plugins: + if plugin in self.plugins_to_export(): + if type(all_stats[i]) is list: + for item in all_stats[i]: + export_names = map( + lambda x: item[item['key']] + '.' + x, item.keys()) + export_values = item.values() + self.__export(plugin, export_names, export_values) + elif type(all_stats[i]) is dict: + export_names = all_stats[i].keys() + export_values = all_stats[i].values() + self.__export(plugin, export_names, export_values) + i += 1 + + return True + + def __export(self, name, columns, points): + """Export the stats to the Statsd server""" + for i in range(0, len(columns)): + if not isinstance(points[i], Number): + continue + stat_name = '{0}.{1}'.format(name, columns[i]) + stat_value = points[i] + try: + self.client.gauge(stat_name, stat_value) + except Exception as e: + logger.critical("Can not export stats to Statsd (%s)" % e) diff --git a/glances/outputs/glances_bottle.py b/glances/outputs/glances_bottle.py index 27b56343..25237225 100644 --- a/glances/outputs/glances_bottle.py +++ b/glances/outputs/glances_bottle.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/outputs/glances_colorconsole.py b/glances/outputs/glances_colorconsole.py index 8407114c..49c55037 100644 --- a/glances/outputs/glances_colorconsole.py +++ b/glances/outputs/glances_colorconsole.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/outputs/glances_curses.py b/glances/outputs/glances_curses.py index abf26a53..5cedb395 100644 --- a/glances/outputs/glances_curses.py +++ b/glances/outputs/glances_curses.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_alert.py b/glances/plugins/glances_alert.py index 49714cde..78c6c45a 100644 --- a/glances/plugins/glances_alert.py +++ b/glances/plugins/glances_alert.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_batpercent.py b/glances/plugins/glances_batpercent.py index f5d67fda..ff1deecc 100644 --- a/glances/plugins/glances_batpercent.py +++ b/glances/plugins/glances_batpercent.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_core.py b/glances/plugins/glances_core.py index ffd4ef2f..20127c8b 100644 --- a/glances/plugins/glances_core.py +++ b/glances/plugins/glances_core.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_cpu.py b/glances/plugins/glances_cpu.py index 436c18e7..685f5454 100644 --- a/glances/plugins/glances_cpu.py +++ b/glances/plugins/glances_cpu.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_diskio.py b/glances/plugins/glances_diskio.py index 373c878c..0cf68bec 100644 --- a/glances/plugins/glances_diskio.py +++ b/glances/plugins/glances_diskio.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_fs.py b/glances/plugins/glances_fs.py index 4f74e45b..20dc85c1 100644 --- a/glances/plugins/glances_fs.py +++ b/glances/plugins/glances_fs.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_hddtemp.py b/glances/plugins/glances_hddtemp.py index 1492a251..82f29f1b 100644 --- a/glances/plugins/glances_hddtemp.py +++ b/glances/plugins/glances_hddtemp.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_help.py b/glances/plugins/glances_help.py index 2644e171..02504b1d 100644 --- a/glances/plugins/glances_help.py +++ b/glances/plugins/glances_help.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_load.py b/glances/plugins/glances_load.py index c689173d..aa2f0dde 100644 --- a/glances/plugins/glances_load.py +++ b/glances/plugins/glances_load.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_mem.py b/glances/plugins/glances_mem.py index 2c2eca43..52bee12a 100644 --- a/glances/plugins/glances_mem.py +++ b/glances/plugins/glances_mem.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_memswap.py b/glances/plugins/glances_memswap.py index 2fcaa8c9..20751add 100644 --- a/glances/plugins/glances_memswap.py +++ b/glances/plugins/glances_memswap.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_monitor.py b/glances/plugins/glances_monitor.py index 16d548ae..66765ea1 100644 --- a/glances/plugins/glances_monitor.py +++ b/glances/plugins/glances_monitor.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_network.py b/glances/plugins/glances_network.py index 0b6ef070..9ef8bc89 100644 --- a/glances/plugins/glances_network.py +++ b/glances/plugins/glances_network.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_now.py b/glances/plugins/glances_now.py index 199085ec..b40fa44f 100644 --- a/glances/plugins/glances_now.py +++ b/glances/plugins/glances_now.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_percpu.py b/glances/plugins/glances_percpu.py index a0a06243..93abeab6 100644 --- a/glances/plugins/glances_percpu.py +++ b/glances/plugins/glances_percpu.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_plugin.py b/glances/plugins/glances_plugin.py index da6d6889..9954cf20 100644 --- a/glances/plugins/glances_plugin.py +++ b/glances/plugins/glances_plugin.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 @@ -32,6 +32,7 @@ from operator import itemgetter from glances.core.glances_globals import is_py3 from glances.core.glances_logging import logger from glances.core.glances_logs import glances_logs +from glances.core.glances_actions import GlancesActions class GlancesPlugin(object): @@ -64,6 +65,9 @@ class GlancesPlugin(object): # Init the limits dictionnary self.limits = dict() + # Init the actions + self.actions = GlancesActions() + def __repr__(self): """Return the raw stats.""" return self.stats @@ -263,6 +267,8 @@ class GlancesPlugin(object): except ValueError: self.limits[ self.plugin_name + '_' + s] = config.get_raw_option(self.plugin_name, s).split(",") + logger.debug("Load limit: {0} = {1}".format(self.plugin_name + '_' + s, + self.limits[self.plugin_name + '_' + s])) def set_limits(self, input_limits): """Set the limits to input_limits.""" @@ -299,19 +305,21 @@ class GlancesPlugin(object): # Manage limits ret = 'OK' try: - if value > self.__get_limit_critical(header=header): + if value > self.__get_limit('critical', header=header): ret = 'CRITICAL' - elif value > self.__get_limit_warning(header=header): + elif value > self.__get_limit('warning', header=header): ret = 'WARNING' - elif value > self.__get_limit_careful(header=header): + elif value > self.__get_limit('careful', header=header): ret = 'CAREFUL' elif current < min: ret = 'CAREFUL' except KeyError: return 'DEFAULT' - # Manage log (if needed) + # Init the return post string log_str = "" + + # Manage log if log: # Add _LOG to the return string # So stats will be highlited with a specific color @@ -324,6 +332,12 @@ class GlancesPlugin(object): # Add the log to the list glances_logs.add(ret, stat_name.upper(), value, []) + # Manage action + action = self.__get_limit_action(ret.lower(), header=header) + if action is not None: + # An action is available for the current alert, run it + self.actions.run(action) + # Default is ok return ret + log_str @@ -331,23 +345,42 @@ class GlancesPlugin(object): """Get the alert log.""" return self.get_alert(current, min, max, header, log=True) - def __get_limit_critical(self, header=""): - if header == "": - return self.limits[self.plugin_name + '_' + 'critical'] - else: - return self.limits[self.plugin_name + '_' + header + '_' + 'critical'] + def __get_limit(self, criticity, header=""): + """Return the limit value for the alert""" + prefix = self.plugin_name + '_' + if header != "": + prefix += header + '_' + action = self.limits[prefix + criticity] + return action - def __get_limit_warning(self, header=""): - if header == "": - return self.limits[self.plugin_name + '_' + 'warning'] - else: - return self.limits[self.plugin_name + '_' + header + '_' + 'warning'] + def __get_limit_action(self, criticity, header=""): + """Return the action for the alert""" + prefix = self.plugin_name + '_' + if header != "": + prefix += header + '_' + try: + action = self.limits[prefix + criticity + '_action'] + except KeyError: + action = None + return action - def __get_limit_careful(self, header=""): - if header == "": - return self.limits[self.plugin_name + '_' + 'careful'] - else: - return self.limits[self.plugin_name + '_' + header + '_' + 'careful'] + # def __get_limit_critical(self, header=""): + # if header == "": + # return self.limits[self.plugin_name + '_' + 'critical'] + # else: + # return self.limits[self.plugin_name + '_' + header + '_' + 'critical'] + + # def __get_limit_warning(self, header=""): + # if header == "": + # return self.limits[self.plugin_name + '_' + 'warning'] + # else: + # return self.limits[self.plugin_name + '_' + header + '_' + 'warning'] + + # def __get_limit_careful(self, header=""): + # if header == "": + # return self.limits[self.plugin_name + '_' + 'careful'] + # else: + # return self.limits[self.plugin_name + '_' + header + '_' + 'careful'] def get_conf_value(self, value, header="", plugin_name=None): """Return the configuration (header_)value for the current plugin (or the one given by the plugin_name var)""" diff --git a/glances/plugins/glances_processcount.py b/glances/plugins/glances_processcount.py index cfdc1ebc..3248ef1d 100644 --- a/glances/plugins/glances_processcount.py +++ b/glances/plugins/glances_processcount.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_processlist.py b/glances/plugins/glances_processlist.py index 061ccc1b..c0502c7b 100644 --- a/glances/plugins/glances_processlist.py +++ b/glances/plugins/glances_processlist.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_psutilversion.py b/glances/plugins/glances_psutilversion.py index 9c54b8df..0c2ffa14 100644 --- a/glances/plugins/glances_psutilversion.py +++ b/glances/plugins/glances_psutilversion.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_raid.py b/glances/plugins/glances_raid.py index 82645cf8..20743c36 100644 --- a/glances/plugins/glances_raid.py +++ b/glances/plugins/glances_raid.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_sensors.py b/glances/plugins/glances_sensors.py index 5fe7fddc..089933a9 100644 --- a/glances/plugins/glances_sensors.py +++ b/glances/plugins/glances_sensors.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_system.py b/glances/plugins/glances_system.py index 3a5f10da..a227847c 100644 --- a/glances/plugins/glances_system.py +++ b/glances/plugins/glances_system.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 diff --git a/glances/plugins/glances_uptime.py b/glances/plugins/glances_uptime.py index 63f6341e..12e1c22b 100644 --- a/glances/plugins/glances_uptime.py +++ b/glances/plugins/glances_uptime.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2014 Nicolargo +# 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 From 91e3b2e9e4f0ea53254f004b59bc200bd2bfa9a5 Mon Sep 17 00:00:00 2001 From: Nicolargo Date: Thu, 1 Jan 2015 22:46:25 +0100 Subject: [PATCH 2/7] Display 64bit every time on 64bit environment and fix the display of io read/write (issue #469 Thk to Sylvain Mouquet) --- glances/plugins/glances_processlist.py | 8 ++++---- glances/plugins/glances_system.py | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/glances/plugins/glances_processlist.py b/glances/plugins/glances_processlist.py index c0502c7b..2e1cc6c0 100644 --- a/glances/plugins/glances_processlist.py +++ b/glances/plugins/glances_processlist.py @@ -235,18 +235,18 @@ class Plugin(GlancesPlugin): # IO read/write if 'io_counters' in p: # IO read - io_rs = (p['io_counters'][0] - p['io_counters'][2]) / p['time_since_update'] + io_rs = int((p['io_counters'][0] - p['io_counters'][2]) / p['time_since_update']) if io_rs == 0: msg = '{0:>6}'.format("0") else: - msg = '{0:>6}'.format(self.auto_unit(io_rs, low_precision=False)) + msg = '{0:>6}'.format(self.auto_unit(io_rs, low_precision=True)) ret.append(self.curse_add_line(msg, optional=True, additional=True)) # IO write - io_ws = (p['io_counters'][1] - p['io_counters'][3]) / p['time_since_update'] + io_ws = int((p['io_counters'][1] - p['io_counters'][3]) / p['time_since_update']) if io_ws == 0: msg = '{0:>6}'.format("0") else: - msg = '{0:>6}'.format(self.auto_unit(io_ws, low_precision=False)) + msg = '{0:>6}'.format(self.auto_unit(io_ws, low_precision=True)) ret.append(self.curse_add_line(msg, optional=True, additional=True)) else: msg = '{0:>6}'.format("?") diff --git a/glances/plugins/glances_system.py b/glances/plugins/glances_system.py index a227847c..e5e1acfa 100644 --- a/glances/plugins/glances_system.py +++ b/glances/plugins/glances_system.py @@ -118,6 +118,10 @@ class Plugin(GlancesPlugin): elif self.stats['os_name'] == "Windows": os_version = platform.win32_ver() self.stats['os_version'] = ' '.join(os_version[::2]) + # if the python version is 32 bit perhaps the windows operating system is 64bit + if self.stats['platform'] == '32bit': + if 'PROCESSOR_ARCHITEW6432' in os.environ: + self.stats['platform'] = '64bit' else: self.stats['os_version'] = "" # Add human readable name From 6f18c3fd7b8bd12f20661560cc50abda0e11b5f2 Mon Sep 17 00:00:00 2001 From: desbma Date: Thu, 1 Jan 2015 19:50:21 +0100 Subject: [PATCH 3/7] Don't break wiki link Conflicts: docs/glances-doc.rst --- docs/glances-doc.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/glances-doc.rst b/docs/glances-doc.rst index 26c375d4..243e709f 100644 --- a/docs/glances-doc.rst +++ b/docs/glances-doc.rst @@ -741,7 +741,7 @@ Glances includes a `XML-RPC server`_ and a `RESTFULL-JSON`_ API which and can be APIs documentations are available at: - XML-RPC: https://github.com/nicolargo/glances/wiki/The-Glances-2.x-API-How-to -- RESTFULL-JSON: https://github.com/nicolargo/glances/wiki/The-Glances-RESTFULL-JSON-API +- RESTFUL-JSON: https://github.com/nicolargo/glances/wiki/The-Glances-RESTFULL-JSON-API Support ======= From 7f34a6d07ac4c48829d2a1912ff2f944906c386e Mon Sep 17 00:00:00 2001 From: Nicolargo Date: Thu, 1 Jan 2015 23:40:40 +0100 Subject: [PATCH 4/7] Trigger OK --- glances/core/glances_actions.py | 41 ++++++++++++++++++++++++++++--- glances/plugins/glances_plugin.py | 24 +++++++++--------- 2 files changed, 50 insertions(+), 15 deletions(-) diff --git a/glances/core/glances_actions.py b/glances/core/glances_actions.py index 9ee947b2..0624fd13 100644 --- a/glances/core/glances_actions.py +++ b/glances/core/glances_actions.py @@ -30,11 +30,44 @@ class GlancesActions(object): """This class manage action if an alert is reached""" - def run(self, commands): - """Run the commands (in background) - - commands: a list of command line""" + def __init__(self): + """Init GlancesActions class""" + # Dict with the criticity status + # - key: stat_name + # - value: criticity + # Goal: avoid to execute the same command twice + self.status = {} + + def get(self, stat_name): + """Get the stat_name criticity""" + try: + return self.status[stat_name] + except KeyError: + return None + + def set(self, stat_name, criticity): + """Set the stat_name to criticity""" + self.status[stat_name] = criticity + + def run(self, stat_name, criticity, commands): + """Run the commands (in background) + - stats_name: plugin_name (+ header) + - criticity: criticity of the trigger + - commands: a list of command line + + Return True if the commands have been ran""" + + if self.get(stat_name) == criticity: + # Action already executed => Exit + return False + + # Ran all actions in background for cmd in commands: - logger.info("Action triggered: {0}".format(cmd)) + logger.info("Action triggered for {0} ({1}): {2}".format(stat_name, criticity, cmd)) splitted_cmd = cmd.split() Popen(splitted_cmd) + + self.set(stat_name, criticity) + + return True diff --git a/glances/plugins/glances_plugin.py b/glances/plugins/glances_plugin.py index 9954cf20..ecc2d4ca 100644 --- a/glances/plugins/glances_plugin.py +++ b/glances/plugins/glances_plugin.py @@ -316,27 +316,29 @@ class GlancesPlugin(object): except KeyError: return 'DEFAULT' - # Init the return post string - log_str = "" + # Get the stat_name = plugin_name (+ header) + if header == "": + stat_name = self.plugin_name + else: + stat_name = self.plugin_name + '_' + header # Manage log + log_str = "" if log: # Add _LOG to the return string # So stats will be highlited with a specific color log_str = "_LOG" - # Get the stat_name = plugin_name (+ header) - if header == "": - stat_name = self.plugin_name - else: - stat_name = self.plugin_name + '_' + header # Add the log to the list glances_logs.add(ret, stat_name.upper(), value, []) # Manage action - action = self.__get_limit_action(ret.lower(), header=header) - if action is not None: - # An action is available for the current alert, run it - self.actions.run(action) + # Here is a command line for the current trigger ? + command = self.__get_limit_action(ret.lower(), header=header) + if command is not None: + # Acommand line is available for the current alert, run it + self.actions.run(stat_name, ret.lower(), command) + else: + self.actions.set(stat_name, ret.lower()) # Default is ok return ret + log_str From e32089f40a16a267cca08cc1b16a690f4c5f1d36 Mon Sep 17 00:00:00 2001 From: Nicolargo Date: Fri, 2 Jan 2015 17:45:18 +0100 Subject: [PATCH 5/7] Catch exp on alert --- glances/core/glances_actions.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/glances/core/glances_actions.py b/glances/core/glances_actions.py index 0624fd13..4c7011e0 100644 --- a/glances/core/glances_actions.py +++ b/glances/core/glances_actions.py @@ -66,7 +66,10 @@ class GlancesActions(object): for cmd in commands: logger.info("Action triggered for {0} ({1}): {2}".format(stat_name, criticity, cmd)) splitted_cmd = cmd.split() - Popen(splitted_cmd) + try: + Popen(splitted_cmd) + except OSError as e: + logger.error("Can't execute the action ({0})".format(e)) self.set(stat_name, criticity) From dfd2cf1c38d9cb0617bef4b181bbd5c52ed3a38f Mon Sep 17 00:00:00 2001 From: Nicolargo Date: Fri, 2 Jan 2015 22:59:08 +0100 Subject: [PATCH 6/7] Add {{mustache}} feature to the action script --- NEWS | 5 ++- conf/glances-test.conf | 5 ++- glances/core/glances_actions.py | 15 ++++--- glances/outputs/glances_curses.py | 5 ++- glances/plugins/glances_fs.py | 4 +- glances/plugins/glances_plugin.py | 64 ++++++++++++++++++------------ glances/plugins/glances_sensors.py | 4 ++ 7 files changed, 65 insertions(+), 37 deletions(-) diff --git a/NEWS b/NEWS index 24298846..7ecc1530 100644 --- a/NEWS +++ b/NEWS @@ -2,12 +2,13 @@ Glances Version 2.x ============================================================================== -Version 2.X +Version 2.3 =========== + * Add actions on alerts (issue #132). It is now possible to run action (command line) by triggers. Action could containq {Mustache} {{tag}} (Mustache) with stat value. * Add InfluxDB export module (--export-influxdb) (issue #455) * Add Statsd export module (--export-statsd) (issue #465) - * Refactor export module (CSV export option is now --export-csv). It is now possible to export stats from the Glances client (issue #463) + * Refactor export module (CSV export option is now --export-csv). It is now possible to export stats from the Glances client mode (issue #463) * The Web inteface is now based on BootStarp / RWD grid (issue #417, #366 and #461) Thanks to Nicolas Hart @nclsHart * Add the RAID plugins (issue #447) diff --git a/conf/glances-test.conf b/conf/glances-test.conf index d4f9dbdc..4a804eea 100644 --- a/conf/glances-test.conf +++ b/conf/glances-test.conf @@ -3,7 +3,7 @@ user_careful=50 user_warning=70 user_critical=90 -user_critical_action=touch /tmp/glances.alert +user_critical_action=echo {{user}} {{value}} {{max}} > /tmp/cpu.alert iowait_careful=50 iowait_warning=70 iowait_critical=90 @@ -72,13 +72,14 @@ hide=sda2,sda5 # Default limits for free filesytem space in % # Default values if not defined: 50/70/90 careful=50 +careful_action=echo {{mnt_point}} {{used}}/{{size}} > /tmp/fs.alert warning=70 critical=90 [sensors] # Sensors core limits # Default values if not defined: 60/70/80 -temperature_core_careful=60 +temperature_core_careful=50 temperature_core_warning=70 temperature_core_critical=80 # Temperatures in °C for hddtemp diff --git a/glances/core/glances_actions.py b/glances/core/glances_actions.py index 4c7011e0..6069e0e8 100644 --- a/glances/core/glances_actions.py +++ b/glances/core/glances_actions.py @@ -21,6 +21,7 @@ # Import system lib from subprocess import Popen +import pystache # Import Glances lib from glances.core.glances_logging import logger @@ -50,11 +51,12 @@ class GlancesActions(object): """Set the stat_name to criticity""" self.status[stat_name] = criticity - def run(self, stat_name, criticity, commands): + def run(self, stat_name, criticity, commands, mustache_dict=None): """Run the commands (in background) - stats_name: plugin_name (+ header) - criticity: criticity of the trigger - - commands: a list of command line + - commands: a list of command line with optional {{mustache}} + - mustache_dict: Plugin stats (can be use within {{mustache}}) Return True if the commands have been ran""" @@ -64,10 +66,13 @@ class GlancesActions(object): # Ran all actions in background for cmd in commands: - logger.info("Action triggered for {0} ({1}): {2}".format(stat_name, criticity, cmd)) - splitted_cmd = cmd.split() + # Replace {{arg}} by the dict one (Thk to {Mustache}) + cmd_full = pystache.render(cmd, mustache_dict) + # Execute the action + logger.info("Action triggered for {0} ({1}): {2}".format(stat_name, criticity, cmd_full)) + logger.debug("Stats value for the trigger: {0}".format(mustache_dict)) try: - Popen(splitted_cmd) + Popen(cmd_full, shell=True) except OSError as e: logger.error("Can't execute the action ({0})".format(e)) diff --git a/glances/outputs/glances_curses.py b/glances/outputs/glances_curses.py index 5cedb395..378dc64b 100644 --- a/glances/outputs/glances_curses.py +++ b/glances/outputs/glances_curses.py @@ -697,6 +697,7 @@ class _GlancesCurses(object): # Display x = display_x + x_max = x y = display_y for m in plugin_stats['msgdict']: # New line @@ -740,9 +741,11 @@ class _GlancesCurses(object): # good offset = len(m['msg']) x = x + offset + if x > x_max: + x_max = x # Compute the next Glances column/line position - self.next_column = max(self.next_column, x + self.space_between_column) + self.next_column = max(self.next_column, x_max + self.space_between_column) self.next_line = max(self.next_line, y + self.space_between_line) def erase(self): diff --git a/glances/plugins/glances_fs.py b/glances/plugins/glances_fs.py index 20dc85c1..621ea5bc 100644 --- a/glances/plugins/glances_fs.py +++ b/glances/plugins/glances_fs.py @@ -209,7 +209,9 @@ class Plugin(GlancesPlugin): msg = '{0:>7}'.format(self.auto_unit(i['free'])) else: msg = '{0:>7}'.format(self.auto_unit(i['used'])) - ret.append(self.curse_add_line(msg, self.get_alert(i['used'], max=i['size']))) + ret.append(self.curse_add_line(msg, self.get_alert(i['used'], + max=i['size'], + header=i['mnt_point']))) msg = '{0:>7}'.format(self.auto_unit(i['size'])) ret.append(self.curse_add_line(msg)) diff --git a/glances/plugins/glances_plugin.py b/glances/plugins/glances_plugin.py index ecc2d4ca..15ba53e1 100644 --- a/glances/plugins/glances_plugin.py +++ b/glances/plugins/glances_plugin.py @@ -333,12 +333,25 @@ class GlancesPlugin(object): # Manage action # Here is a command line for the current trigger ? - command = self.__get_limit_action(ret.lower(), header=header) - if command is not None: - # Acommand line is available for the current alert, run it - self.actions.run(stat_name, ret.lower(), command) - else: + try: + command = self.__get_limit_action(ret.lower(), header=header) + except KeyError: + # Reset the trigger self.actions.set(stat_name, ret.lower()) + else: + # A command line is available for the current alert, run it + # Build the {{mustache}} dictionnary + if type(self.stats) is list: + # If the stats are stored in a list of dict (fs plugin for exemple) + # Return the dict for the current header + try: + mustache_dict = (item for item in self.stats if item[self.get_key()] == header).next() + except StopIteration: + mustache_dict = {} + else: + # Use the stats dict + mustache_dict = self.stats + self.actions.run(stat_name, ret.lower(), command, mustache_dict=mustache_dict) # Default is ok return ret + log_str @@ -352,38 +365,37 @@ class GlancesPlugin(object): prefix = self.plugin_name + '_' if header != "": prefix += header + '_' - action = self.limits[prefix + criticity] - return action + + # Get the limit for stat + header + # Exemple: network_wlan0_rx_careful + try: + limit = self.limits[prefix + criticity] + except KeyError: + # Try fallback to plugin default limit + # Exemple: network_careful + limit = self.limits[self.plugin_name + '_' + criticity] + + # Return the limit + return limit def __get_limit_action(self, criticity, header=""): """Return the action for the alert""" prefix = self.plugin_name + '_' if header != "": prefix += header + '_' + + # Get the limit for stat + header + # Exemple: network_wlan0_rx_careful_action try: action = self.limits[prefix + criticity + '_action'] except KeyError: - action = None + # Try fallback to plugin default limit + # Exemple: network_careful_action + action = self.limits[self.plugin_name + '_' + criticity + '_action'] + + # Return the action list return action - # def __get_limit_critical(self, header=""): - # if header == "": - # return self.limits[self.plugin_name + '_' + 'critical'] - # else: - # return self.limits[self.plugin_name + '_' + header + '_' + 'critical'] - - # def __get_limit_warning(self, header=""): - # if header == "": - # return self.limits[self.plugin_name + '_' + 'warning'] - # else: - # return self.limits[self.plugin_name + '_' + header + '_' + 'warning'] - - # def __get_limit_careful(self, header=""): - # if header == "": - # return self.limits[self.plugin_name + '_' + 'careful'] - # else: - # return self.limits[self.plugin_name + '_' + header + '_' + 'careful'] - def get_conf_value(self, value, header="", plugin_name=None): """Return the configuration (header_)value for the current plugin (or the one given by the plugin_name var)""" if plugin_name is None: diff --git a/glances/plugins/glances_sensors.py b/glances/plugins/glances_sensors.py index 089933a9..00fc3552 100644 --- a/glances/plugins/glances_sensors.py +++ b/glances/plugins/glances_sensors.py @@ -64,6 +64,10 @@ class Plugin(GlancesPlugin): # Init the stats self.reset() + def get_key(self): + """Return the key of the list""" + return 'label' + def reset(self): """Reset/init the stats.""" self.stats = [] From a0a3349e6350375d8ad826df4cab4751f8bc8faf Mon Sep 17 00:00:00 2001 From: Nicolargo Date: Fri, 2 Jan 2015 23:23:47 +0100 Subject: [PATCH 7/7] Update documentation --- conf/glances.conf | 2 ++ docs/glances-doc.rst | 24 ++++++++++++++++++++++-- setup.py | 3 ++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/conf/glances.conf b/conf/glances.conf index c8378e98..f3df2a25 100644 --- a/conf/glances.conf +++ b/conf/glances.conf @@ -70,6 +70,8 @@ critical=90 [fs] # Default limits for free filesytem space in % # Default values if not defined: 50/70/90 +# It is also possible to define per mount point value +# Example: /_careful=40 careful=50 warning=70 critical=90 diff --git a/docs/glances-doc.rst b/docs/glances-doc.rst index 243e709f..cd4330c6 100644 --- a/docs/glances-doc.rst +++ b/docs/glances-doc.rst @@ -4,9 +4,9 @@ Glances This manual describes *Glances* version 2.2. -Copyright © 2012-2014 Nicolas Hennion +Copyright © 2011-2015 Nicolas Hennion -December 2014 +Junuary 2015 .. contents:: Table of Contents @@ -669,6 +669,26 @@ Each alert message displays the following information: 4. {min,avg,max} values or number of running processes for monitored processes list alerts +Actions +------- + +Glances can trigger actions on events. + +By action, we mean all shell command line. For example, if you want to execute the foo.py script if the last 5 minutes load are critical then add the action line to the Glances configuration file: + + [load] + critical=5.0 + critical_action=python /path/to/foo.py + +All the stats are usable in the command line by the use of the {{mustache}} syntax. Another example to create a log file containing used vs total disk space if a warning space trigger is reached: + +[fs] +warning=70 +warning_action=echo {{mnt_point}} {{used}}/{{size}} > /tmp/fs.alert + +Note: You can use all the stats for the current plugin (see https://github.com/nicolargo/glances/wiki/The-Glances-2.x-API-How-to for the stats list) + + Gateway to others services ========================== diff --git a/setup.py b/setup.py index 5d78b0f0..cf1d40a8 100755 --- a/setup.py +++ b/setup.py @@ -67,7 +67,8 @@ setup( 'CHART': ['matplotlib'], 'BROWSER': ['zeroconf>=0.16', 'netifaces'], 'RAID': ['pymdstat'], - 'EXPORT': ['influxdb', 'statsd'] + 'EXPORT': ['influxdb', 'statsd'], + 'ACTION': ['pystache'] }, packages=['glances'], include_package_data=True,