def get_stats_display_width(self, curse_msg, without_option=False): """Return the width of the formatted curses message.""" try: if without_option: # Size without options c = len( max(''.join([ (u(u(nativestr(i['msg'])).encode('ascii', 'replace')) if not i['optional'] else "") for i in curse_msg['msgdict'] ]).split('\n'), key=len)) else: # Size with all options c = len( max(''.join([ u(u(nativestr(i['msg'])).encode('ascii', 'replace')) for i in curse_msg['msgdict'] ]).split('\n'), key=len)) except Exception as e: logger.debug('ERROR: Can not compute plugin width ({})'.format(e)) return 0 else: return c
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 # Build the string message for m in self.stats: msg = '{0:<16} '.format(m['description']) ret.append(self.curse_add_line( msg, self.get_alert(m['count'], m['countmin'], m['countmax']))) msg = '{0:<3} '.format(m['count'] if m['count'] > 1 else '') ret.append(self.curse_add_line(msg)) msg = '{0:13} '.format('RUNNING' if m['count'] >= 1 else 'NOT RUNNING') ret.append(self.curse_add_line(msg)) # Decode to UTF-8 (for Python 2) try: msg = u(m['result']) if m['count'] >= 1 else '' except UnicodeEncodeError: # Hack if return message contains non UTF-8 compliant char msg = u(m['default_result']) if m['count'] >= 1 else '' ret.append(self.curse_add_line(msg, optional=True, splittable=True)) ret.append(self.curse_new_line()) # Delete the last empty line try: ret.pop() except IndexError: pass return ret
def set_result(self, result, separator=''): """Store the result (string) into the result key of the AMP if one_line is true then replace \n by separator """ if self.one_line(): self.configs['result'] = u(result).replace('\n', separator) else: self.configs['result'] = u(result)
def update(self, process_list): """Update the AMP""" # Get the systemctl status logger.debug('{}: Update AMP stats using command {}'.format( self.NAME, self.get('service_cmd'))) # Get command to execute try: res = self.get('command') except OSError as e: logger.debug('{}: Error while executing command ({})'.format( self.NAME, e)) return self.result() # No command found, use default message if res is None: # Set the default message if command return None # Default sum of CPU and MEM for the matching regex self.set_result('CPU: {:.1f}% | MEM: {:.1f}%'.format( sum([p['cpu_percent'] for p in process_list]), sum([p['memory_percent'] for p in process_list]))) return self.result() # Run command(s) # Comman separated commands can be executed try: msg = '' for cmd in res.split(';'): msg += u(check_output(cmd.split(), stderr=STDOUT)) self.set_result(to_ascii(msg.rstrip())) except CalledProcessError as e: self.set_result(e.output) return self.result()
def update(self, process_list): """Update the AMP""" # Get the systemctl status logger.debug('{}: Update AMP stats using service {}'.format( self.NAME, self.get('service_cmd'))) try: res = self.get('command') except OSError as e: logger.debug('{}: Error while executing service ({})'.format( self.NAME, e)) else: if res is not None: try: msg = u(check_output(res.split(), stderr=STDOUT)) self.set_result(to_ascii(msg.rstrip())) except CalledProcessError as e: self.set_result(e.output) else: # Set the default message if command return None # Default sum of CPU and MEM for the matching regex self.set_result('CPU: {:.1f}% | MEM: {:.1f}%'.format( sum([p['cpu_percent'] for p in process_list]), sum([p['memory_percent'] for p in process_list]))) return self.result()
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 # Build the string message for m in self.stats: msg = '{0:<16} '.format(m['description']) ret.append( self.curse_add_line( msg, self.get_alert(m['count'], m['countmin'], m['countmax']))) msg = '{0:<3} '.format(m['count'] if m['count'] > 1 else '') ret.append(self.curse_add_line(msg)) msg = '{0:13} '.format( 'RUNNING' if m['count'] >= 1 else 'NOT RUNNING') ret.append(self.curse_add_line(msg)) # Decode to UTF-8 (for Python 2) try: msg = u(m['result']) if m['count'] >= 1 else '' except UnicodeEncodeError: # Hack if return message contains non UTF-8 compliant char msg = u(m['default_result']) if m['count'] >= 1 else '' ret.append(self.curse_add_line(msg, optional=True, splittable=True)) ret.append(self.curse_new_line()) # Delete the last empty line try: ret.pop() except IndexError: pass return ret
def update(self): """Update the command result attributed.""" # Only continue if monitor list is not empty if len(self.__monitor_list) == 0: return self.__monitor_list # Search monitored processes by a regular expression processlist = [p for p in glances_processes.getalllist()] # Iter upon the monitored list for i in range(len(self.get())): monitoredlist = [ p for p in processlist for c in p['cmdline'] if re.search(self.regex(i), c) is not None ] self.__monitor_list[i]['count'] = len(monitoredlist) # Always get processes CPU and MEM self.__monitor_list[i][ 'default_result'] = 'CPU: {0:.1f}% | MEM: {1:.1f}%'.format( sum([p['cpu_percent'] for p in monitoredlist]), sum([p['memory_percent'] for p in monitoredlist])) if self.command(i) is not None: # Execute the user command line try: self.__monitor_list[i]['result'] = subprocess.check_output( self.command(i), shell=True) except subprocess.CalledProcessError: self.__monitor_list[i][ 'result'] = 'Error: ' + self.command(i) except Exception: self.__monitor_list[i]['result'] = 'Cannot execute command' # Only save the first line try: self.__monitor_list[i]['result'] = u( self.__monitor_list[i]['result']).split('\n')[0] except: self.__monitor_list[i]['result'] = '' if self.command( i) is None or self.__monitor_list[i]['result'] == '': # If there is no command specified in the conf file # then display CPU and MEM % self.__monitor_list[i]['result'] = self.__monitor_list[i][ 'default_result'] return self.__monitor_list
def update(self, process_list): """Update the AMP""" # Get the systemctl status logger.debug('{}: Update stats using service {}'.format(self.NAME, self.get('service_cmd'))) try: res = self.get('command') except OSError as e: logger.debug('{}: Error while executing service ({})'.format(self.NAME, e)) else: if res is not None: msg = u(check_output(res.split(), stderr=STDOUT)) self.set_result(to_ascii(msg.rstrip())) else: # Set the default message if command return None # Default sum of CPU and MEM for the matching regex self.set_result('CPU: {:.1f}% | MEM: {:.1f}%'.format( sum([p['cpu_percent'] for p in process_list]), sum([p['memory_percent'] for p in process_list]))) return self.result()
def update(self): """Update the command result attributed.""" # Only continue if monitor list is not empty if len(self.__monitor_list) == 0: return self.__monitor_list # Search monitored processes by a regular expression processlist = [p for p in glances_processes.getalllist()] # Iter upon the monitored list for i in range(len(self.get())): monitoredlist = [p for p in processlist for c in p["cmdline"] if re.search(self.regex(i), c) is not None] self.__monitor_list[i]["count"] = len(monitoredlist) # Always get processes CPU and MEM self.__monitor_list[i]["default_result"] = "CPU: {0:.1f}% | MEM: {1:.1f}%".format( sum([p["cpu_percent"] for p in monitoredlist]), sum([p["memory_percent"] for p in monitoredlist]) ) if self.command(i) is not None: # Execute the user command line try: self.__monitor_list[i]["result"] = subprocess.check_output(self.command(i), shell=True) except subprocess.CalledProcessError: self.__monitor_list[i]["result"] = "Error: " + self.command(i) except Exception: self.__monitor_list[i]["result"] = "Cannot execute command" # Only save the first line try: self.__monitor_list[i]["result"] = u(self.__monitor_list[i]["result"]).split("\n")[0] except: self.__monitor_list[i]["result"] = "" if self.command(i) is None or self.__monitor_list[i]["result"] == "": # If there is no command specified in the conf file # then display CPU and MEM % self.__monitor_list[i]["result"] = self.__monitor_list[i]["default_result"] return self.__monitor_list
def display_plugin(self, plugin_stats, display_optional=True, display_additional=True, max_y=65535, add_space=0): """Display the plugin_stats on the screen. If display_optional=True display the optional stats If display_additional=True display additionnal stats max_y: do not display line > max_y add_space: add x space (line) after the plugin """ # Exit if: # - the plugin_stats message is empty # - the display tag = False if plugin_stats is None or not plugin_stats['msgdict'] or not plugin_stats['display']: # Exit return 0 # Get the screen size screen_x = self.screen.getmaxyx()[1] screen_y = self.screen.getmaxyx()[0] # Set the upper/left position of the message if plugin_stats['align'] == 'right': # Right align (last column) display_x = screen_x - self.get_stats_display_width(plugin_stats) else: display_x = self.column if plugin_stats['align'] == 'bottom': # Bottom (last line) display_y = screen_y - self.get_stats_display_height(plugin_stats) else: display_y = self.line # Display x = display_x x_max = x y = display_y for m in plugin_stats['msgdict']: # New line if m['msg'].startswith('\n'): # Go to the next line y += 1 # Return to the first column x = display_x continue # Do not display outside the screen if x < 0: continue if not m['splittable'] and (x + len(m['msg']) > screen_x): continue if y < 0 or (y + 1 > screen_y) or (y > max_y): break # If display_optional = False do not display optional stats if not display_optional and m['optional']: continue # If display_additional = False do not display additional stats if not display_additional and m['additional']: continue # Is it possible to display the stat with the current screen size # !!! Crach if not try/except... Why ??? try: self.term_window.addnstr(y, x, m['msg'], # Do not disply outside the screen screen_x - x, self.colors_list[m['decoration']]) except Exception: pass else: # New column # Python 2: we need to decode to get real screen size because # UTF-8 special tree chars occupy several bytes. # Python 3: strings are strings and bytes are bytes, all is # good. try: x += len(u(m['msg'])) except UnicodeDecodeError: # Quick and dirty hack for issue #745 pass if x > x_max: x_max = x # Compute the next Glances column/line position 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) # Have empty lines after the plugins self.next_line += add_space
def result(self): """ Return the result of the AMP (as a string)""" ret = self.get('result') if ret is not None: ret = u(ret) return ret
def update(self): """Update the FS stats using the input method.""" # Reset the list self.reset() if self.input_method == 'local': # Update stats using the standard system lib # Grab the stats using the PsUtil disk_partitions # If 'all'=False return physical devices only (e.g. hard disks, cd-rom drives, USB keys) # and ignore all others (e.g. memory partitions such as /dev/shm) try: fs_stat = psutil.disk_partitions(all=False) except UnicodeDecodeError: return self.stats # Optionnal hack to allow logicals mounts points (issue #448) # Ex: Had to put 'allow=zfs' in the [fs] section of the conf file # to allow zfs monitoring for fstype in self.get_conf_value('allow'): try: fs_stat += [ f for f in psutil.disk_partitions(all=True) if f.fstype.find(fstype) >= 0 ] except UnicodeDecodeError: return self.stats # Loop over fs for fs in fs_stat: # Do not take hidden file system into account if self.is_hide(fs.mountpoint): continue # Grab the disk usage try: fs_usage = psutil.disk_usage(fs.mountpoint) except OSError: # Correct issue #346 # Disk is ejected during the command continue fs_current = { 'device_name': fs.device, 'fs_type': fs.fstype, # Manage non breaking space (see issue #1065) 'mnt_point': u(fs.mountpoint).replace(u'\u00A0', ' '), 'size': fs_usage.total, 'used': fs_usage.used, 'free': fs_usage.free, 'percent': fs_usage.percent, 'key': self.get_key() } self.stats.append(fs_current) elif self.input_method == 'snmp': # Update stats using SNMP # SNMP bulk command to get all file system in one shot try: fs_stat = self.get_stats_snmp( snmp_oid=snmp_oid[self.short_system_name], bulk=True) except KeyError: fs_stat = self.get_stats_snmp(snmp_oid=snmp_oid['default'], bulk=True) # Loop over fs if self.short_system_name in ('windows', 'esxi'): # Windows or ESXi tips for fs in fs_stat: # Memory stats are grabbed in the same OID table (ignore it) if fs == 'Virtual Memory' or fs == 'Physical Memory' or fs == 'Real Memory': continue size = int(fs_stat[fs]['size']) * int( fs_stat[fs]['alloc_unit']) used = int(fs_stat[fs]['used']) * int( fs_stat[fs]['alloc_unit']) percent = float(used * 100 / size) fs_current = { 'device_name': '', 'mnt_point': fs.partition(' ')[0], 'size': size, 'used': used, 'percent': percent, 'key': self.get_key() } self.stats.append(fs_current) else: # Default behavior for fs in fs_stat: fs_current = { 'device_name': fs_stat[fs]['device_name'], 'mnt_point': fs, 'size': int(fs_stat[fs]['size']) * 1024, 'used': int(fs_stat[fs]['used']) * 1024, 'percent': float(fs_stat[fs]['percent']), 'key': self.get_key() } self.stats.append(fs_current) return self.stats
def update(self): """Update the FS stats using the input method.""" # Init new stats stats = self.get_init_value() if self.input_method == 'local': # Update stats using the standard system lib # Grab the stats using the psutil disk_partitions # If 'all'=False return physical devices only (e.g. hard disks, cd-rom drives, USB keys) # and ignore all others (e.g. memory partitions such as /dev/shm) try: fs_stat = psutil.disk_partitions(all=False) except UnicodeDecodeError: return self.stats # Optionnal hack to allow logicals mounts points (issue #448) # Ex: Had to put 'allow=zfs' in the [fs] section of the conf file # to allow zfs monitoring for fstype in self.get_conf_value('allow'): try: fs_stat += [f for f in psutil.disk_partitions(all=True) if f.fstype.find(fstype) >= 0] except UnicodeDecodeError: return self.stats # Loop over fs for fs in fs_stat: # Do not take hidden file system into account if self.is_hide(fs.mountpoint): continue # Grab the disk usage try: fs_usage = psutil.disk_usage(fs.mountpoint) except OSError: # Correct issue #346 # Disk is ejected during the command continue fs_current = { 'device_name': fs.device, 'fs_type': fs.fstype, # Manage non breaking space (see issue #1065) 'mnt_point': u(fs.mountpoint).replace(u'\u00A0', ' '), 'size': fs_usage.total, 'used': fs_usage.used, 'free': fs_usage.free, 'percent': fs_usage.percent, 'key': self.get_key()} stats.append(fs_current) elif self.input_method == 'snmp': # Update stats using SNMP # SNMP bulk command to get all file system in one shot try: fs_stat = self.get_stats_snmp(snmp_oid=snmp_oid[self.short_system_name], bulk=True) except KeyError: fs_stat = self.get_stats_snmp(snmp_oid=snmp_oid['default'], bulk=True) # Loop over fs if self.short_system_name in ('windows', 'esxi'): # Windows or ESXi tips for fs in fs_stat: # Memory stats are grabbed in the same OID table (ignore it) if fs == 'Virtual Memory' or fs == 'Physical Memory' or fs == 'Real Memory': continue size = int(fs_stat[fs]['size']) * int(fs_stat[fs]['alloc_unit']) used = int(fs_stat[fs]['used']) * int(fs_stat[fs]['alloc_unit']) percent = float(used * 100 / size) fs_current = { 'device_name': '', 'mnt_point': fs.partition(' ')[0], 'size': size, 'used': used, 'percent': percent, 'key': self.get_key()} stats.append(fs_current) else: # Default behavior for fs in fs_stat: fs_current = { 'device_name': fs_stat[fs]['device_name'], 'mnt_point': fs, 'size': int(fs_stat[fs]['size']) * 1024, 'used': int(fs_stat[fs]['used']) * 1024, 'percent': float(fs_stat[fs]['percent']), 'key': self.get_key()} stats.append(fs_current) # Update the stats self.stats = stats return self.stats