def __set_monitor_list(self, section, key): """Init the monitored processes list. The list is defined in the Glances configuration file. """ for l in range(1, self.__monitor_list_max_size + 1): value = {} key = "list_" + str(l) + "_" try: description = self.config.get_raw_option(section, key + "description") regex = self.config.get_raw_option(section, key + "regex") command = self.config.get_raw_option(section, key + "command") countmin = self.config.get_raw_option(section, key + "countmin") countmax = self.config.get_raw_option(section, key + "countmax") except Exception as e: logger.error(_("Cannot read monitored list: {0}").format(e)) pass else: if description is not None and regex is not None: # Build the new item value["description"] = description try: re.compile(regex) except: continue else: value["regex"] = regex value["command"] = command value["countmin"] = countmin value["countmax"] = countmax value["count"] = None value["result"] = None # Add the item to the list self.__monitor_list.append(value)
def __init__(self, config=None, args=None, timeout=7, return_to_browser=False): # Store the arg/config self.args = args self.config = config # Client mode: self.set_mode() # Build the URI if args.password != "": uri = 'http://{0}:{1}@{2}:{3}'.format(args.username, args.password, args.client, args.port) else: uri = 'http://{0}:{1}'.format(args.client, args.port) logger.debug("Try to connect to {0}".format(uri)) # Try to connect to the URI transport = GlancesClientTransport() # Configure the server timeout transport.set_timeout(timeout) try: self.client = ServerProxy(uri, transport=transport) except Exception as e: msg = "Client couldn't create socket {0}: {1}".format(uri, e) if not return_to_browser: logger.critical(msg) sys.exit(2) else: logger.error(msg)
def login(self): """Logon to the server.""" ret = True if not self.args.snmp_force: # First of all, trying to connect to a Glances server self.set_mode('glances') client_version = None try: client_version = self.client.init() except socket.error as err: # Fallback to SNMP logger.error(_("Connection to Glances server failed")) self.set_mode('snmp') fallbackmsg = _("Trying fallback to SNMP...") print(fallbackmsg) except ProtocolError as err: # Others errors if str(err).find(" 401 ") > 0: logger.error( _("Connection to server failed (Bad password)")) else: logger.error( _("Connection to server failed ({0})").format(err)) sys.exit(2) if self.get_mode( ) == 'glances' and version[:3] == client_version[:3]: # Init stats self.stats = GlancesStatsClient() self.stats.set_plugins(json.loads(self.client.getAllPlugins())) else: logger.error("Client version: %s / Server version: %s" % (version, client_version)) else: self.set_mode('snmp') if self.get_mode() == 'snmp': logger.info(_("Trying to grab stats by SNMP...")) # Fallback to SNMP if needed from glances.core.glances_stats import GlancesStatsClientSNMP # Init stats self.stats = GlancesStatsClientSNMP(args=self.args) if not self.stats.check_snmp(): logger.error(_("Connection to SNMP server failed")) sys.exit(2) if ret: # Load limits from the configuration file # Each client can choose its owns limits self.stats.load_limits(self.config) # Init screen self.screen = GlancesCurses(args=self.args) # Return result return ret
def __set_monitor_list(self, section, key): """Init the monitored processes list. The list is defined in the Glances configuration file. """ for l in range(1, self.__monitor_list_max_size + 1): value = {} key = "list_" + str(l) + "_" try: description = self.config.get_raw_option(section, key + "description") regex = self.config.get_raw_option(section, key + "regex") command = self.config.get_raw_option(section, key + "command") countmin = self.config.get_raw_option(section, key + "countmin") countmax = self.config.get_raw_option(section, key + "countmax") except Exception as e: logger.error("Cannot read monitored list: {0}".format(e)) pass else: if description is not None and regex is not None: # Build the new item value["description"] = description try: re.compile(regex) except Exception: continue else: value["regex"] = regex value["command"] = command value["countmin"] = countmin value["countmax"] = countmax value["count"] = None value["result"] = None # Add the item to the list self.__monitor_list.append(value)
def login(self): """Logon to the server.""" ret = True if not self.args.snmp_force: # First of all, trying to connect to a Glances server self.set_mode('glances') client_version = None try: client_version = self.client.init() except socket.error as err: # Fallback to SNMP logger.error(_("Connection to Glances server failed")) self.set_mode('snmp') fallbackmsg = _("Trying fallback to SNMP...") print(fallbackmsg) except ProtocolError as err: # Others errors if str(err).find(" 401 ") > 0: logger.error(_("Connection to server failed (Bad password)")) else: logger.error(_("Connection to server failed ({0})").format(err)) sys.exit(2) if self.get_mode() == 'glances' and version[:3] == client_version[:3]: # Init stats self.stats = GlancesStatsClient() self.stats.set_plugins(json.loads(self.client.getAllPlugins())) else: logger.error("Client version: %s / Server version: %s" % (version, client_version)) else: self.set_mode('snmp') if self.get_mode() == 'snmp': logger.info(_("Trying to grab stats by SNMP...")) # Fallback to SNMP if needed from glances.core.glances_stats import GlancesStatsClientSNMP # Init stats self.stats = GlancesStatsClientSNMP(args=self.args) if not self.stats.check_snmp(): logger.error(_("Connection to SNMP server failed")) sys.exit(2) if ret: # Load limits from the configuration file # Each client can choose its owns limits self.stats.load_limits(self.config) # Init screen self.screen = GlancesCurses(args=self.args) # Return result return ret
def update(self): """Update the stats using SNMP.""" # For each plugins, call the update method for p in self._plugins: # Set the input method to SNMP self._plugins[p].set_input('snmp', self.system_name) try: self._plugins[p].update() except Exception as e: logger.error(_("Error: Update {0} failed: {1}").format(p, e))
def update(self): """Update the stats using SNMP.""" # For each plugins, call the update method for p in self._plugins: # Set the input method to SNMP self._plugins[p].set_input('snmp', self.system_name) try: self._plugins[p].update() except Exception as e: logger.error(_("Error: Update {0} failed: {1}").format(p, e))
def __init__(self, bind_address, bind_port=61209, requestHandler=GlancesXMLRPCHandler): try: self.address_family = socket.getaddrinfo(bind_address, bind_port)[0][0] except socket.error as e: logger.error(_("Couldn't open socket: {0}").format(e)) sys.exit(1) SimpleXMLRPCServer.__init__(self, (bind_address, bind_port), requestHandler)
def remove_server(self, name): """Remove a server from the dict""" for i in self._server_list: if i['key'] == name: try: self._server_list.remove(i) logger.debug("Remove server %s from the list" % name) logger.debug("Updated servers list (%s servers): %s" % ( len(self._server_list), self._server_list)) except ValueError: logger.error( "Cannot remove server %s from the list" % name)
def set_process_filter(self, value): """Set the process filter""" logger.info(_("Set process filter to %s") % value) self.process_filter = value if value is not None: try: self.process_filter_re = re.compile(value) logger.debug(_("Process filter regular expression compilation OK: %s") % self.get_process_filter()) except: logger.error(_("Can not compile process filter regular expression: %s") % value) self.process_filter_re = None else: self.process_filter_re = None return self.process_filter
def __init__(self, bind_address, bind_port=61209, requestHandler=GlancesXMLRPCHandler): try: self.address_family = socket.getaddrinfo(bind_address, bind_port)[0][0] except socket.error as e: logger.error(_("Couldn't open socket: {0}").format(e)) sys.exit(1) SimpleXMLRPCServer.__init__(self, (bind_address, bind_port), requestHandler)
def save_password(self, hashed_password): """Save the hashed password to the Glances folder.""" # Check if the Glances folder already exists if not os.path.exists(self.password_path): # Create the Glances folder try: os.makedirs(self.password_path) except OSError as e: logger.error("Cannot create Glances directory: {0}".format(e)) return # Create/overwrite the password file with open(self.password_filepath, 'w') as file_pwd: file_pwd.write(hashed_password)
def set_process_filter(self, value): """Set the process filter""" logger.info("Set process filter to {0}".format(value)) self.process_filter = value if value is not None: try: self.process_filter_re = re.compile(value) logger.debug("Process filter regex compilation OK: {0}".format(self.get_process_filter())) except Exception: logger.error("Cannot compile process filter regex: {0}".format(value)) self.process_filter_re = None else: self.process_filter_re = None return self.process_filter
def get_stats_value(self, item, value): """ Return the stats object for a specific item=value (in JSON format) Stats should be a list of dict (processlist, network...) """ if type(self.stats) is not list: return None else: if value.isdigit(): value = int(value) try: return json.dumps({ value: [i for i in self.stats if i[item] == value] }) except (KeyError, ValueError) as e: logger.error(_("Can not get item(%s)=value(%s) (%s)") % (item, value,e)) return None
def save_password(self, hashed_password): """Save the hashed password to the Glances folder.""" # Check if the Glances folder already exists if not os.path.exists(self.password_path): # Create the Glances folder try: os.makedirs(self.password_path) except OSError as e: logger.error( _("Cannot create Glances directory: {0}").format(e)) return # Create/overwrite the password file with open(self.password_filepath, 'w') as file_pwd: file_pwd.write(hashed_password)
def __init__(self, args=None): if zeroconf_tag: logger.info("Init autodiscover mode (Zeroconf protocol)") try: self.zeroconf = Zeroconf() except socket.error as e: logger.error("Cannot start Zeroconf (%s)" % e) self.zeroconf_enable_tag = False else: self.listener = GlancesAutoDiscoverListener() self.browser = ServiceBrowser( self.zeroconf, zeroconf_type, self.listener) self.zeroconf_enable_tag = True else: logger.error("Cannot start autodiscover mode (Zeroconf lib is not installed)") self.zeroconf_enable_tag = False
def load(self): """Load a config file from the list of paths, if it exists.""" for config_file in self.get_config_paths(): if os.path.isfile(config_file) and os.path.getsize(config_file) > 0: try: if is_py3: self.parser.read(config_file, encoding='utf-8') else: self.parser.read(config_file) logger.info(_("Read configuration file %s") % config_file) except UnicodeDecodeError as e: logger.error(_("Cannot decode configuration file '{0}': {1}").format(config_file, e)) sys.exit(1) # Save the loaded configuration file path (issue #374) self._loaded_config_file = config_file break
def load(self): """Load a config file from the list of paths, if it exists.""" for config_file in self.get_config_paths(): if os.path.isfile(config_file) and os.path.getsize(config_file) > 0: try: if is_py3: self.parser.read(config_file, encoding='utf-8') else: self.parser.read(config_file) logger.info("Read configuration file '{0}'".format(config_file)) except UnicodeDecodeError as e: logger.error("Cannot decode configuration file '{0}': {1}".format(config_file, e)) sys.exit(1) # Save the loaded configuration file path (issue #374) self._loaded_config_file = config_file break
def load(self, config): """Load the server list from the configuration file""" server_list = [] if config is None: logger.warning("No configuration file available. Cannot load server list.") elif not config.has_section(self._section): logger.warning("No [%s] section in the configuration file. Cannot load server list." % self._section) else: logger.info("Start reading the [%s] section in the configuration file" % self._section) for i in range(1, 256): new_server = {} postfix = 'server_%s_' % str(i) # Read the server name (mandatory) for s in ['name', 'port', 'alias']: new_server[s] = config.get_raw_option(self._section, '%s%s' % (postfix, s)) if new_server['name'] is not None: # Manage optionnal information if new_server['port'] is None: new_server['port'] = 61209 new_server['username'] = '******' new_server['password'] = '' try: new_server['ip'] = gethostbyname(new_server['name']) except gaierror as e: logger.error("Cannot get IP address for server %s (%s)" % (new_server['name'], e)) continue new_server['key'] = new_server['name'] + ':' + new_server['port'] # Default status is 'UNKNOWN' new_server['status'] = 'UNKNOWN' # Server type is 'STATIC' new_server['type'] = 'STATIC' # Add the server to the list logger.debug("Add server %s to the static list" % new_server['name']) server_list.append(new_server) # Server list loaded logger.info("%s server(s) loaded from the configuration file" % len(server_list)) logger.debug("Static server list: %s" % server_list) return server_list
def set_process_filter(self, value): """Set the process filter""" logger.info(_("Set process filter to %s") % value) self.process_filter = value if value is not None: try: self.process_filter_re = re.compile(value) logger.debug( _("Process filter regular expression compilation OK: %s") % self.get_process_filter()) except: logger.error( _("Can not compile process filter regular expression: %s") % value) self.process_filter_re = None else: self.process_filter_re = None return self.process_filter
def __init__(self, requestHandler=GlancesXMLRPCHandler, cached_time=1, config=None, args=None): # Init the XML RPC server try: self.server = GlancesXMLRPCServer(args.bind_address, args.port, requestHandler) except Exception as e: logger.error(_("Cannot start Glances server: {0}").format(e)) sys.exit(2) # The users dict # username / password couple # By default, no auth is needed self.server.user_dict = {} self.server.isAuth = False # Register functions self.server.register_introspection_functions() self.server.register_instance(GlancesInstance(cached_time, config))
def get_stats_item(self, item): """ Return the stats object for a specific item (in JSON format) Stats should be a list of dict (processlist, network...) """ if type(self.stats) is not list: if type(self.stats) is dict: try: return json.dumps({ item: self.stats[item] }) except KeyError as e: logger.error(_("Can not get item %s (%s)") % (item, e)) else: return None else: try: # Source: http://stackoverflow.com/questions/4573875/python-get-index-of-dictionary-item-in-list return json.dumps({ item: map(itemgetter(item), self.stats) }) except (KeyError, ValueError) as e: logger.error(_("Can not get item %s (%s)") % (item, e)) return None
def __init__(self, hostname, args=None): if zeroconf_tag: zeroconf_bind_address = args.bind_address try: self.zeroconf = Zeroconf() except socket.error as e: logger.error("Cannot start zeroconf: {0}".format(e)) if netifaces_tag: # -B @ overwrite the dynamic IPv4 choice if zeroconf_bind_address == '0.0.0.0': zeroconf_bind_address = self.find_active_ip_address() else: logger.error("Couldn't find the active IP address: netifaces library not found.") logger.info("Announce the Glances server on the LAN (using {0} IP address)".format(zeroconf_bind_address)) print("Announce the Glances server on the LAN (using {0} IP address)".format(zeroconf_bind_address)) self.info = ServiceInfo( zeroconf_type, '{0}:{1}.{2}'.format(hostname, args.port, zeroconf_type), address=socket.inet_aton(zeroconf_bind_address), port=args.port, weight=0, priority=0, properties={}, server=hostname) self.zeroconf.register_service(self.info) else: logger.error("Cannot announce Glances server on the network: zeroconf library not found.")
def __init__(self, requestHandler=GlancesXMLRPCHandler, cached_time=1, config=None, args=None): # Init the XML RPC server try: self.server = GlancesXMLRPCServer(args.bind_address, args.port, requestHandler) except Exception as e: logger.error(_("Cannot start Glances server: {0}").format(e)) sys.exit(2) # The users dict # username / password couple # By default, no auth is needed self.server.user_dict = {} self.server.isAuth = False # Register functions self.server.register_introspection_functions() self.server.register_instance(GlancesInstance(cached_time, config))
def __init__(self, config=None, args=None): # Store the arg/config self.args = args self.config = config # Client mode: self.set_mode() # Build the URI if args.password != "": uri = 'http://{0}:{1}@{2}:{3}'.format(args.username, args.password, args.client, args.port) else: uri = 'http://{0}:{1}'.format(args.client, args.port) # Try to connect to the URI transport = GlancesClientTransport() # Configure the server timeout to 7 seconds transport.set_timeout(7) try: self.client = ServerProxy(uri, transport = transport) except Exception as e: logger.error(_("Couldn't create socket {0}: {1}").format(uri, e)) sys.exit(2)
def __init__(self, config=None, args=None): # Store the arg/config self.args = args self.config = config # Client mode: self.set_mode() # Build the URI if args.password != "": uri = 'http://{0}:{1}@{2}:{3}'.format(args.username, args.password, args.client, args.port) else: uri = 'http://{0}:{1}'.format(args.client, args.port) # Try to connect to the URI transport = GlancesClientTransport() # Configure the server timeout to 7 seconds transport.set_timeout(7) try: self.client = ServerProxy(uri, transport=transport) except Exception as e: logger.error(_("Couldn't create socket {0}: {1}").format(uri, e)) sys.exit(2)
def update(self): """Update sensors stats using the input method.""" # Reset the stats self.reset() if self.get_input() == 'local': # Update stats using the dedicated lib try: self.stats = self.__set_type(self.glancesgrabsensors.get(), 'temperature_core') except Exception as e: logger.error("Cannot grab sensors temperatures (%s)" % e) # Update HDDtemp stats try: hddtemp = self.__set_type(self.hddtemp_plugin.update(), 'temperature_hdd') except Exception as e: logger.error("Cannot grab HDD temperature (%s)" % e) else: # Append HDD temperature self.stats.extend(hddtemp) # Update batteries stats try: batpercent = self.__set_type(self.batpercent_plugin.update(), 'battery') except Exception as e: logger.error("Cannot grab battery percent (%s)" % e) else: # Append Batteries % self.stats.extend(batpercent) elif self.get_input() == 'snmp': # Update stats using SNMP # No standard: # http://www.net-snmp.org/wiki/index.php/Net-SNMP_and_lm-sensors_on_Ubuntu_10.04 pass return self.stats
def __init__(self, args=None): # Init args self.args = args # Init windows positions self.term_w = 80 self.term_h = 24 # Space between stats self.space_between_column = 3 self.space_between_line = 2 # Init the curses screen self.screen = curses.initscr() if not self.screen: logger.critical("Cannot init the curses library.\n") sys.exit(1) # Set curses options if hasattr(curses, 'start_color'): curses.start_color() if hasattr(curses, 'use_default_colors'): curses.use_default_colors() if hasattr(curses, 'noecho'): curses.noecho() if hasattr(curses, 'cbreak'): curses.cbreak() self.set_cursor(0) # Init colors self.hascolors = False if curses.has_colors() and curses.COLOR_PAIRS > 8: self.hascolors = True # FG color, BG color if args.theme_white: curses.init_pair(1, curses.COLOR_BLACK, -1) else: curses.init_pair(1, curses.COLOR_WHITE, -1) curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_RED) curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_GREEN) curses.init_pair(4, curses.COLOR_WHITE, curses.COLOR_BLUE) curses.init_pair(5, curses.COLOR_WHITE, curses.COLOR_MAGENTA) curses.init_pair(6, curses.COLOR_RED, -1) curses.init_pair(7, curses.COLOR_GREEN, -1) curses.init_pair(8, curses.COLOR_BLUE, -1) try: curses.init_pair(9, curses.COLOR_MAGENTA, -1) except Exception: if args.theme_white: curses.init_pair(9, curses.COLOR_BLACK, -1) else: curses.init_pair(9, curses.COLOR_WHITE, -1) try: curses.init_pair(10, curses.COLOR_CYAN, -1) except Exception: if args.theme_white: curses.init_pair(10, curses.COLOR_BLACK, -1) else: curses.init_pair(10, curses.COLOR_WHITE, -1) else: self.hascolors = False if args.disable_bold: A_BOLD = curses.A_BOLD else: A_BOLD = 0 self.title_color = A_BOLD self.title_underline_color = A_BOLD | curses.A_UNDERLINE self.help_color = A_BOLD if self.hascolors: # Colors text styles self.no_color = curses.color_pair(1) self.default_color = curses.color_pair(3) | A_BOLD self.nice_color = curses.color_pair(9) | A_BOLD self.ifCAREFUL_color = curses.color_pair(4) | A_BOLD self.ifWARNING_color = curses.color_pair(5) | A_BOLD self.ifCRITICAL_color = curses.color_pair(2) | A_BOLD self.default_color2 = curses.color_pair(7) | A_BOLD self.ifCAREFUL_color2 = curses.color_pair(8) | A_BOLD self.ifWARNING_color2 = curses.color_pair(9) | A_BOLD self.ifCRITICAL_color2 = curses.color_pair(6) | A_BOLD self.filter_color = curses.color_pair(10) | A_BOLD else: # B&W text styles self.no_color = curses.A_NORMAL self.default_color = curses.A_NORMAL self.nice_color = A_BOLD self.ifCAREFUL_color = curses.A_UNDERLINE self.ifWARNING_color = A_BOLD self.ifCRITICAL_color = curses.A_REVERSE self.default_color2 = curses.A_NORMAL self.ifCAREFUL_color2 = curses.A_UNDERLINE self.ifWARNING_color2 = A_BOLD self.ifCRITICAL_color2 = curses.A_REVERSE self.filter_color = A_BOLD # Define the colors list (hash table) for stats self.colors_list = { 'DEFAULT': self.no_color, 'UNDERLINE': curses.A_UNDERLINE, 'BOLD': A_BOLD, 'SORT': A_BOLD, 'OK': self.default_color2, 'FILTER': self.filter_color, 'TITLE': self.title_color, 'PROCESS': self.default_color2, 'STATUS': self.default_color2, 'NICE': self.nice_color, 'CAREFUL': self.ifCAREFUL_color2, 'WARNING': self.ifWARNING_color2, 'CRITICAL': self.ifCRITICAL_color2, 'OK_LOG': self.default_color, 'CAREFUL_LOG': self.ifCAREFUL_color, 'WARNING_LOG': self.ifWARNING_color, 'CRITICAL_LOG': self.ifCRITICAL_color } # Init main window self.term_window = self.screen.subwin(0, 0) # Init refresh time self.__refresh_time = args.time # Init process sort method self.args.process_sorted_by = 'auto' # Init edit filter tag self.edit_filter = False # Catch key pressed with non blocking mode self.term_window.keypad(1) self.term_window.nodelay(1) self.pressedkey = -1 # History tag self.reset_history_tag = False self.history_tag = False if args.enable_history: logger.info('Stats history enabled with output path %s' % args.path_history) from glances.outputs.glances_history import GlancesHistory self.glances_history = GlancesHistory(args.path_history) if not self.glances_history.graph_enabled(): args.enable_history = False logger.error( 'Stats history disabled because MatPlotLib is not installed')
def update(self): """ Update the processes stats """ # Reset the stats self.processlist = [] self.processcount = { 'total': 0, 'running': 0, 'sleeping': 0, 'thread': 0} # Do not process if disable tag is set if self.disable_tag: return # Get the time since last update time_since_update = getTimeSinceLastUpdate('process_disk') # Build an internal dict with only mandatories stats (sort keys) processdict = {} for proc in psutil.process_iter(): # Ignore kernel threads if needed if (self.no_kernel_threads and (not is_windows) # gids() is only available on unix and (proc.gids().real == 0)): continue # If self.get_max_processes() is None: Only retreive mandatory stats # Else: retreive mandatory and standard stats s = self.__get_process_stats(proc, mandatory_stats=True, standard_stats=self.get_max_processes() is None) # Continue to the next process if it has to be filtered if s is None or (self.is_filtered(s['cmdline']) and self.is_filtered(s['name'])): continue # Ok add the process to the list processdict[proc] = s # ignore the 'idle' process on Windows and *BSD # ignore the 'kernel_task' process on OS X # waiting for upstream patch from psutil if (is_bsd and processdict[proc]['name'] == 'idle' or is_windows and processdict[proc]['name'] == 'System Idle Process' or is_mac and processdict[proc]['name'] == 'kernel_task'): continue # Update processcount (global statistics) try: self.processcount[str(proc.status())] += 1 except KeyError: # Key did not exist, create it try: self.processcount[str(proc.status())] = 1 except psutil.NoSuchProcess: pass except psutil.NoSuchProcess: pass else: self.processcount['total'] += 1 # Update thread number (global statistics) try: self.processcount['thread'] += proc.num_threads() except Exception: pass if self._enable_tree: self.process_tree = ProcessTreeNode.build_tree(processdict, self.getsortkey(), self.no_kernel_threads) for i, node in enumerate(self.process_tree): # Only retreive stats for visible processes (get_max_processes) if (self.get_max_processes() is not None) and (i >= self.get_max_processes()): break # add standard stats new_stats = self.__get_process_stats(node.process, mandatory_stats=False, standard_stats=True, extended_stats=False) if new_stats is not None: node.stats.update(new_stats) # Add a specific time_since_update stats for bitrate node.stats['time_since_update'] = time_since_update else: # Process optimization # Only retreive stats for visible processes (get_max_processes) if self.get_max_processes() is not None: # Sort the internal dict and cut the top N (Return a list of tuple) # tuple=key (proc), dict (returned by __get_process_stats) try: processiter = sorted( processdict.items(), key=lambda x: x[1][self.getsortkey()], reverse=True) except (KeyError, TypeError) as e: logger.error("Cannot sort process list by %s (%s)" % (self.getsortkey(), e)) logger.error("%s" % str(processdict.items()[0])) # Fallback to all process (issue #423) processloop = processdict.items() first = False else: processloop = processiter[0:self.get_max_processes()] first = True else: # Get all processes stats processloop = processdict.items() first = False for i in processloop: # Already existing mandatory stats procstat = i[1] if self.get_max_processes() is not None: # Update with standard stats # and extended stats but only for TOP (first) process s = self.__get_process_stats(i[0], mandatory_stats=False, standard_stats=True, extended_stats=first) if s is None: continue procstat.update(s) # Add a specific time_since_update stats for bitrate procstat['time_since_update'] = time_since_update # Update process list self.processlist.append(procstat) # Next... first = False # Clean internals caches if timeout is reached if self.cache_timer.finished(): self.username_cache = {} self.cmdline_cache = {} # Restart the timer self.cache_timer.reset()
def __init__(self, args=None): # Init args self.args = args # Init windows positions self.term_w = 80 self.term_h = 24 # Space between stats self.space_between_column = 3 self.space_between_line = 2 # Init the curses screen self.screen = curses.initscr() if not self.screen: logger.critical(_("Error: Cannot init the curses library.\n")) sys.exit(1) # Set curses options if hasattr(curses, 'start_color'): curses.start_color() if hasattr(curses, 'use_default_colors'): curses.use_default_colors() if hasattr(curses, 'noecho'): curses.noecho() if hasattr(curses, 'cbreak'): curses.cbreak() self.set_cursor(0) # Init colors self.hascolors = False if curses.has_colors() and curses.COLOR_PAIRS > 8: self.hascolors = True # FG color, BG color if args.theme_white: curses.init_pair(1, curses.COLOR_BLACK, -1) else: curses.init_pair(1, curses.COLOR_WHITE, -1) curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_RED) curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_GREEN) curses.init_pair(4, curses.COLOR_WHITE, curses.COLOR_BLUE) curses.init_pair(5, curses.COLOR_WHITE, curses.COLOR_MAGENTA) curses.init_pair(6, curses.COLOR_RED, -1) curses.init_pair(7, curses.COLOR_GREEN, -1) curses.init_pair(8, curses.COLOR_BLUE, -1) try: curses.init_pair(9, curses.COLOR_MAGENTA, -1) except: if args.theme_white: curses.init_pair(9, curses.COLOR_BLACK, -1) else: curses.init_pair(9, curses.COLOR_WHITE, -1) try: curses.init_pair(10, curses.COLOR_CYAN, -1) except: if args.theme_white: curses.init_pair(10, curses.COLOR_BLACK, -1) else: curses.init_pair(10, curses.COLOR_WHITE, -1) else: self.hascolors = False if args.disable_bold: A_BOLD = curses.A_BOLD else: A_BOLD = 0 self.title_color = A_BOLD self.title_underline_color = A_BOLD | curses.A_UNDERLINE self.help_color = A_BOLD if self.hascolors: # Colors text styles self.no_color = curses.color_pair(1) self.default_color = curses.color_pair(3) | A_BOLD self.nice_color = curses.color_pair(9) | A_BOLD self.ifCAREFUL_color = curses.color_pair(4) | A_BOLD self.ifWARNING_color = curses.color_pair(5) | A_BOLD self.ifCRITICAL_color = curses.color_pair(2) | A_BOLD self.default_color2 = curses.color_pair(7) | A_BOLD self.ifCAREFUL_color2 = curses.color_pair(8) | A_BOLD self.ifWARNING_color2 = curses.color_pair(9) | A_BOLD self.ifCRITICAL_color2 = curses.color_pair(6) | A_BOLD self.filter_color = curses.color_pair(10) | A_BOLD else: # B&W text styles self.no_color = curses.A_NORMAL self.default_color = curses.A_NORMAL self.nice_color = A_BOLD self.ifCAREFUL_color = curses.A_UNDERLINE self.ifWARNING_color = A_BOLD self.ifCRITICAL_color = curses.A_REVERSE self.default_color2 = curses.A_NORMAL self.ifCAREFUL_color2 = curses.A_UNDERLINE self.ifWARNING_color2 = A_BOLD self.ifCRITICAL_color2 = curses.A_REVERSE self.filter_color = A_BOLD # Define the colors list (hash table) for stats self.__colors_list = { 'DEFAULT': self.no_color, 'UNDERLINE': curses.A_UNDERLINE, 'BOLD': A_BOLD, 'SORT': A_BOLD, 'OK': self.default_color2, 'FILTER': self.filter_color, 'TITLE': self.title_color, 'PROCESS': self.default_color2, 'STATUS': self.default_color2, 'NICE': self.nice_color, 'CAREFUL': self.ifCAREFUL_color2, 'WARNING': self.ifWARNING_color2, 'CRITICAL': self.ifCRITICAL_color2, 'OK_LOG': self.default_color, 'CAREFUL_LOG': self.ifCAREFUL_color, 'WARNING_LOG': self.ifWARNING_color, 'CRITICAL_LOG': self.ifCRITICAL_color } # Init main window self.term_window = self.screen.subwin(0, 0) # Init refresh time self.__refresh_time = args.time # Init process sort method self.args.process_sorted_by = 'auto' # Init edit filter tag self.edit_filter = False # Catch key pressed with non blocking mode self.term_window.keypad(1) self.term_window.nodelay(1) self.pressedkey = -1 # History tag self.reset_history_tag = False self.history_tag = False if args.enable_history: logger.info('Stats history enabled') from glances.outputs.glances_history import GlancesHistory self.glances_history = GlancesHistory() if not self.glances_history.graph_enabled(): args.enable_history = False logger.error( 'Stats history disabled because graph lib is not available' )