def sort_stats(self, sortedby=None): """Return the stats sorted by sortedby variable.""" if sortedby is None: # No need to sort... return self.stats tree = glances_processes.is_tree_enabled() if sortedby == 'io_counters' and not tree: # Specific case for io_counters # Sum of io_r + io_w try: # Sort process by IO rate (sum IO read + IO write) self.stats.sort(key=lambda process: process[sortedby][0] - process[sortedby][2] + process[sortedby][1] - process[sortedby][3], reverse=glances_processes.sort_reverse) except Exception: self.stats.sort(key=operator.itemgetter('cpu_percent'), reverse=glances_processes.sort_reverse) else: # Others sorts if tree: self.stats.set_sorting(sortedby, glances_processes.sort_reverse) else: try: self.stats.sort(key=operator.itemgetter(sortedby), reverse=glances_processes.sort_reverse) except (KeyError, TypeError): self.stats.sort(key=operator.itemgetter('name'), reverse=False) return self.stats
def update(self): """Update processes stats using the input method.""" # Reset stats self.reset() if self.input_method == 'local': # Update stats using the standard system lib # Note: Update is done in the processcount plugin # Just return the processes list if glances_processes.is_tree_enabled(): self.stats = glances_processes.gettree() else: self.stats = glances_processes.getlist() elif self.input_method == 'snmp': # No SNMP grab for processes pass return self.stats
def update(self): """Update processes stats using the input method.""" # Reset stats self.reset() if self.input_method == 'local': # Update stats using the standard system lib # Note: Update is done in the processcount plugin # Just return the processes list if glances_processes.is_tree_enabled(): self.stats = glances_processes.gettree() else: self.stats = glances_processes.getlist() elif self.input_method == 'snmp': # No SNMP grab for processes pass return self.stats
def msg_curse(self, args=None): """Return the dict to display in the curse interface.""" # Init the return message ret = [] # Only process if stats exist and display plugin enable... if not self.stats or args.disable_process: return ret # Compute the sort key process_sort_key = glances_processes.sort_key # Header self.__msg_curse_header(ret, process_sort_key, args) # Process list if glances_processes.is_tree_enabled(): ret.extend( self.get_process_tree_curses_data( self.__sort_stats(process_sort_key), args, first_level=True, max_node_count=glances_processes.max_processes)) else: # Loop over processes (sorted by the sort key previously compute) first = True for p in self.__sort_stats(process_sort_key): ret.extend(self.get_process_curses_data(p, first, args)) # End of extended stats first = False if glances_processes.process_filter is not None: if args.reset_minmax_tag: args.reset_minmax_tag = not args.reset_minmax_tag self.__mmm_reset() self.__msg_curse_sum(ret, args=args) self.__msg_curse_sum(ret, mmm='min', args=args) self.__msg_curse_sum(ret, mmm='max', args=args) # Return the message with decoration return ret
def msg_curse(self, args=None): """Return the dict to display in the curse interface.""" # Init the return message ret = [] # Only process if stats exist and display plugin enable... if not self.stats or args.disable_process: return ret # Compute the sort key process_sort_key = glances_processes.sort_key # Header self.__msg_curse_header(ret, process_sort_key, args) # Process list if glances_processes.is_tree_enabled(): ret.extend(self.get_process_tree_curses_data( self.sort_stats(process_sort_key), args, first_level=True, max_node_count=glances_processes.max_processes)) else: # Loop over processes (sorted by the sort key previously compute) first = True for p in self.sort_stats(process_sort_key): ret.extend(self.get_process_curses_data(p, first, args)) # End of extended stats first = False if glances_processes.process_filter is not None: if args.reset_minmax_tag: args.reset_minmax_tag = not args.reset_minmax_tag self.__mmm_reset() self.__msg_curse_sum(ret, args=args) self.__msg_curse_sum(ret, mmm='min', args=args) self.__msg_curse_sum(ret, mmm='max', args=args) # Return the message with decoration return ret
def __sort_stats(self, sortedby=None): """Return the stats (dict) sorted by (sortedby)""" return sort_stats(self.stats, sortedby, tree=glances_processes.is_tree_enabled(), reverse=glances_processes.sort_reverse)
def get_process_curses_data(self, p, first, args): """Get curses data to display for a process.""" ret = [self.curse_new_line()] # CPU if 'cpu_percent' in p and p[ 'cpu_percent'] is not None and p['cpu_percent'] != '': if args.disable_irix and self.nb_log_core != 0: msg = '{:>6.1f}'.format(p['cpu_percent'] / float(self.nb_log_core)) else: msg = '{:>6.1f}'.format(p['cpu_percent']) ret.append( self.curse_add_line( msg, self.get_alert(p['cpu_percent'], header="cpu"))) else: msg = '{:>6}'.format('?') ret.append(self.curse_add_line(msg)) # MEM if 'memory_percent' in p and p[ 'memory_percent'] is not None and p['memory_percent'] != '': msg = '{:>6.1f}'.format(p['memory_percent']) ret.append( self.curse_add_line( msg, self.get_alert(p['memory_percent'], header="mem"))) else: msg = '{:>6}'.format('?') ret.append(self.curse_add_line(msg)) # VMS/RSS if 'memory_info' in p and p[ 'memory_info'] is not None and p['memory_info'] != '': # VMS msg = '{:>6}'.format( self.auto_unit(p['memory_info'][1], low_precision=False)) ret.append(self.curse_add_line(msg, optional=True)) # RSS msg = '{:>6}'.format( self.auto_unit(p['memory_info'][0], low_precision=False)) ret.append(self.curse_add_line(msg, optional=True)) else: msg = '{:>6}'.format('?') ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg)) # PID msg = '{:>6}'.format(p['pid']) ret.append(self.curse_add_line(msg)) # USER if 'username' in p: # docker internal users are displayed as ints only, therefore str() # Correct issue #886 on Windows OS msg = ' {:9}'.format(str(p['username'])[:9]) ret.append(self.curse_add_line(msg)) else: msg = ' {:9}'.format('?') ret.append(self.curse_add_line(msg)) # NICE if 'nice' in p: nice = p['nice'] if nice is None: nice = '?' msg = '{:>5}'.format(nice) if isinstance(nice, int) and ((WINDOWS and nice != 32) or (not WINDOWS and nice != 0)): ret.append(self.curse_add_line(msg, decoration='NICE')) else: ret.append(self.curse_add_line(msg)) else: msg = '{:>5}'.format('?') ret.append(self.curse_add_line(msg)) # STATUS if 'status' in p: status = p['status'] msg = '{:>2}'.format(status) if status == 'R': ret.append(self.curse_add_line(msg, decoration='STATUS')) else: ret.append(self.curse_add_line(msg)) else: msg = '{:>2}'.format('?') ret.append(self.curse_add_line(msg)) # TIME+ if self.tag_proc_time: try: delta = timedelta(seconds=sum(p['cpu_times'])) except (OverflowError, TypeError) as e: # Catch OverflowError on some Amazon EC2 server # See https://github.com/nicolargo/glances/issues/87 # Also catch TypeError on Mac OS X # See: https://github.com/nicolargo/glances/issues/622 logger.debug("Cannot get TIME+ ({})".format(e)) self.tag_proc_time = False else: hours, minutes, seconds, microseconds = convert_timedelta( delta) if hours: msg = '{:>4}h'.format(hours) ret.append( self.curse_add_line(msg, decoration='CPU_TIME', optional=True)) msg = '{}:{}'.format(str(minutes).zfill(2), seconds) else: msg = '{:>4}:{}.{}'.format(minutes, seconds, microseconds) else: msg = '{:>10}'.format('?') ret.append(self.curse_add_line(msg, optional=True)) # IO read/write if 'io_counters' in p: # IO read io_rs = int((p['io_counters'][0] - p['io_counters'][2]) / p['time_since_update']) if io_rs == 0: msg = '{:>6}'.format("0") else: msg = '{:>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 = int((p['io_counters'][1] - p['io_counters'][3]) / p['time_since_update']) if io_ws == 0: msg = '{:>6}'.format("0") else: msg = '{:>6}'.format(self.auto_unit(io_ws, low_precision=True)) ret.append(self.curse_add_line(msg, optional=True, additional=True)) else: msg = '{:>6}'.format("?") ret.append(self.curse_add_line(msg, optional=True, additional=True)) ret.append(self.curse_add_line(msg, optional=True, additional=True)) # Command line # If no command line for the process is available, fallback to # the bare process name instead cmdline = p['cmdline'] try: # XXX: remove `cmdline != ['']` when we'll drop support for psutil<4.0.0 if cmdline and cmdline != ['']: path, cmd, arguments = split_cmdline(cmdline) if os.path.isdir(path) and not args.process_short_name: msg = ' {}'.format(path) + os.sep ret.append(self.curse_add_line(msg, splittable=True)) if glances_processes.is_tree_enabled(): # mark position to add tree decoration ret[-1]["_tree_decoration"] = True ret.append( self.curse_add_line(cmd, decoration='PROCESS', splittable=True)) else: msg = ' {}'.format(cmd) ret.append( self.curse_add_line(msg, decoration='PROCESS', splittable=True)) if glances_processes.is_tree_enabled(): # mark position to add tree decoration ret[-1]["_tree_decoration"] = True if arguments: msg = ' {}'.format(arguments) ret.append(self.curse_add_line(msg, splittable=True)) else: msg = ' {}'.format(p['name']) ret.append(self.curse_add_line(msg, splittable=True)) except UnicodeEncodeError: ret.append(self.curse_add_line('', splittable=True)) # Add extended stats but only for the top processes # !!! CPU consumption ??? # TODO: extended stats into the web interface if first and 'extended_stats' in p: # Left padding xpad = ' ' * 13 # First line is CPU affinity if 'cpu_affinity' in p and p['cpu_affinity'] is not None: ret.append(self.curse_new_line()) msg = xpad + 'CPU affinity: ' + str(len( p['cpu_affinity'])) + ' cores' ret.append(self.curse_add_line(msg, splittable=True)) # Second line is memory info if 'memory_info' in p and p['memory_info'] is not None: ret.append(self.curse_new_line()) msg = xpad + 'Memory info: ' for k, v in iteritems(p['memory_info']._asdict()): # Ignore rss and vms (already displayed) if k not in ['rss', 'vms'] and v is not None: msg += k + ' ' + self.auto_unit( v, low_precision=False) + ' ' if 'memory_swap' in p and p['memory_swap'] is not None: msg += 'swap ' + self.auto_unit(p['memory_swap'], low_precision=False) ret.append(self.curse_add_line(msg, splittable=True)) # Third line is for open files/network sessions msg = '' if 'num_threads' in p and p['num_threads'] is not None: msg += 'threads ' + str(p['num_threads']) + ' ' if 'num_fds' in p and p['num_fds'] is not None: msg += 'files ' + str(p['num_fds']) + ' ' if 'num_handles' in p and p['num_handles'] is not None: msg += 'handles ' + str(p['num_handles']) + ' ' if 'tcp' in p and p['tcp'] is not None: msg += 'TCP ' + str(p['tcp']) + ' ' if 'udp' in p and p['udp'] is not None: msg += 'UDP ' + str(p['udp']) + ' ' if msg != '': ret.append(self.curse_new_line()) msg = xpad + 'Open: ' + msg ret.append(self.curse_add_line(msg, splittable=True)) # Fouth line is IO nice level (only Linux and Windows OS) if 'ionice' in p and p['ionice'] is not None: ret.append(self.curse_new_line()) msg = xpad + 'IO nice: ' k = 'Class is ' v = p['ionice'].ioclass # Linux: The scheduling class. 0 for none, 1 for real time, 2 for best-effort, 3 for idle. # Windows: On Windows only ioclass is used and it can be set to 2 (normal), 1 (low) or 0 (very low). if WINDOWS: if v == 0: msg += k + 'Very Low' elif v == 1: msg += k + 'Low' elif v == 2: msg += 'No specific I/O priority' else: msg += k + str(v) else: if v == 0: msg += 'No specific I/O priority' elif v == 1: msg += k + 'Real Time' elif v == 2: msg += k + 'Best Effort' elif v == 3: msg += k + 'IDLE' else: msg += k + str(v) # value is a number which goes from 0 to 7. # The higher the value, the lower the I/O priority of the process. if hasattr(p['ionice'], 'value') and p['ionice'].value != 0: msg += ' (value %s/7)' % str(p['ionice'].value) ret.append(self.curse_add_line(msg, splittable=True)) return ret
def msg_curse(self, args=None): """Return the dict to display in the curse interface.""" # Init the return message ret = [] # Only process if stats exist and display plugin enable... if args.disable_process: msg = "PROCESSES DISABLED (press 'z' to display)" ret.append(self.curse_add_line(msg)) return ret if not self.stats: return ret # Display the filter (if it exists) if glances_processes.process_filter is not None: msg = 'Processes filter:' ret.append(self.curse_add_line(msg, "TITLE")) msg = ' {} '.format(glances_processes.process_filter) if glances_processes.process_filter_key is not None: msg += 'on column {} '.format(glances_processes.process_filter_key) ret.append(self.curse_add_line(msg, "FILTER")) msg = '(\'ENTER\' to edit, \'E\' to reset)' ret.append(self.curse_add_line(msg)) ret.append(self.curse_new_line()) # Build the string message # Header msg = 'TASKS' ret.append(self.curse_add_line(msg, "TITLE")) # Compute processes other = self.stats['total'] msg = '{:>4}'.format(self.stats['total']) ret.append(self.curse_add_line(msg)) if 'thread' in self.stats: msg = ' ({} thr),'.format(self.stats['thread']) ret.append(self.curse_add_line(msg)) if 'running' in self.stats: other -= self.stats['running'] msg = ' {} run,'.format(self.stats['running']) ret.append(self.curse_add_line(msg)) if 'sleeping' in self.stats: other -= self.stats['sleeping'] msg = ' {} slp,'.format(self.stats['sleeping']) ret.append(self.curse_add_line(msg)) msg = ' {} oth '.format(other) ret.append(self.curse_add_line(msg)) # Display sort information if glances_processes.auto_sort: msg = 'sorted automatically' ret.append(self.curse_add_line(msg)) msg = ' by {}'.format(glances_processes.sort_key) ret.append(self.curse_add_line(msg)) else: msg = 'sorted by {}'.format(glances_processes.sort_key) ret.append(self.curse_add_line(msg)) ret[-1]["msg"] += ", %s view" % ("tree" if glances_processes.is_tree_enabled() else "flat") # if args.disable_irix: # ret[-1]["msg"] += " - IRIX off" # Return the message with decoration return ret
def __sort_stats(self, sortedby=None): """Return the stats (dict) sorted by (sortedby)""" return sort_stats(self.stats, sortedby, tree=glances_processes.is_tree_enabled(), reverse=glances_processes.sort_reverse)
def get_process_curses_data(self, p, first, args): """Get curses data to display for a process. - p is the process to display - first is a tag=True if the process is the first on the list """ ret = [self.curse_new_line()] # CPU if 'cpu_percent' in p and p['cpu_percent'] is not None and p['cpu_percent'] != '': if args.disable_irix and self.nb_log_core != 0: msg = '{:>6.1f}'.format(p['cpu_percent'] / float(self.nb_log_core)) else: msg = '{:>6.1f}'.format(p['cpu_percent']) alert = self.get_alert(p['cpu_percent'], highlight_zero=False, is_max=(p['cpu_percent'] == self.max_values['cpu_percent']), header="cpu") ret.append(self.curse_add_line(msg, alert)) else: msg = '{:>6}'.format('?') ret.append(self.curse_add_line(msg)) # MEM if 'memory_percent' in p and p['memory_percent'] is not None and p['memory_percent'] != '': msg = '{:>6.1f}'.format(p['memory_percent']) alert = self.get_alert(p['memory_percent'], highlight_zero=False, is_max=(p['memory_percent'] == self.max_values['memory_percent']), header="mem") ret.append(self.curse_add_line(msg, alert)) else: msg = '{:>6}'.format('?') ret.append(self.curse_add_line(msg)) # VMS/RSS if 'memory_info' in p and p['memory_info'] is not None and p['memory_info'] != '': # VMS msg = '{:>6}'.format(self.auto_unit(p['memory_info'][1], low_precision=False)) ret.append(self.curse_add_line(msg, optional=True)) # RSS msg = '{:>6}'.format(self.auto_unit(p['memory_info'][0], low_precision=False)) ret.append(self.curse_add_line(msg, optional=True)) else: msg = '{:>6}'.format('?') ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg)) # PID msg = '{:>{width}}'.format(p['pid'], width=self.__max_pid_size() + 1) ret.append(self.curse_add_line(msg)) # USER if 'username' in p: # docker internal users are displayed as ints only, therefore str() # Correct issue #886 on Windows OS msg = ' {:9}'.format(str(p['username'])[:9]) ret.append(self.curse_add_line(msg)) else: msg = ' {:9}'.format('?') ret.append(self.curse_add_line(msg)) # NICE if 'nice' in p: nice = p['nice'] if nice is None: nice = '?' msg = '{:>5}'.format(nice) if isinstance(nice, int) and ((WINDOWS and nice != 32) or (not WINDOWS and nice != 0)): ret.append(self.curse_add_line(msg, decoration='NICE')) else: ret.append(self.curse_add_line(msg)) else: msg = '{:>5}'.format('?') ret.append(self.curse_add_line(msg)) # STATUS if 'status' in p: status = p['status'] msg = '{:>2}'.format(status) if status == 'R': ret.append(self.curse_add_line(msg, decoration='STATUS')) else: ret.append(self.curse_add_line(msg)) else: msg = '{:>2}'.format('?') ret.append(self.curse_add_line(msg)) # TIME+ if self.tag_proc_time: try: delta = timedelta(seconds=sum(p['cpu_times'])) except (OverflowError, TypeError) as e: # Catch OverflowError on some Amazon EC2 server # See https://github.com/nicolargo/glances/issues/87 # Also catch TypeError on macOS # See: https://github.com/nicolargo/glances/issues/622 logger.debug("Cannot get TIME+ ({})".format(e)) self.tag_proc_time = False else: hours, minutes, seconds, microseconds = convert_timedelta(delta) if hours: msg = '{:>4}h'.format(hours) ret.append(self.curse_add_line(msg, decoration='CPU_TIME', optional=True)) msg = '{}:{}'.format(str(minutes).zfill(2), seconds) else: msg = '{:>4}:{}.{}'.format(minutes, seconds, microseconds) else: msg = '{:>10}'.format('?') ret.append(self.curse_add_line(msg, optional=True)) # IO read/write if 'io_counters' in p: # IO read io_rs = int((p['io_counters'][0] - p['io_counters'][2]) / p['time_since_update']) if io_rs == 0: msg = '{:>6}'.format("0") else: msg = '{:>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 = int((p['io_counters'][1] - p['io_counters'][3]) / p['time_since_update']) if io_ws == 0: msg = '{:>6}'.format("0") else: msg = '{:>6}'.format(self.auto_unit(io_ws, low_precision=True)) ret.append(self.curse_add_line(msg, optional=True, additional=True)) else: msg = '{:>6}'.format("?") ret.append(self.curse_add_line(msg, optional=True, additional=True)) ret.append(self.curse_add_line(msg, optional=True, additional=True)) # Command line # If no command line for the process is available, fallback to # the bare process name instead cmdline = p['cmdline'] try: # XXX: remove `cmdline != ['']` when we'll drop support for psutil<4.0.0 if cmdline and cmdline != ['']: path, cmd, arguments = split_cmdline(cmdline) if os.path.isdir(path) and not args.process_short_name: msg = ' {}'.format(path) + os.sep ret.append(self.curse_add_line(msg, splittable=True)) if glances_processes.is_tree_enabled(): # mark position to add tree decoration ret[-1]["_tree_decoration"] = True ret.append(self.curse_add_line(cmd, decoration='PROCESS', splittable=True)) else: msg = ' {}'.format(cmd) ret.append(self.curse_add_line(msg, decoration='PROCESS', splittable=True)) if glances_processes.is_tree_enabled(): # mark position to add tree decoration ret[-1]["_tree_decoration"] = True if arguments: msg = ' {}'.format(arguments) ret.append(self.curse_add_line(msg, splittable=True)) else: msg = ' {}'.format(p['name']) ret.append(self.curse_add_line(msg, splittable=True)) except UnicodeEncodeError: ret.append(self.curse_add_line('', splittable=True)) # Add extended stats but only for the top processes # !!! CPU consumption ??? # TODO: extended stats into the web interface if first and 'extended_stats' in p: # Left padding xpad = ' ' * 13 # First line is CPU affinity if 'cpu_affinity' in p and p['cpu_affinity'] is not None: ret.append(self.curse_new_line()) msg = xpad + 'CPU affinity: ' + str(len(p['cpu_affinity'])) + ' cores' ret.append(self.curse_add_line(msg, splittable=True)) # Second line is memory info if 'memory_info' in p and p['memory_info'] is not None: ret.append(self.curse_new_line()) msg = xpad + 'Memory info: ' for k, v in iteritems(p['memory_info']._asdict()): # Ignore rss and vms (already displayed) if k not in ['rss', 'vms'] and v is not None: msg += k + ' ' + self.auto_unit(v, low_precision=False) + ' ' if 'memory_swap' in p and p['memory_swap'] is not None: msg += 'swap ' + self.auto_unit(p['memory_swap'], low_precision=False) ret.append(self.curse_add_line(msg, splittable=True)) # Third line is for open files/network sessions msg = '' if 'num_threads' in p and p['num_threads'] is not None: msg += 'threads ' + str(p['num_threads']) + ' ' if 'num_fds' in p and p['num_fds'] is not None: msg += 'files ' + str(p['num_fds']) + ' ' if 'num_handles' in p and p['num_handles'] is not None: msg += 'handles ' + str(p['num_handles']) + ' ' if 'tcp' in p and p['tcp'] is not None: msg += 'TCP ' + str(p['tcp']) + ' ' if 'udp' in p and p['udp'] is not None: msg += 'UDP ' + str(p['udp']) + ' ' if msg != '': ret.append(self.curse_new_line()) msg = xpad + 'Open: ' + msg ret.append(self.curse_add_line(msg, splittable=True)) # Fouth line is IO nice level (only Linux and Windows OS) if 'ionice' in p and p['ionice'] is not None: ret.append(self.curse_new_line()) msg = xpad + 'IO nice: ' k = 'Class is ' v = p['ionice'].ioclass # Linux: The scheduling class. 0 for none, 1 for real time, 2 for best-effort, 3 for idle. # Windows: On Windows only ioclass is used and it can be set to 2 (normal), 1 (low) or 0 (very low). if WINDOWS: if v == 0: msg += k + 'Very Low' elif v == 1: msg += k + 'Low' elif v == 2: msg += 'No specific I/O priority' else: msg += k + str(v) else: if v == 0: msg += 'No specific I/O priority' elif v == 1: msg += k + 'Real Time' elif v == 2: msg += k + 'Best Effort' elif v == 3: msg += k + 'IDLE' else: msg += k + str(v) # value is a number which goes from 0 to 7. # The higher the value, the lower the I/O priority of the process. if hasattr(p['ionice'], 'value') and p['ionice'].value != 0: msg += ' (value %s/7)' % str(p['ionice'].value) ret.append(self.curse_add_line(msg, splittable=True)) return ret
def msg_curse(self, args=None): """Return the dict to display in the curse interface.""" # Init the return message ret = [] # Only process if stats exist and display plugin enable... if args.disable_process: msg = "PROCESSES DISABLED (press 'z' to display)" ret.append(self.curse_add_line(msg)) return ret if not self.stats: return ret # Display the filter (if it exists) if glances_processes.process_filter is not None: msg = 'Processes filter:' ret.append(self.curse_add_line(msg, "TITLE")) msg = ' {} '.format(glances_processes.process_filter) if glances_processes.process_filter_key is not None: msg += 'on column {} '.format( glances_processes.process_filter_key) ret.append(self.curse_add_line(msg, "FILTER")) msg = '(\'ENTER\' to edit, \'E\' to reset)' ret.append(self.curse_add_line(msg)) ret.append(self.curse_new_line()) # Build the string message # Header msg = 'TASKS' ret.append(self.curse_add_line(msg, "TITLE")) # Compute processes other = self.stats['total'] msg = '{:>4}'.format(self.stats['total']) ret.append(self.curse_add_line(msg)) if 'thread' in self.stats: msg = ' ({} thr),'.format(self.stats['thread']) ret.append(self.curse_add_line(msg)) if 'running' in self.stats: other -= self.stats['running'] msg = ' {} run,'.format(self.stats['running']) ret.append(self.curse_add_line(msg)) if 'sleeping' in self.stats: other -= self.stats['sleeping'] msg = ' {} slp,'.format(self.stats['sleeping']) ret.append(self.curse_add_line(msg)) msg = ' {} oth '.format(other) ret.append(self.curse_add_line(msg)) # Display sort information if glances_processes.auto_sort: msg = 'sorted automatically' ret.append(self.curse_add_line(msg)) msg = ' by {}'.format(glances_processes.sort_key) ret.append(self.curse_add_line(msg)) else: msg = 'sorted by {}'.format(glances_processes.sort_key) ret.append(self.curse_add_line(msg)) ret[-1]["msg"] += ", %s view" % ( "tree" if glances_processes.is_tree_enabled() else "flat") # if args.disable_irix: # ret[-1]["msg"] += " - IRIX off" # Return the message with decoration return ret