diff --git a/conf/glances.conf b/conf/glances.conf index 62f01d9b..17392939 100644 --- a/conf/glances.conf +++ b/conf/glances.conf @@ -171,15 +171,15 @@ mem_critical=90 # A warning will be displayed if number of process < count # * countmax: (optional) maximum number of processes # A warning will be displayed if number of process > count -#list_1_description=Dropbox -#list_1_regex=.*dropbox.* -#list_1_countmin=1 -#list_1_command=dropbox status | head -1 -#list_2_description=Python programs -#list_2_regex=.*python.* -#list_3_description=Famous Xeyes -#list_3_regex=.*xeyes.* -#list_3_countmin=1 +list_1_description=Dropbox +list_1_regex=.*dropbox.* +list_1_countmin=1 +list_1_command=dropbox status | head -1 +list_2_description=Python programs +list_2_regex=.*python.* +list_3_description=Famous Xeyes +list_3_regex=.*xeyes.* +list_3_countmin=1 [serverlist] # Define the static servers list @@ -259,4 +259,5 @@ queue=glances_queue enable=true regex=\/usr\/sbin\/nginx refresh=60 +one_line=false status_url=http://localhost/nginx_status diff --git a/glances/amps/glances_amp.py b/glances/amps/glances_amp.py index 1a95f68a..4dd9bb34 100644 --- a/glances/amps/glances_amp.py +++ b/glances/amps/glances_amp.py @@ -24,6 +24,7 @@ I am your father... """ from glances.compat import u +from glances.timer import Timer from glances.logger import logger @@ -42,6 +43,10 @@ class GlancesAmp(object): # Init the configs self.configs = {} + # A timer is needed to only update every refresh seconds + # Init to 0 in order to update the AMP on startup + self.timer = Timer(0) + def load_config(self, config): """Load AMP parameters from the configuration file.""" @@ -55,7 +60,9 @@ class GlancesAmp(object): # # and optionnaly: # + # one_line=false # option1=opt1 + # ... # if (hasattr(config, 'has_section') and config.has_section(self.amp_name)): @@ -100,12 +107,20 @@ class GlancesAmp(object): """Return refresh time in seconds for the current application monitoring process.""" return self.get('refresh') + def time_until_refresh(self): + """Return time in seconds until refresh.""" + return self.timer.get() + def should_update(self): """Return True is the AMP should be updated: - AMP is enable - only update every 'refresh' seconds """ - return True + if self.timer.finished(): + self.timer.set(self.refresh()) + self.timer.reset() + return self.enable() + return False def set_result(self, result): """Store the result (string) into the result key of the AMP""" @@ -113,4 +128,7 @@ class GlancesAmp(object): def result(self): """ Return the result of the AMP (as a string)""" - return u(self.get('result')) + ret = self.get('result') + if ret is not None: + ret = u(ret) + return ret diff --git a/glances/amps/glances_nginx.py b/glances/amps/glances_nginx.py index 33b49309..1cc80026 100644 --- a/glances/amps/glances_nginx.py +++ b/glances/amps/glances_nginx.py @@ -29,19 +29,23 @@ class Amp(GlancesAmp): """Glances' Nginx AMP.""" - def __init__(self, args=None): - """Init the AMP.""" - super(Amp, self).__init__(args=args) + # def __init__(self, args=None): + # """Init the AMP.""" + # super(Amp, self).__init__(args=args) def update(self): """Update the AMP""" if self.should_update(): logger.debug('AMPS: Update {0} using status URL {1}'.format(self.amp_name, self.get('status_url'))) + # Get the Nginx status req = requests.get(self.get('status_url')) if req.ok: # u'Active connections: 1 \nserver accepts handled requests\n 1 1 1 \nReading: 0 Writing: 1 Waiting: 0 \n' - self.set_result(req.text) + if self.get('one_line') is not None and self.get('one_line').lower() == 'true': + self.set_result(req.text.replace('\n', '')) + else: + self.set_result(req.text) else: logger.debug('AMPS: Can not grab status URL {0} ({1})'.format(self.get('status_url'), req.reason)) diff --git a/glances/amps_list.py b/glances/amps_list.py index ff197870..089202bc 100644 --- a/glances/amps_list.py +++ b/glances/amps_list.py @@ -21,7 +21,7 @@ import os import re -import subprocess +import threading from glances.compat import listkeys, iteritems from glances.logger import logger @@ -100,7 +100,10 @@ class AmpsList(object): # At least one process is matching the regex logger.debug("AMPS: {} process detected (PID={})".format(k, amps_list[0]['pid'])) # Call the AMP update method - v.update() + # TODO: should be non blocking + thread = threading.Thread(target=v.update) + thread.start() + # v.update() return self.__amps_dict diff --git a/glances/compat.py b/glances/compat.py index 049bb6dd..920d256a 100644 --- a/glances/compat.py +++ b/glances/compat.py @@ -32,7 +32,7 @@ if PY3: from xmlrpc.client import Fault, ProtocolError, ServerProxy, Transport from xmlrpc.server import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer from urllib.request import urlopen - from urllib.error import URLError + from urllib.error import URLError, timeout input = input range = range diff --git a/glances/outputs/glances_curses.py b/glances/outputs/glances_curses.py index 8fe66c01..a02a409e 100644 --- a/glances/outputs/glances_curses.py +++ b/glances/outputs/glances_curses.py @@ -725,13 +725,13 @@ class _GlancesCurses(object): self.display_plugin(stats_docker) self.new_line() self.display_plugin(stats_processcount) - self.new_line() - self.display_plugin(stats_amps) if glances_processes.process_filter is None and cs_status is None: - # Do not display stats monitor list if a filter exist + # Do not display stats monitor list and AMPS if a filter exist self.new_line() self.display_plugin(stats_monitor) - self.new_line() + self.new_line() + self.display_plugin(stats_amps) + # self.new_line() self.display_plugin(stats_processlist, display_optional=(screen_x > 102), display_additional=(not OSX), diff --git a/glances/plugins/glances_amps.py b/glances/plugins/glances_amps.py index ff93cca3..91a41396 100644 --- a/glances/plugins/glances_amps.py +++ b/glances/plugins/glances_amps.py @@ -21,6 +21,7 @@ from glances.compat import iteritems from glances.amps_list import AmpsList as glancesAmpsList +from glances.logger import logger from glances.plugins.glances_plugin import GlancesPlugin @@ -54,10 +55,14 @@ class Plugin(GlancesPlugin): self.reset() if self.input_method == 'local': - # TODO for k, v in iteritems(self.glances_amps.update()): - self.stats.append({k: v.result()}) + # self.stats.append({k: v.result()}) + self.stats.append({'key': k, + 'result': v.result(), + 'refresh': v.refresh(), + 'timer': v.time_until_refresh()}) else: + # Not available in SNMP mode pass return self.stats @@ -73,12 +78,21 @@ class Plugin(GlancesPlugin): # Build the string message for m in self.stats: - for k, v in iteritems(m): - msg = '{0:<16} '.format(k) + if m['result'] is None: + # Only display AMP if a result exist + continue + # Display AMP + # first_column = '{0} {1}/{2}'.format(m['key'], int(m['timer']), int(m['refresh'])) + first_column = '{0}'.format(m['key']) + for l in m['result'].split('\n'): + # Display first column with the process name... + msg = '{0:<16} '.format(first_column) ret.append(self.curse_add_line(msg)) - msg = '{0}'.format(v.replace('\n', '')) - ret.append(self.curse_add_line(msg, splittable=True)) - ret.append(self.curse_new_line()) + # ... only on the first line + first_column = '' + # Display AMP result in the second column + ret.append(self.curse_add_line(l, splittable=True)) + ret.append(self.curse_new_line()) # Delete the last empty line try: diff --git a/glances/plugins/glances_ip.py b/glances/plugins/glances_ip.py index 99bab71e..87fc930c 100644 --- a/glances/plugins/glances_ip.py +++ b/glances/plugins/glances_ip.py @@ -138,11 +138,15 @@ class Plugin(GlancesPlugin): # VPN with no internet access (issue #842) msg = '/{0}'.format(self.stats['mask_cidr']) ret.append(self.curse_add_line(msg)) - if self.stats['public_address'] is not None: - msg = ' Pub ' - ret.append(self.curse_add_line(msg, 'TITLE')) - msg = '{0:}'.format(self.stats['public_address']) - ret.append(self.curse_add_line(msg)) + try: + msg_pub = '{0:}'.format(self.stats['public_address']) + except UnicodeEncodeError: + pass + else: + if self.stats['public_address'] is not None: + msg = ' Pub ' + ret.append(self.curse_add_line(msg, 'TITLE')) + ret.append(self.curse_add_line(msg_pub)) return ret @@ -186,7 +190,10 @@ class PublicIpAddress(object): queue_target.put(None) else: # Request depend on service - if not json: - queue_target.put(response) - else: - queue_target.put(loads(response)[key]) + try: + if not json: + queue_target.put(response) + else: + queue_target.put(loads(response)[key]) + except ValueError: + queue_target.put(None) diff --git a/glances/timer.py b/glances/timer.py index 71fd4667..896a053e 100644 --- a/glances/timer.py +++ b/glances/timer.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2015 Nicolargo +# Copyright (C) 2016 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 @@ -53,6 +53,9 @@ class Timer(object): def reset(self): self.start() + def get(self): + return self.duration - (self.target - time()) + def set(self, duration): self.duration = duration