diff options
author | Nicolas Hennion <nicolashennion@gmail.com> | 2013-01-11 12:47:48 -0800 |
---|---|---|
committer | Nicolas Hennion <nicolashennion@gmail.com> | 2013-01-11 12:47:48 -0800 |
commit | bfbc1b7609c57ef3a9e731497e4179c476489044 (patch) | |
tree | 9e10ca9a1f24a7f5b44e0535f936aeb76b0df0bf | |
parent | ebf8cf92d2520b2d5f815e6531b1a628f1e0dd6f (diff) | |
parent | 93596379d99b47f19c1cf171b49bdd4e25c04eba (diff) |
Merge pull request #160 from nicolargo/iorate
IoRate and more...
-rw-r--r-- | NEWS | 13 | ||||
-rw-r--r-- | glances/conf/glances.conf | 69 | ||||
-rwxr-xr-x | glances/glances.py | 921 | ||||
-rw-r--r-- | i18n/es/LC_MESSAGES/glances.mo | bin | 934 -> 934 bytes | |||
-rw-r--r-- | i18n/es/LC_MESSAGES/glances.po | 379 | ||||
-rw-r--r-- | i18n/fr/LC_MESSAGES/glances.mo | bin | 3422 -> 7709 bytes | |||
-rw-r--r-- | i18n/fr/LC_MESSAGES/glances.po | 503 | ||||
-rw-r--r-- | i18n/glances.pot | 379 | ||||
-rw-r--r-- | i18n/it/LC_MESSAGES/glances.mo | bin | 853 -> 853 bytes | |||
-rw-r--r-- | i18n/it/LC_MESSAGES/glances.po | 379 | ||||
-rw-r--r-- | i18n/pt_BR/LC_MESSAGES/glances.mo | bin | 924 -> 924 bytes | |||
-rw-r--r-- | i18n/pt_BR/LC_MESSAGES/glances.po | 379 | ||||
-rwxr-xr-x | setup.py | 6 |
13 files changed, 1904 insertions, 1124 deletions
@@ -1,3 +1,16 @@ +Version 1.6 +=========== + + * Configuration file: user can defines limits + * Display limits in the help screen + * Add per process IO (read and write) rate in B per second + IO rate only available on Linux from a root account + * If CPU iowait alert then sort by processes by IO rate + * Per CPU display IOwait (if data is available) + * Process column style auto (underline) or manual (bold) + * Display a sort indicator (is space is available) + * Change the table key in the help screen + Version 1.5.2 ============= diff --git a/glances/conf/glances.conf b/glances/conf/glances.conf new file mode 100644 index 00000000..3cbebba4 --- /dev/null +++ b/glances/conf/glances.conf @@ -0,0 +1,69 @@ +[cpu] +# Limits values for CPU user in % +# Defaults values if not defined: 50/70/90 +user_careful=50 +user_warning=70 +user_critical=90 +# Limits values for CPU system in % +# Defaults values if not defined: 50/70/90 +system_careful=50 +system_warning=70 +system_critical=90 +# Limits values for CPU iowait in % +# Defaults values if not defined: 40/60/80 +# Not easy to tweek... +# Source: http://blog.scoutapp.com/articles/2011/02/10/understanding-disk-i-o-when-should-you-be-worried +# http://blog.logicmonitor.com/2011/04/20/troubleshooting-server-performance-and-application-monitoring-a-real-example/ +# http://blog.developpeur-neurasthenique.fr/auto-hebergement-iowait-ma-tuer-1-2-vmstat-mpstat-atop-pidstat.html (FR) +iowait_careful=40 +iowait_warning=60 +iowait_critical=80 + +[load] +# Value * Core +# Defaults values if not defined: 0.7/1.0/5.0 per Core +# Source: http://blog.scoutapp.com/articles/2009/07/31/understanding-load-averages +# http://www.linuxjournal.com/article/9001 +careful=0.7 +warning=1.0 +critical=5.0 + +[memory] +# Defaults limits for free RAM memory in % +# Defaults values if not defined: 50/70/90 +careful=50 +warning=70 +critical=90 + +[swap] +# Defaults limits for free swap memory in % +# Defaults values if not defined: 50/70/90 +careful=50 +warning=70 +critical=90 + +[temperature] +# Temperatures in °C for sensors +# Defaults values if not defined: 60/70/80 +careful=60 +warning=70 +critical=80 + +[filesystem] +# Defaults limits for free filesytem space in % +# Defaults values if not defined: 50/70/90 +careful=50 +warning=70 +critical=90 + +[process] +# Limits values for CPU per process in % +# Defaults values if not defined: 50/70/90 +cpu_careful=50 +cpu_warning=70 +cpu_critical=90 +# Limits values for MEM per process in % +# Defaults values if not defined: 50/70/90 +mem_careful=50 +mem_warning=70 +mem_critical=90 diff --git a/glances/glances.py b/glances/glances.py index 9430bb37..58c1aa91 100755 --- a/glances/glances.py +++ b/glances/glances.py @@ -19,7 +19,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. __appname__ = 'glances' -__version__ = "1.5.2" +__version__ = "1.6b" __author__ = "Nicolas Hennion <nicolas@nicolargo.com>" __licence__ = "LGPL" @@ -34,6 +34,7 @@ import getopt import signal import time from datetime import datetime, timedelta +import ConfigParser import locale import gettext locale.setlocale(locale.LC_ALL, '') @@ -180,6 +181,8 @@ except ImportError: else: csv_lib_tag = True +# Define the default configuration file +default_conf_file = "/etc/glances.conf" # Classes #======== @@ -206,51 +209,190 @@ class glancesLimits: # The limit list is stored in an hash table: # limits_list[STAT] = [CAREFUL, WARNING, CRITICAL] - # Exemple: - # limits_list['STD'] = [50, 70, 90] - - #_______________________CAREFUL WARNING CRITICAL + # + # STD is for defaults limits (CPU / MEM / SWAP / FS) + # CPU_IOWAIT limits (iowait in %) + # LOAD is for LOAD limits (5 min / 15 min) + # TEMP is for sensors limits (temperature in °C) + # + #_____________________[ CAREFUL, WARNING, CRITICAL ] __limits_list = {'STD': [50, 70, 90], + 'CPU_USER': [50, 70, 90], + 'CPU_SYSTEM': [50, 70, 90], + 'CPU_IOWAIT': [40, 60, 80], 'LOAD': [0.7, 1.0, 5.0], - 'TEMP': [50, 70, 80]} + 'MEM': [50, 70, 90], + 'SWAP': [50, 70, 90], + 'TEMP': [60, 70, 80], + 'FS': [50, 70, 90], + 'PROCESS_CPU': [50, 70, 90], + 'PROCESS_MEM': [50, 70, 90]} + + def __init__(self, conf_file = default_conf_file): + # Open the configuration file + config = ConfigParser.RawConfigParser() + if (config.read(conf_file) != []): + # The configuration file exist + if (config.has_section('global')): + # The configuration file has a limits section + # Read STD limits + self.__setLimits(config, 'global', 'STD', 'careful') + self.__setLimits(config, 'global', 'STD', 'warning') + self.__setLimits(config, 'global', 'STD', 'critical') + if (config.has_section('cpu')): + # Read CPU limits + self.__setLimits(config, 'cpu', 'CPU_USER', 'user_careful') + self.__setLimits(config, 'cpu', 'CPU_USER', 'user_warning') + self.__setLimits(config, 'cpu', 'CPU_USER', 'user_critical') + self.__setLimits(config, 'cpu', 'CPU_SYSTEM', 'system_careful') + self.__setLimits(config, 'cpu', 'CPU_SYSTEM', 'system_warning') + self.__setLimits(config, 'cpu', 'CPU_SYSTEM', 'system_critical') + self.__setLimits(config, 'cpu', 'CPU_IOWAIT', 'iowait_careful') + self.__setLimits(config, 'cpu', 'CPU_IOWAIT', 'iowait_warning') + self.__setLimits(config, 'cpu', 'CPU_IOWAIT', 'iowait_critical') + if (config.has_section('load')): + # Read LOAD limits + self.__setLimits(config, 'load', 'LOAD', 'careful') + self.__setLimits(config, 'load', 'LOAD', 'warning') + self.__setLimits(config, 'load', 'LOAD', 'critical') + if (config.has_section('memory')): + # Read MEM limits + self.__setLimits(config, 'memory', 'MEM', 'careful') + self.__setLimits(config, 'memory', 'MEM', 'warning') + self.__setLimits(config, 'memory', 'MEM', 'critical') + if (config.has_section('swap')): + # Read MEM limits + self.__setLimits(config, 'swap', 'SWAP', 'careful') + self.__setLimits(config, 'swap', 'SWAP', 'warning') + self.__setLimits(config, 'swap', 'SWAP', 'critical') + if (config.has_section('temperature')): + # Read TEMP limits + self.__setLimits(config, 'temperature', 'TEMP', 'careful') + self.__setLimits(config, 'temperature', 'TEMP', 'warning') + self.__setLimits(config, 'temperature', 'TEMP', 'critical') + if (config.has_section('filesystem')): + # Read FS limits + self.__setLimits(config, 'filesystem', 'FS', 'careful') + self.__setLimits(config, 'filesystem', 'FS', 'warning') + self.__setLimits(config, 'filesystem', 'FS', 'critical') + if (config.has_section('process')): + # Process limits + self.__setLimits(config, 'process', 'PROCESS_CPU', 'cpu_careful') + self.__setLimits(config, 'process', 'PROCESS_CPU', 'cpu_warning') + self.__setLimits(config, 'process', 'PROCESS_CPU', 'cpu_critical') + self.__setLimits(config, 'process', 'PROCESS_MEM', 'mem_careful') + self.__setLimits(config, 'process', 'PROCESS_MEM', 'mem_warning') + self.__setLimits(config, 'process', 'PROCESS_MEM', 'mem_critical') + + def __setLimits(self, config, section, stat, alert): + """ + config: Pointer to the config file ConfigParser.RawConfigParser() + section: 'limits' + stat: 'CPU', 'LOAD', 'MEM', 'SWAP', 'TEMP'... + alert key (from config file): + """ + try: + value = config.getfloat(section, alert) + except ConfigParser.NoOptionError: + pass + else: + #~ print("%s / %s = %s -> %s" % (section, alert, value, stat)) + if (alert.endswith('careful')): + self.__limits_list[stat][0] = value + elif (alert.endswith('warning')): + self.__limits_list[stat][1] = value + elif (alert.endswith('critical')): + self.__limits_list[stat][2] = value - def __init__(self, careful=50, warning=70, critical=90): - self.__limits_list['STD'] = [careful, warning, critical] + def getCareful(self, stat): + return self.__limits_list[stat][0] + def getWarning(self, stat): + return self.__limits_list[stat][1] + + def getCritical(self, stat): + return self.__limits_list[stat][2] + + # TO BE DELETED AFTER THE HTML output refactoring def getSTDCareful(self): - return self.__limits_list['STD'][0] + return self.getCareful('STD') def getSTDWarning(self): - return self.__limits_list['STD'][1] + return self.getWarning('STD') def getSTDCritical(self): - return self.__limits_list['STD'][2] + return self.getCritical('STD') + # /TO BE DELETED AFTER THE HTML output refactoring + + def getCPUCareful(self, stat): + return self.getCareful('CPU_' + stat.upper()) + + def getCPUWarning(self, stat): + return self.getWarning('CPU_' + stat.upper()) + + def getCPUCritical(self, stat): + return self.getCritical('CPU_' + stat.upper()) def getLOADCareful(self, core=1): - return self.__limits_list['LOAD'][0] * core + return self.getCareful('LOAD') * core def getLOADWarning(self, core=1): - return self.__limits_list['LOAD'][1] * core + return self.getWarning('LOAD') * core def getLOADCritical(self, core=1): - return self.__limits_list['LOAD'][2] * core + return self.getCritical('LOAD') * core + + def getMEMCareful(self): + return self.getCareful('MEM') + + def getMEMWarning(self): + return self.getWarning('MEM') + + def getMEMCritical(self): + return self.getCritical('MEM') + + def getSWAPCareful(self): + return self.getCareful('SWAP') + + def getSWAPWarning(self): + return self.getWarning('SWAP') + + def getSWAPCritical(self): + return self.getCritical('SWAP') def getTEMPCareful(self): - return self.__limits_list['TEMP'][0] + return self.getCareful('TEMP') def getTEMPWarning(self): - return self.__limits_list['TEMP'][1] + return self.getWarning('TEMP') def getTEMPCritical(self): - return self.__limits_list['TEMP'][2] + return self.getCritical('TEMP') + + def getFSCareful(self): + return self.getCareful('FS') + + def getFSWarning(self): + return self.getWarning('FS') + + def getFSCritical(self): + return self.getCritical('FS') + + def getProcessCareful(self, stat = ''): + return self.getCareful('PROCESS_' + stat.upper()) + + def getProcessWarning(self, stat = ''): + return self.getWarning('PROCESS_' + stat.upper()) + + def getProcessCritical(self, stat = ''): + return self.getWarning('PROCESS_' + stat.upper()) class glancesLogs: """ The main class to manage logs inside the Glances software - Logs is a list of list (stored in the self.logs_list var): - [["begin", "end", "WARNING|CRITICAL", "CPU|LOAD|MEM", - MAX, AVG, MIN, SUM, COUNT],...] + Logs is a list of list (stored in the self.logs_list var) + See item description in the add function """ def __init__(self): @@ -303,10 +445,13 @@ class glancesLogs: # Add Top process sort depending on alert type if item_type.startswith("MEM"): - # MEM + # Sort TOP process by memory_percent sortby = 'memory_percent' + elif item_type.startswith("CPU IO") and is_Linux: + # Sort TOP process by io_counters (only for Linux OS) + sortby = 'io_counters' else: - # CPU* and LOAD + # Default TOP process sort is cpu_percent (for CPU* and LOAD) sortby = 'cpu_percent' topprocess = sorted(proc_list, key=lambda process: process[sortby], reverse=True) @@ -486,6 +631,14 @@ class GlancesGrabProcesses: """ Get processed stats using the PsUtil lib """ + + def __init__(self): + """ + Init the io dict + key = pid + value = [ read_bytes_old, write_bytes_old ] + """ + self.io_old = {} def __get_process_stats__(self, proc): """ @@ -497,8 +650,11 @@ class GlancesGrabProcesses: procstat['name'] = proc.name except psutil.AccessDenied: # Can not get the process name ? - # then exit... + # then no need to retreive others stats + # so exit... return {} + + procstat['pid'] = proc.pid try: procstat['cmdline'] = " ".join(proc.cmdline) @@ -522,13 +678,34 @@ class GlancesGrabProcesses: except psutil.AccessDenied: procstat['cpu_percent'] = {} - try: - if psutil_get_io_counter_tag: - procstat['io_counters'] = proc.get_io_counters() - except: - procstat['io_counters'] = {} + # procstat['io_counters'] is a list: + # [ read_bytes, write_bytes, read_bytes_old, write_bytes_old, io_tag ] + # if io_tag = 0 > Access denied (display "?") + # If io_tag = 1 > No access denied (display the IO rate) + if psutil_get_io_counter_tag: + try: + # Get the process IO counters + proc_io = proc.get_io_counters() + io_new = [ proc_io.read_bytes, proc_io.write_bytes ] + except psutil.AccessDenied: + # Access denied to process IO (no root account) + # Put 0 in all values (for sort) and io_tag = 0 (for display) + procstat['io_counters'] = [ 0, 0 ] + [ 0, 0 ] + io_tag = 0 + else: + # For IO rate computation + # Append saved IO r/w bytes + try: + procstat['io_counters'] = io_new + self.io_old[procstat['pid']] + except KeyError: + procstat['io_counters'] = io_new + [ 0, 0 ] + # then save the IO r/w bytes + self.io_old[procstat['pid']] = io_new + io_tag = 1 + + # Append the IO tag (for display) + procstat['io_counters'] += [ io_tag ] - procstat['pid'] = proc.pid try: procstat['username'] = proc.username except psutil.AccessDenied: @@ -559,7 +736,8 @@ class GlancesGrabProcesses: def update(self): self.processlist = [] self.processcount = {'total': 0, 'running': 0, 'sleeping': 0} - + + # For each existing process... for proc in psutil.process_iter(): procstat = self.__get_process_stats__(proc) # Ignore the 'idle' process on Windows or Bsd @@ -568,8 +746,8 @@ class GlancesGrabProcesses: or (is_Windows and (procstat['name'] == 'System Idle Process'))): continue # Update processlist - self.processlist.append(procstat) - # Update processcount + self.processlist.append(procstat) + # Update processcount (global stattistics) try: self.processcount[str(proc.status)] += 1 except KeyError: @@ -611,6 +789,7 @@ class GlancesStats: # Init the process list self.process_list_refresh = True + self.process_list_sortedby = '' self.glancesgrabprocesses = GlancesGrabProcesses() def _init_host(self): @@ -727,6 +906,15 @@ class GlancesStats: if hasattr(self.percputime_new[i], 'nice'): cpu['nice'] = (self.percputime_new[i].nice - self.percputime_old[i].nice) * perpercent[i] + if hasattr(self.percputime_new[i], 'iowait'): + cpu['iowait'] = (self.percputime_new[i].iowait - + self.percputime_old[i].iowait) * perpercent[i] + if hasattr(self.percputime_new[i], 'irq'): + cpu['irq'] = (self.percputime_new[i].irq - + self.percputime_old[i].irq) * perpercent[i] + if hasattr(self.percputime_new[i], 'softirq'): + cpu['softirq'] = (self.percputime_new[i].softirq - + self.percputime_old[i].softirq) * perpercent[i] self.percpu.append(cpu) self.percputime_old = self.percputime_new self.percputime_total_old = self.percputime_total_new @@ -873,23 +1061,9 @@ class GlancesStats: self.fs = self.glancesgrabfs.get() # PROCESS - # TODO: Add IO rate -1 - #~ self.glancesgrabprocesses.update() - #~ process = self.glancesgrabprocesses.getlist() - #~ processcount = self.glancesgrabprocesses.getcount() - #~ if not hasattr(self, 'process_old'): - #~ self.processcount = {} - #~ self.process = [] - #~ self.process_old = process - #~ else: - #~ self.processcount = processcount - #~ self.process = process - #~ for proc in self.process: - #~ pass - #~ self.process_old = process self.glancesgrabprocesses.update() - process = self.glancesgrabprocesses.getlist() processcount = self.glancesgrabprocesses.getcount() + process = self.glancesgrabprocesses.getlist() if not hasattr(self, 'process'): self.processcount = {} self.process = [] @@ -897,8 +1071,6 @@ class GlancesStats: self.processcount = processcount self.process = process - # Initialiation of the running processes list - # Data are refreshed every two cycle (refresh_time * 2) # Get the current date/time self.now = datetime.now() @@ -909,8 +1081,11 @@ class GlancesStats: # Update the stats self.__update__(input_stats) - #~ def getAll(self): - #~ return self.all_stats + def getSortedBy(self): + return self.process_list_sortedby + + def getAll(self): + return self.all_stats def getHost(self): return self.host @@ -975,22 +1150,41 @@ class GlancesStats: sortedReverse = True if sortedby == 'auto': + # Auto selection + # By default sort by CPU or memory (if CPU not available) if psutil_get_cpu_percent_tag: sortedby = 'cpu_percent' else: sortedby = 'memory_percent' - # Auto selection - # If global MEM > 70% sort by MEM usage - # else sort by CPU usage - if self.mem['total'] != 0: - memtotal = (self.mem['used'] * 100) / self.mem['total'] - if memtotal > limits.getSTDWarning(): - sortedby = 'memory_percent' + # Dynamic choice + if (('iowait' in self.cpu) and + (self.cpu['iowait'] > limits.getCPUWarning(stat = 'iowait'))): + # If CPU IOWait > 70% sort by IORATE usage + sortedby = 'io_counters' + elif ((self.mem['total'] != 0) + and (((self.mem['used'] * 100) / self.mem['total']) > limits.getMEMWarning())): + # If global MEM > 70% sort by MEM usage + sortedby = 'memory_percent' elif sortedby == 'name': sortedReverse = False - return sorted(self.process, key=lambda process: process[sortedby], - reverse=sortedReverse) + if (sortedby == 'io_counters'): + # Sort process by IO rate (sum IO read + IO write) + listsorted = sorted(self.process, + key=lambda process: process[sortedby][0]-process[sortedby][2] + +process[sortedby][1]-process[sortedby][3], + reverse=sortedReverse) + else: + # Others sorts + listsorted = sorted(self.process, + key=lambda process: process[sortedby], + reverse=sortedReverse) + + # Save the latest sort type in a global var + self.process_list_sortedby = sortedby + + # Return the sorted list + return listsorted def getNow(self): return self.now @@ -1018,23 +1212,11 @@ class GlancesStatsServer(GlancesStats): self.all_stats["percpu"] = self.percpu self.all_stats["load"] = self.load self.all_stats["mem"] = self.mem - self.all_stats["memswap"] = self.memswap - if psutil_network_io_tag: - self.all_stats["network"] = self.network - else: - self.all_stats["network"] = [] - if sensors_tag: - self.all_stats["sensors"] = self.sensors - else: - self.all_stats["sensors"] = [] - if psutil_disk_io_tag: - self.all_stats["diskio"] = self.diskio - else: - self.all_stats["diskio"] = [] - if psutil_fs_usage_tag: - self.all_stats["fs"] = self.fs - else: - self.all_stats["fs"] = [] + self.all_stats["memswap"] = self.memswap + self.all_stats["network"] = self.network if psutil_network_io_tag else [] + self.all_stats["sensors"] = self.sensors if sensors_tag else [] + self.all_stats["diskio"] = self.diskio if psutil_disk_io_tag else [] + self.all_stats["fs"] = self.fs if psutil_fs_usage_tag else [] self.all_stats["processcount"] = self.processcount self.all_stats["process"] = self.process self.all_stats["core_number"] = self.core_number @@ -1050,8 +1232,6 @@ class GlancesStatsClient(GlancesStats): def __init__(self): GlancesStats.__init__(self) - # Cached informations (no need to be refreshed) - # Host and OS informations def __update__(self, input_stats): """ @@ -1272,47 +1452,30 @@ class glancesScreen: return "{0!s}".format(val) - def __getAlert(self, current=0, max=100): + def __getCpuAlert(self, current=0, max=100, stat = ''): # If current < CAREFUL of max then alert = OK # If current > CAREFUL of max then alert = CAREFUL # If current > WARNING of max then alert = WARNING # If current > CRITICAL of max then alert = CRITICAL try: - (current * 100) / max + variable = (current * 100) / max except ZeroDivisionError: return 'DEFAULT' - variable = (current * 100) / max - - if variable > limits.getSTDCritical(): + if (variable > limits.getCPUCritical(stat = stat)): return 'CRITICAL' - elif variable > limits.getSTDWarning(): + elif (variable > limits.getCPUWarning(stat = stat)): return 'WARNING' - elif variable > limits.getSTDCareful(): + elif (variable > limits.getCPUCareful(stat = stat)): return 'CAREFUL' return 'OK' - def __getColor(self, current=0, max=100): - """ - Return colors for logged stats - """ - return self.__colors_list[self.__getAlert(current, max)] - - def __getColor2(self, current=0, max=100): - """ - Return colors for non logged stats - """ - return self.__colors_list2[self.__getAlert(current, max)] + def __getCpuColor(self, current=0, max=100, stat = ''): + return self.__colors_list[self.__getCpuAlert(current, max, stat)] - def __getCpuAlert(self, current=0, max=100): - return self.__getAlert(current, max) - - def __getCpuColor(self, current=0, max=100): - return self.__getColor(current, max) - - def __getExtCpuColor(self, current=0, max=100): - return self.__getColor2(current, max) + def __getCpuColor2(self, current=0, max=100, stat = ''): + return self.__colors_list2[self.__getCpuAlert(current, max, stat)] def __getLoadAlert(self, current=0, core=1): # If current < CAREFUL*core of max then alert = OK @@ -1332,23 +1495,83 @@ class glancesScreen: def __getLoadColor(self, current=0, core=1): return self.__colors_list[self.__getLoadAlert(current, core)] + def __getLoadColor2(self, current=0, core=1): + return self.__colors_list2[self.__getLoadAlert(current, core)] + def __getMemAlert(self, current=0, max=100): - return self.__getAlert(current, max) + # If current < CAREFUL of max then alert = OK + # If current > CAREFUL of max then alert = CAREFUL + # If current > WARNING of max then alert = WARNING + # If current > CRITICAL of max then alert = CRITICAL + try: + variable = (current * 100) / max + except ZeroDivisionError: + return 'DEFAULT' + + if variable > limits.getMEMCritical(): + return 'CRITICAL' + elif variable > limits.getMEMWarning(): + return 'WARNING' + elif variable > limits.getMEMCareful(): + return 'CAREFUL' + + return 'OK' def __getMemColor(self, current=0, max=100): - return self.__getColor(current, max) + return self.__colors_list[self.__getMemAlert(current, max)] - def __getNetColor(self, current=0, max=100): - return self.__getColor2(current, max) + def __getMemColor2(self, current=0, max=100): + return self.__colors_list2[self.__getMemAlert(current, max)] - def __getSensorsColor(self, current=0, max=100): - return self.__getColor2(current, max) + def __getSwapAlert(self, current=0, max=100): + # If current < CAREFUL of max then alert = OK + # If current > CAREFUL of max then alert = CAREFUL + # If current > WARNING of max then alert = WARNING + # If current > CRITICAL of max then alert = CRITICAL + try: + variable = (current * 100) / max + except ZeroDivisionError: + return 'DEFAULT' + + if variable > limits.getSWAPCritical(): + return 'CRITICAL' + elif variable > limits.getSWAPWarning(): + return 'WARNING' + elif variable > limits.getSWAPCareful(): + return 'CAREFUL' + + return 'OK' + + def __getSwapColor(self, current=0, max=100): + return self.__colors_list[self.__getSwapAlert(current, max)] + + def __getSwapColor2(self, current=0, max=100): + return self.__colors_list2[self.__getSwapAlert(current, max)] + + def __getFsAlert(self, current=0, max=100): + # If current < CAREFUL of max then alert = OK + # If current > CAREFUL of max then alert = CAREFUL + # If current > WARNING of max then alert = WARNING + # If current > CRITICAL of max then alert = CRITICAL + try: + variable = (current * 100) / max + except ZeroDivisionError: + return 'DEFAULT' + + if variable > limits.getSWAPCritical(): + return 'CRITICAL' + elif variable > limits.getSWAPWarning(): + return 'WARNING' + elif variable > limits.getSWAPCareful(): + return 'CAREFUL' + + return 'OK' def __getFsColor(self, current=0, max=100): - return self.__getColor2(current, max) + return self.__colors_list[self.__getFsAlert(current, max)] - def __getProcessColor(self, current=0, max=100): - return self.__getColor2(current, max) + def __getFsColor2(self, current=0, max=100): + return self.__colors_list2[self.__getFsAlert(current, max)] def __getSensorsAlert(self, current=0): # Alert for Sensors (temperature in degre) @@ -1368,10 +1591,47 @@ class glancesScreen: def __getSensorsColor(self, current=0): """ - Return color for Sensors temperature (non logged stats) + Return color for Sensors temperature + """ + return self.__colors_list[self.__getSensorsAlert(current)] + + def __getSensorsColor2(self, current=0): + """ + Return color for Sensors temperature """ return self.__colors_list2[self.__getSensorsAlert(current)] + def __getProcessAlert(self, current=0, max=100, stat = ''): + # If current < CAREFUL of max then alert = OK + # If current > CAREFUL of max then alert = CAREFUL + # If current > WARNING of max then alert = WARNING + # If current > CRITICAL of max then alert = CRITICAL + try: + variable = (current * 100) / max + except ZeroDivisionError: + return 'DEFAULT' + + if (variable > limits.getProcessCritical(stat = stat)): + return 'CRITICAL' + elif (variable > limits.getProcessWarning(stat = stat)): + return 'WARNING' + elif (variable > limits.getProcessCareful(stat = stat)): + return 'CAREFUL' + + return 'OK' + + def __getProcessCpuColor(self, current=0, max=100): + return self.__colors_list[self.__getProcessAlert(current, max, 'CPU')] + + def __getProcessCpuColor2(self, current=0, max=100): + return self.__colors_list2[self.__getProcessAlert(current, max, 'CPU')] + + def __getProcessMemColor(self, current=0, max=100): + return self.__colors_list[self.__getProcessAlert(current, max, 'MEM')] + + def __getProcessMemColor2(self, current=0, max=100): + return self.__colors_list2[self.__getProcessAlert(current, max, 'MEM')] + def __catchKey(self): # Get key self.pressedkey = self.term_window.getch() @@ -1401,6 +1661,9 @@ class glancesScreen: elif self.pressedkey == 104: # 'h' > Show/hide help self.help_tag = not self.help_tag + elif self.pressedkey == 105 and psutil_get_io_counter_tag: + # 'i' > Sort processes by IO rate + self.setProcessSortedBy('io_counters') elif self.pressedkey == 108: # 'l' > Show/hide log messages self.log_tag = not self.log_tag @@ -1445,6 +1708,7 @@ class glancesScreen: # Get stats for processes (used in another functions for logs) processcount = stats.getProcessCount() processlist = stats.getProcessList(screen.getProcessSortedBy()) + # Display stats self.displaySystem(stats.getHost(), stats.getSystem()) cpu_offset = self.displayCpu(stats.getCpu(), stats.getPerCpu(), processlist) @@ -1460,10 +1724,10 @@ class glancesScreen: network_count + diskio_count) log_count = self.displayLog(self.network_y + sensors_count + network_count + diskio_count + fs_count) - self.displayProcess(processcount, processlist, log_count) - self.displayCaption(cs_status=cs_status) + self.displayProcess(processcount, processlist, stats.getSortedBy(), log_count) + self.displayCaption(cs_status = cs_status) self.displayNow(stats.getNow()) - self.displayHelp() + self.displayHelp(core = stats.getCore()) def erase(self): # Erase the content of the screen @@ -1556,12 +1820,14 @@ class g |