Regression on Monitoring list

This commit is contained in:
nicolargo 2016-04-15 15:05:32 +02:00
parent 8efb5e2ac8
commit 09d87e0a4e
9 changed files with 89 additions and 39 deletions

View File

@ -171,15 +171,15 @@ mem_critical=90
# A warning will be displayed if number of process < count # A warning will be displayed if number of process < count
# * countmax: (optional) maximum number of processes # * countmax: (optional) maximum number of processes
# A warning will be displayed if number of process > count # A warning will be displayed if number of process > count
#list_1_description=Dropbox list_1_description=Dropbox
#list_1_regex=.*dropbox.* list_1_regex=.*dropbox.*
#list_1_countmin=1 list_1_countmin=1
#list_1_command=dropbox status | head -1 list_1_command=dropbox status | head -1
#list_2_description=Python programs list_2_description=Python programs
#list_2_regex=.*python.* list_2_regex=.*python.*
#list_3_description=Famous Xeyes list_3_description=Famous Xeyes
#list_3_regex=.*xeyes.* list_3_regex=.*xeyes.*
#list_3_countmin=1 list_3_countmin=1
[serverlist] [serverlist]
# Define the static servers list # Define the static servers list
@ -259,4 +259,5 @@ queue=glances_queue
enable=true enable=true
regex=\/usr\/sbin\/nginx regex=\/usr\/sbin\/nginx
refresh=60 refresh=60
one_line=false
status_url=http://localhost/nginx_status status_url=http://localhost/nginx_status

View File

@ -24,6 +24,7 @@ I am your father...
""" """
from glances.compat import u from glances.compat import u
from glances.timer import Timer
from glances.logger import logger from glances.logger import logger
@ -42,6 +43,10 @@ class GlancesAmp(object):
# Init the configs # Init the configs
self.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): def load_config(self, config):
"""Load AMP parameters from the configuration file.""" """Load AMP parameters from the configuration file."""
@ -55,7 +60,9 @@ class GlancesAmp(object):
# #
# and optionnaly: # and optionnaly:
# #
# one_line=false
# option1=opt1 # option1=opt1
# ...
# #
if (hasattr(config, 'has_section') and if (hasattr(config, 'has_section') and
config.has_section(self.amp_name)): 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 refresh time in seconds for the current application monitoring process."""
return self.get('refresh') return self.get('refresh')
def time_until_refresh(self):
"""Return time in seconds until refresh."""
return self.timer.get()
def should_update(self): def should_update(self):
"""Return True is the AMP should be updated: """Return True is the AMP should be updated:
- AMP is enable - AMP is enable
- only update every 'refresh' seconds - 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): def set_result(self, result):
"""Store the result (string) into the result key of the AMP""" """Store the result (string) into the result key of the AMP"""
@ -113,4 +128,7 @@ class GlancesAmp(object):
def result(self): def result(self):
""" Return the result of the AMP (as a string)""" """ 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

View File

@ -29,19 +29,23 @@ class Amp(GlancesAmp):
"""Glances' Nginx AMP.""" """Glances' Nginx AMP."""
def __init__(self, args=None): # def __init__(self, args=None):
"""Init the AMP.""" # """Init the AMP."""
super(Amp, self).__init__(args=args) # super(Amp, self).__init__(args=args)
def update(self): def update(self):
"""Update the AMP""" """Update the AMP"""
if self.should_update(): if self.should_update():
logger.debug('AMPS: Update {0} using status URL {1}'.format(self.amp_name, self.get('status_url'))) 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')) req = requests.get(self.get('status_url'))
if req.ok: if req.ok:
# u'Active connections: 1 \nserver accepts handled requests\n 1 1 1 \nReading: 0 Writing: 1 Waiting: 0 \n' # 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: else:
logger.debug('AMPS: Can not grab status URL {0} ({1})'.format(self.get('status_url'), req.reason)) logger.debug('AMPS: Can not grab status URL {0} ({1})'.format(self.get('status_url'), req.reason))

View File

@ -21,7 +21,7 @@
import os import os
import re import re
import subprocess import threading
from glances.compat import listkeys, iteritems from glances.compat import listkeys, iteritems
from glances.logger import logger from glances.logger import logger
@ -100,7 +100,10 @@ class AmpsList(object):
# At least one process is matching the regex # At least one process is matching the regex
logger.debug("AMPS: {} process detected (PID={})".format(k, amps_list[0]['pid'])) logger.debug("AMPS: {} process detected (PID={})".format(k, amps_list[0]['pid']))
# Call the AMP update method # 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 return self.__amps_dict

View File

@ -32,7 +32,7 @@ if PY3:
from xmlrpc.client import Fault, ProtocolError, ServerProxy, Transport from xmlrpc.client import Fault, ProtocolError, ServerProxy, Transport
from xmlrpc.server import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer from xmlrpc.server import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer
from urllib.request import urlopen from urllib.request import urlopen
from urllib.error import URLError from urllib.error import URLError, timeout
input = input input = input
range = range range = range

View File

@ -725,13 +725,13 @@ class _GlancesCurses(object):
self.display_plugin(stats_docker) self.display_plugin(stats_docker)
self.new_line() self.new_line()
self.display_plugin(stats_processcount) 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: 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.new_line()
self.display_plugin(stats_monitor) self.display_plugin(stats_monitor)
self.new_line() self.new_line()
self.display_plugin(stats_amps)
# self.new_line()
self.display_plugin(stats_processlist, self.display_plugin(stats_processlist,
display_optional=(screen_x > 102), display_optional=(screen_x > 102),
display_additional=(not OSX), display_additional=(not OSX),

View File

@ -21,6 +21,7 @@
from glances.compat import iteritems from glances.compat import iteritems
from glances.amps_list import AmpsList as glancesAmpsList from glances.amps_list import AmpsList as glancesAmpsList
from glances.logger import logger
from glances.plugins.glances_plugin import GlancesPlugin from glances.plugins.glances_plugin import GlancesPlugin
@ -54,10 +55,14 @@ class Plugin(GlancesPlugin):
self.reset() self.reset()
if self.input_method == 'local': if self.input_method == 'local':
# TODO
for k, v in iteritems(self.glances_amps.update()): 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: else:
# Not available in SNMP mode
pass pass
return self.stats return self.stats
@ -73,12 +78,21 @@ class Plugin(GlancesPlugin):
# Build the string message # Build the string message
for m in self.stats: for m in self.stats:
for k, v in iteritems(m): if m['result'] is None:
msg = '{0:<16} '.format(k) # 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)) ret.append(self.curse_add_line(msg))
msg = '{0}'.format(v.replace('\n', '')) # ... only on the first line
ret.append(self.curse_add_line(msg, splittable=True)) first_column = ''
ret.append(self.curse_new_line()) # 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 # Delete the last empty line
try: try:

View File

@ -138,11 +138,15 @@ class Plugin(GlancesPlugin):
# VPN with no internet access (issue #842) # VPN with no internet access (issue #842)
msg = '/{0}'.format(self.stats['mask_cidr']) msg = '/{0}'.format(self.stats['mask_cidr'])
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
if self.stats['public_address'] is not None: try:
msg = ' Pub ' msg_pub = '{0:}'.format(self.stats['public_address'])
ret.append(self.curse_add_line(msg, 'TITLE')) except UnicodeEncodeError:
msg = '{0:}'.format(self.stats['public_address']) pass
ret.append(self.curse_add_line(msg)) 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 return ret
@ -186,7 +190,10 @@ class PublicIpAddress(object):
queue_target.put(None) queue_target.put(None)
else: else:
# Request depend on service # Request depend on service
if not json: try:
queue_target.put(response) if not json:
else: queue_target.put(response)
queue_target.put(loads(response)[key]) else:
queue_target.put(loads(response)[key])
except ValueError:
queue_target.put(None)

View File

@ -2,7 +2,7 @@
# #
# This file is part of Glances. # This file is part of Glances.
# #
# Copyright (C) 2015 Nicolargo <nicolas@nicolargo.com> # Copyright (C) 2016 Nicolargo <nicolas@nicolargo.com>
# #
# Glances is free software; you can redistribute it and/or modify # 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 # it under the terms of the GNU Lesser General Public License as published by
@ -53,6 +53,9 @@ class Timer(object):
def reset(self): def reset(self):
self.start() self.start()
def get(self):
return self.duration - (self.target - time())
def set(self, duration): def set(self, duration):
self.duration = duration self.duration = duration