Example #1
0
    def __init__(self):
        """Init sensors stats."""
        # Temperatures
        try:
            # psutil>=5.1.0 is required
            self.stemps = psutil.sensors_temperatures()
        except AttributeError:
            logger.warning(
                "PsUtil 5.1.0 or higher is needed to grab temperatures sensors"
            )
            self.initok = False
            self.stemps = {}
        else:
            self.initok = True

        # Fans
        try:
            # psutil>=5.2.0 is required
            self.sfans = psutil.sensors_fans()
        except AttributeError:
            logger.warning(
                "PsUtil 5.2.0 or higher is needed to grab fans sensors")
            self.sfans = {}

        # Init the stats
        self.reset()
    def check_snmp(self):
        """Chek if SNMP is available on the server."""
        # Import the SNMP client class
        from glances.snmp import GlancesSNMPClient

        # Create an instance of the SNMP client
        clientsnmp = GlancesSNMPClient(host=self.args.client,
                                       port=self.args.snmp_port,
                                       version=self.args.snmp_version,
                                       community=self.args.snmp_community,
                                       user=self.args.snmp_user,
                                       auth=self.args.snmp_auth)

        # If we cannot grab the hostname, then exit...
        ret = clientsnmp.get_by_oid("1.3.6.1.2.1.1.5.0") != {}
        if ret:
            # Get the OS name (need to grab the good OID...)
            oid_os_name = clientsnmp.get_by_oid("1.3.6.1.2.1.1.1.0")
            try:
                self.system_name = self.get_system_name(
                    oid_os_name['1.3.6.1.2.1.1.1.0'])
                logger.info("SNMP system name detected: {}".format(
                    self.system_name))
            except KeyError:
                self.system_name = None
                logger.warning("Cannot detect SNMP system name")

        return ret
    def check_snmp(self):
        """Chek if SNMP is available on the server."""
        # Import the SNMP client class
        from glances.snmp import GlancesSNMPClient

        # Create an instance of the SNMP client
        clientsnmp = GlancesSNMPClient(host=self.args.client,
                                       port=self.args.snmp_port,
                                       version=self.args.snmp_version,
                                       community=self.args.snmp_community,
                                       user=self.args.snmp_user,
                                       auth=self.args.snmp_auth)

        # If we cannot grab the hostname, then exit...
        ret = clientsnmp.get_by_oid("1.3.6.1.2.1.1.5.0") != {}
        if ret:
            # Get the OS name (need to grab the good OID...)
            oid_os_name = clientsnmp.get_by_oid("1.3.6.1.2.1.1.1.0")
            try:
                self.system_name = self.get_system_name(oid_os_name['1.3.6.1.2.1.1.1.0'])
                logger.info("SNMP system name detected: {}".format(self.system_name))
            except KeyError:
                self.system_name = None
                logger.warning("Cannot detect SNMP system name")

        return ret
Example #4
0
    def __init__(self):
        """Init sensors stats."""
        # Temperatures
        self.init_temp = False
        self.stemps = {}
        try:
            # psutil>=5.1.0 is required
            self.stemps = psutil.sensors_temperatures()
        except AttributeError:
            logger.warning("PsUtil 5.1.0 or higher is needed to grab temperatures sensors")
        except OSError as e:
            # FreeBSD: If oid 'hw.acpi.battery' not present, Glances wont start #1055
            logger.error("Can not grab temperatures sensors ({})".format(e))
        else:
            self.init_temp = True

        # Fans
        self.init_fan = False
        self.sfans = {}
        try:
            # psutil>=5.2.0 is required
            self.sfans = psutil.sensors_fans()
        except AttributeError:
            logger.warning("PsUtil 5.2.0 or higher is needed to grab fans sensors")
        except OSError as e:
            logger.error("Can not grab fans sensors ({})".format(e))
        else:
            self.init_fan = True

        # !!! Disable Fan: High CPU consumption is PSUtil 5.2.0
        # Delete the following line when corrected
        self.init_fan = False

        # Init the stats
        self.reset()
Example #5
0
    def __update_stats(self, server):
        """
        Update stats for the given server (picked from the server list)
        """
        # Get the server URI
        uri = self.__get_uri(server)

        # Try to connect to the server
        t = GlancesClientTransport()
        t.set_timeout(3)

        # Get common stats
        try:
            s = ServerProxy(uri, transport=t)
        except Exception as e:
            logger.warning(
                "Client browser couldn't create socket {}: {}".format(uri, e))
        else:
            # Mandatory stats
            try:
                # CPU%
                cpu_percent = 100 - json.loads(s.getCpu())['idle']
                server['cpu_percent'] = '{:.1f}'.format(cpu_percent)
                # MEM%
                server['mem_percent'] = json.loads(s.getMem())['percent']
                # OS (Human Readable name)
                server['hr_name'] = json.loads(s.getSystem())['hr_name']
            except (socket.error, Fault, KeyError) as e:
                logger.debug("Error while grabbing stats form {}: {}".format(
                    uri, e))
                server['status'] = 'OFFLINE'
            except ProtocolError as e:
                if e.errcode == 401:
                    # Error 401 (Authentication failed)
                    # Password is not the good one...
                    server['password'] = None
                    server['status'] = 'PROTECTED'
                else:
                    server['status'] = 'OFFLINE'
                logger.debug("Cannot grab stats from {} ({} {})".format(
                    uri, e.errcode, e.errmsg))
            else:
                # Status
                server['status'] = 'ONLINE'

                # Optional stats (load is not available on Windows OS)
                try:
                    # LOAD
                    load_min5 = json.loads(s.getLoad())['min5']
                    server['load_min5'] = '{:.2f}'.format(load_min5)
                except Exception as e:
                    logger.warning(
                        "Error while grabbing stats form {}: {}".format(
                            uri, e))

        return server
Example #6
0
    def load(self, config):
        """Load the server list from the configuration file."""
        server_list = []

        if config is None:
            logger.debug(
                "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_value(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'] = '******'
                    # By default, try empty (aka no) password
                    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
Example #7
0
    def __update_stats(self, server):
        """
        Update stats for the given server (picked from the server list)
        """
        # Get the server URI
        uri = self.__get_uri(server)

        # Try to connect to the server
        t = GlancesClientTransport()
        t.set_timeout(3)

        # Get common stats
        try:
            s = ServerProxy(uri, transport=t)
        except Exception as e:
            logger.warning(
                "Client browser couldn't create socket {}: {}".format(uri, e))
        else:
            # Mandatory stats
            try:
                # CPU%
                cpu_percent = 100 - json.loads(s.getCpu())['idle']
                server['cpu_percent'] = '{:.1f}'.format(cpu_percent)
                # MEM%
                server['mem_percent'] = json.loads(s.getMem())['percent']
                # OS (Human Readable name)
                server['hr_name'] = json.loads(s.getSystem())['hr_name']
            except (socket.error, Fault, KeyError) as e:
                logger.debug(
                    "Error while grabbing stats form {}: {}".format(uri, e))
                server['status'] = 'OFFLINE'
            except ProtocolError as e:
                if e.errcode == 401:
                    # Error 401 (Authentication failed)
                    # Password is not the good one...
                    server['password'] = None
                    server['status'] = 'PROTECTED'
                else:
                    server['status'] = 'OFFLINE'
                logger.debug("Cannot grab stats from {} ({} {})".format(uri, e.errcode, e.errmsg))
            else:
                # Status
                server['status'] = 'ONLINE'

                # Optional stats (load is not available on Windows OS)
                try:
                    # LOAD
                    load_min5 = json.loads(s.getLoad())['min5']
                    server['load_min5'] = '{:.2f}'.format(load_min5)
                except Exception as e:
                    logger.warning(
                        "Error while grabbing stats form {}: {}".format(uri, e))

        return server
Example #8
0
    def load_config(self, config):
        """Load AMP parameters from the configuration file."""

        # Read AMP confifuration.
        # For ex, the AMP foo should have the following section:
        #
        # [foo]
        # enable=true
        # regex=\/usr\/bin\/nginx
        # refresh=60
        #
        # and optionnaly:
        #
        # one_line=false
        # option1=opt1
        # ...
        #
        amp_section = 'amp_' + self.amp_name
        if (hasattr(config, 'has_section')
                and config.has_section(amp_section)):
            logger.debug("{}: Load configuration".format(self.NAME))
            for param, _ in config.items(amp_section):
                try:
                    self.configs[param] = config.get_float_value(
                        amp_section, param)
                except ValueError:
                    self.configs[param] = config.get_value(amp_section,
                                                           param).split(',')
                    if len(self.configs[param]) == 1:
                        self.configs[param] = self.configs[param][0]
                logger.debug("{}: Load parameter: {} = {}".format(
                    self.NAME, param, self.configs[param]))
        else:
            logger.debug(
                "{}: Can not find section {} in the configuration file".format(
                    self.NAME, self.amp_name))
            return False

        # enable, regex and refresh are mandatories
        # if not configured then AMP is disabled
        if self.enable():
            for k in ['regex', 'refresh']:
                if k not in self.configs:
                    logger.warning(
                        "{}: Can not find configuration key {} in section {}".
                        format(self.NAME, k, self.amp_name))
                    self.configs['enable'] = 'false'
        else:
            logger.debug("{} is disabled".format(self.NAME))

        # Init the count to 0
        self.configs['count'] = 0

        return self.enable()
Example #9
0
    def update(self,
               stats,
               duration=3,
               cs_status=None,
               return_to_browser=False):
        """Update the screen.

        INPUT
        stats: Stats database to display
        duration: duration of the loop
        cs_status:
            "None": standalone or server mode
            "Connected": Client is connected to the server
            "Disconnected": Client is disconnected from the server
        return_to_browser:
            True: Do not exist, return to the browser list
            False: Exit and return to the shell

        OUTPUT
        True: Exit key has been pressed
        False: Others cases...
        """
        # Flush display
        self.flush(stats, cs_status=cs_status)

        # If the duration is < 0 (update + export time > refresh_time)
        # Then display the interface and log a message
        if duration <= 0:
            logger.warning('Update and export time higher than refresh_time.')
            duration = 0.1

        # Wait duration (in s) time
        exitkey = False
        countdown = Timer(duration)
        # Set the default timeout (in ms) for the getch method
        self.term_window.timeout(int(duration * 1000))
        while not countdown.finished() and not exitkey:
            # Getkey
            pressedkey = self.__catch_key(return_to_browser=return_to_browser)
            # Is it an exit key ?
            exitkey = (pressedkey == ord('\x1b') or pressedkey == ord('q'))
            if not exitkey and pressedkey > -1:
                # Redraw display
                self.flush(stats, cs_status=cs_status)
                # Overwrite the timeout with the countdown
                self.term_window.timeout(int(countdown.get() * 1000))

        return exitkey
Example #10
0
    def fetch(self):
        """Fetch the data from hddtemp daemon."""
        # Taking care of sudden deaths/stops of hddtemp daemon
        try:
            sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sck.connect((self.host, self.port))
            data = sck.recv(4096)
        except socket.error as e:
            logger.warning("Can not connect to an HDDtemp server ({0}:{1} => {2})".format(self.host, self.port, e))
            logger.debug("Disable the HDDtemp module. Use the --disable-hddtemp to hide the previous message.")
            self.args.disable_hddtemp = True
            data = ""
        finally:
            sck.close()

        return data
Example #11
0
    def fetch(self):
        """Fetch the data from hddtemp daemon."""
        # Taking care of sudden deaths/stops of hddtemp daemon
        try:
            sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sck.connect((self.host, self.port))
            data = sck.recv(4096)
        except socket.error as e:
            logger.warning("Can not connect to an HDDtemp server ({0}:{1} => {2})".format(self.host, self.port, e))
            logger.debug("Disable the HDDtemp module. Use the --disable-hddtemp to hide the previous message.")
            self.args.disable_hddtemp = True
            data = ""
        finally:
            sck.close()

        return data
Example #12
0
    def load_config(self, config):
        """Load AMP parameters from the configuration file."""

        # Read AMP confifuration.
        # For ex, the AMP foo should have the following section:
        #
        # [foo]
        # enable=true
        # regex=\/usr\/bin\/nginx
        # refresh=60
        #
        # and optionnaly:
        #
        # one_line=false
        # option1=opt1
        # ...
        #
        amp_section = 'amp_' + self.amp_name
        if (hasattr(config, 'has_section') and
                config.has_section(amp_section)):
            logger.debug("AMP - {}: Load configuration".format(self.NAME))
            for param, _ in config.items(amp_section):
                try:
                    self.configs[param] = config.get_float_value(amp_section, param)
                except ValueError:
                    self.configs[param] = config.get_value(amp_section, param).split(',')
                    if len(self.configs[param]) == 1:
                        self.configs[param] = self.configs[param][0]
                logger.debug("AMP - {}: Load parameter: {} = {}".format(self.NAME, param, self.configs[param]))
        else:
            logger.debug("AMP - {}: Can not find section {} in the configuration file".format(self.NAME, self.amp_name))
            return False

        # enable, regex and refresh are mandatories
        # if not configured then AMP is disabled
        if self.enable():
            for k in ['regex', 'refresh']:
                if k not in self.configs:
                    logger.warning("AMP - {}: Can not find configuration key {} in section {}".format(self.NAME, k, self.amp_name))
                    self.configs['enable'] = 'false'
        else:
            logger.debug("AMP - {} is disabled".format(self.NAME))

        # Init the count to 0
        self.configs['count'] = 0

        return self.enable()
Example #13
0
    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_value(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"] = "******"
                    # By default, try empty (aka no) password
                    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
Example #14
0
    def load(self, config):
        """Load the server list from the configuration file."""
        server_list = []

        if config is None:
            logger.debug("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_value(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'] = '******'
                    # By default, try empty (aka no) password
                    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
Example #15
0
    def load(self, config):
        """Load the password from the configuration file."""
        password_dict = {}

        if config is None:
            logger.warning("No configuration file available. Cannot load password list.")
        elif not config.has_section(self._section):
            logger.warning("No [%s] section in the configuration file. Cannot load password list." % self._section)
        else:
            logger.info("Start reading the [%s] section in the configuration file" % self._section)

            password_dict = dict(config.items(self._section))

            # Password list loaded
            logger.info("%s password(s) loaded from the configuration file" % len(password_dict))
            logger.debug("Password dictionary: %s" % password_dict)

        return password_dict
Example #16
0
    def __init__(self):
        """Init sensors stats."""
        # Temperatures
        self.init_temp = False
        self.stemps = {}
        try:
            # psutil>=5.1.0 is required
            self.stemps = psutil.sensors_temperatures()
        except AttributeError:
            logger.warning(
                "PsUtil 5.1.0 or higher is needed to grab temperatures sensors"
            )
        except OSError as e:
            # FreeBSD: If oid 'hw.acpi.battery' not present, Glances wont start #1055
            logger.error("Can not grab temperatures sensors ({})".format(e))
        else:
            self.init_temp = True

        # Fans
        self.init_fan = False
        self.sfans = {}
        try:
            # psutil>=5.2.0 is required
            self.sfans = psutil.sensors_fans()
        except AttributeError:
            logger.warning(
                "PsUtil 5.2.0 or higher is needed to grab fans sensors")
        except OSError as e:
            logger.error("Can not grab fans sensors ({})".format(e))
        else:
            self.init_fan = True

        # !!! Disable Fan: High CPU consumption is PSUtil 5.2.0
        # Delete the following line when corrected
        self.init_fan = False

        # Init the stats
        self.reset()
    def add_service(self, zeroconf, srv_type, srv_name):
        """Method called when a new Zeroconf client is detected.

        Return True if the zeroconf client is a Glances server
        Note: the return code will never be used
        """
        if srv_type != zeroconf_type:
            return False
        logger.debug("Check new Zeroconf server: %s / %s" %
                     (srv_type, srv_name))
        info = zeroconf.get_service_info(srv_type, srv_name)
        if info:
            new_server_ip = socket.inet_ntoa(info.address)
            new_server_port = info.port

            # Add server to the global dict
            self.servers.add_server(srv_name, new_server_ip, new_server_port)
            logger.info("New Glances server detected (%s from %s:%s)" %
                        (srv_name, new_server_ip, new_server_port))
        else:
            logger.warning(
                "New Glances server detected, but Zeroconf info failed to be grabbed")
        return True
Example #18
0
    def add_service(self, zeroconf, srv_type, srv_name):
        """Method called when a new Zeroconf client is detected.

        Return True if the zeroconf client is a Glances server
        Note: the return code will never be used
        """
        if srv_type != zeroconf_type:
            return False
        logger.debug("Check new Zeroconf server: %s / %s" %
                     (srv_type, srv_name))
        info = zeroconf.get_service_info(srv_type, srv_name)
        if info:
            new_server_ip = socket.inet_ntoa(info.address)
            new_server_port = info.port

            # Add server to the global dict
            self.servers.add_server(srv_name, new_server_ip, new_server_port)
            logger.info("New Glances server detected (%s from %s:%s)" %
                        (srv_name, new_server_ip, new_server_port))
        else:
            logger.warning(
                "New Glances server detected, but Zeroconf info failed to be grabbed")
        return True
Example #19
0
    def load(self, config):
        """Load the password from the configuration file."""
        password_dict = []

        if config is None:
            logger.warning(
                "No configuration file available. Cannot load password list.")
        elif not config.has_section(self._section):
            logger.warning(
                "No [%s] section in the configuration file. Cannot load password list."
                % self._section)
        else:
            logger.info(
                "Start reading the [%s] section in the configuration file" %
                self._section)

            password_dict = dict(config.items(self._section))

            # Password list loaded
            logger.info("%s password(s) loaded from the configuration file" %
                        len(password_dict))
            logger.debug("Password dictionary: %s" % password_dict)

        return password_dict
Example #20
0
    def load_configs(self):
        """Load the AMP configuration files."""
        if self.config is None:
            return False

        # Display a warning (deprecated) message if the monitor section exist
        if "monitor" in self.config.sections():
            logger.warning(
                "A deprecated [monitor] section exists in the Glances configuration file. You should use the new Applications Monitoring Process module instead (http://glances.readthedocs.io/en/develop/aoa/amps.html)."
            )

        header = "glances_"
        # For each AMP scrip, call the load_config method
        for s in self.config.sections():
            if s.startswith("amp_"):
                # An AMP section exists in the configuration file
                # If an AMP script exist in the glances/amps folder, use it
                amp_conf_name = s[4:]
                amp_script = os.path.join(amps_path, header + s[4:] + ".py")
                if not os.path.exists(amp_script):
                    # If not, use the default script
                    amp_script = os.path.join(amps_path, "glances_default.py")
                try:
                    amp = __import__(os.path.basename(amp_script)[:-3])
                except ImportError as e:
                    logger.warning(
                        "Cannot load {}, you need to install an external Python package ({})"
                        .format(os.path.basename(amp_script), e))
                except Exception as e:
                    logger.warning("Cannot load {} ({})".format(
                        os.path.basename(amp_script), e))
                else:
                    # Add the AMP to the dictionary
                    # The key is the AMP name
                    # for example, the file glances_xxx.py
                    # generate self._amps_list["xxx"] = ...
                    self.__amps_dict[amp_conf_name] = amp.Amp(
                        name=amp_conf_name, args=self.args)
                    # Load the AMP configuration
                    self.__amps_dict[amp_conf_name].load_config(self.config)
        # Log AMPs list
        logger.debug("AMPs list: {}".format(self.getList()))

        return True
Example #21
0
    def load_configs(self):
        """Load the AMP configuration files."""
        if self.config is None:
            return False

        # Display a warning (deprecated) message if the monitor section exist
        if "monitor" in self.config.sections():
            logger.warning("A deprecated [monitor] section exists in the Glances configuration file. You should use the new Applications Monitoring Process module instead (http://glances.readthedocs.io/en/develop/aoa/amps.html).")

        header = "glances_"
        # For each AMP scrip, call the load_config method
        for s in self.config.sections():
            if s.startswith("amp_"):
                # An AMP section exists in the configuration file
                # If an AMP script exist in the glances/amps folder, use it
                amp_conf_name = s[4:]
                amp_script = os.path.join(amps_path, header + s[4:] + ".py")
                if not os.path.exists(amp_script):
                    # If not, use the default script
                    amp_script = os.path.join(amps_path, "glances_default.py")
                try:
                    amp = __import__(os.path.basename(amp_script)[:-3])
                except ImportError as e:
                    logger.warning("Cannot load {}, you need to install an external Python package ({})".format(os.path.basename(amp_script), e))
                except Exception as e:
                    logger.warning("Cannot load {} ({})".format(os.path.basename(amp_script), e))
                else:
                    # Add the AMP to the dictionary
                    # The key is the AMP name
                    # for example, the file glances_xxx.py
                    # generate self._amps_list["xxx"] = ...
                    self.__amps_dict[amp_conf_name] = amp.Amp(name=amp_conf_name, args=self.args)
                    # Load the AMP configuration
                    self.__amps_dict[amp_conf_name].load_config(self.config)
        # Log AMPs list
        logger.debug("AMPs list: {}".format(self.getList()))

        return True
Example #22
0
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""RAID plugin."""

from glances.compat import iterkeys
from glances.logger import logger
from glances.plugins.glances_plugin import GlancesPlugin

# Import plugin specific dependency
try:
    from pymdstat import MdStat
except ImportError as e:
    import_error_tag = True
    logger.warning(
        "Missing Python Lib ({}), Raid plugin is disabled".format(e))
else:
    import_error_tag = False


class Plugin(GlancesPlugin):
    """Glances RAID plugin.

    stats is a dict (see pymdstat documentation)
    """
    def __init__(self, args=None):
        """Init the plugin."""
        super(Plugin, self).__init__(args=args)

        # We want to display the stat in the curse interface
        self.display_curse = True
Example #23
0
import operator

from glances.compat import nativestr
from glances.logger import logger
from glances.plugins.glances_plugin import GlancesPlugin

import psutil
# Use the Wifi Python lib (https://pypi.python.org/pypi/wifi)
# Linux-only
try:
    from wifi.scan import Cell
    from wifi.exceptions import InterfaceError
except ImportError as e:
    import_error_tag = True
    logger.warning("Missing Python Lib ({}), Wifi plugin is disabled".format(e))
else:
    import_error_tag = False


class Plugin(GlancesPlugin):
    """Glances Wifi plugin.

    Get stats of the current Wifi hotspots.
    """

    def __init__(self, args=None):
        """Init the plugin."""
        super(Plugin, self).__init__(args=args,
                                     stats_init_value=[])
Example #24
0
import numbers

from glances.globals import WINDOWS, MACOS, BSD
from glances.ports_list import GlancesPortsList
from glances.web_list import GlancesWebList
from glances.timer import Timer, Counter
from glances.compat import bool_type
from glances.logger import logger
from glances.plugins.glances_plugin import GlancesPlugin

try:
    import requests
    requests_tag = True
except ImportError as e:
    requests_tag = False
    logger.warning("Missing Python Lib ({}), Ports plugin is limited to port scanning".format(e))


class Plugin(GlancesPlugin):
    """Glances ports scanner plugin."""

    def __init__(self, args=None, config=None):
        """Init the plugin."""
        super(Plugin, self).__init__(args=args,
                                     stats_init_value=[])
        self.args = args
        self.config = config

        # We want to display the stat in the curse interface
        self.display_curse = True
Example #25
0
"""Quicklook plugin."""

from glances.cpu_percent import cpu_percent
from glances.logger import logger
from glances.outputs.glances_bars import Bar
from glances.plugins.glances_plugin import GlancesPlugin

import psutil

# Import plugin specific dependency
try:
    from cpuinfo import cpuinfo
except ImportError as e:
    cpuinfo_tag = False
    logger.warning("Missing Python Lib ({}), Quicklook plugin will not display CPU info".format(e))
else:
    cpuinfo_tag = True


class Plugin(GlancesPlugin):
    """Glances quicklook plugin.

    'stats' is a dictionary.
    """

    def __init__(self, args=None):
        """Init the quicklook plugin."""
        super(Plugin, self).__init__(args=args)

        # We want to display the stat in the curse interface
Example #26
0
    def __serve_forever(self):
        """Main client loop."""
        while True:
            # No need to update the server list
            # It's done by the GlancesAutoDiscoverListener class (autodiscover.py)
            # Or define staticaly in the configuration file (module static_list.py)
            # For each server in the list, grab elementary stats (CPU, LOAD, MEM, OS...)
            # logger.debug(self.get_servers_list())
            try:
                for v in self.get_servers_list():
                    # Do not retreive stats for statics server
                    # Why ? Because for each offline servers, the timeout will be reached
                    # So ? The curse interface freezes
                    if v['type'] == 'STATIC' and v['status'] in [
                            'UNKNOWN', 'SNMP', 'OFFLINE'
                    ]:
                        continue

                    # Get the server URI
                    uri = self.__get_uri(v)

                    # Try to connect to the server
                    t = GlancesClientTransport()
                    t.set_timeout(3)

                    # Get common stats
                    try:
                        s = ServerProxy(uri, transport=t)
                    except Exception as e:
                        logger.warning(
                            "Client browser couldn't create socket {0}: {1}".
                            format(uri, e))
                    else:
                        # Mandatory stats
                        try:
                            # CPU%
                            cpu_percent = 100 - json.loads(s.getCpu())['idle']
                            v['cpu_percent'] = '{0:.1f}'.format(cpu_percent)
                            # MEM%
                            v['mem_percent'] = json.loads(
                                s.getMem())['percent']
                            # OS (Human Readable name)
                            v['hr_name'] = json.loads(s.getSystem())['hr_name']
                        except (socket.error, Fault, KeyError) as e:
                            logger.debug(
                                "Error while grabbing stats form {0}: {1}".
                                format(uri, e))
                            v['status'] = 'OFFLINE'
                        except ProtocolError as e:
                            if e.errcode == 401:
                                # Error 401 (Authentication failed)
                                # Password is not the good one...
                                v['password'] = None
                                v['status'] = 'PROTECTED'
                            else:
                                v['status'] = 'OFFLINE'
                            logger.debug(
                                "Cannot grab stats from {0} ({1} {2})".format(
                                    uri, e.errcode, e.errmsg))
                        else:
                            # Status
                            v['status'] = 'ONLINE'

                            # Optional stats (load is not available on Windows OS)
                            try:
                                # LOAD
                                load_min5 = json.loads(s.getLoad())['min5']
                                v['load_min5'] = '{0:.2f}'.format(load_min5)
                            except Exception as e:
                                logger.warning(
                                    "Error while grabbing stats form {0}: {1}".
                                    format(uri, e))
            # List can change size during iteration...
            except RuntimeError:
                logger.debug(
                    "Server list dictionnary change inside the loop (wait next update)"
                )

            # Update the screen (list or Glances client)
            if self.screen.active_server is None:
                #  Display the Glances browser
                self.screen.update(self.get_servers_list())
            else:
                # Display the Glances client for the selected server
                logger.debug("Selected server: {0}".format(
                    self.get_servers_list()[self.screen.active_server]))

                # Connection can take time
                # Display a popup
                self.screen.display_popup('Connect to {0}:{1}'.format(
                    v['name'], v['port']),
                                          duration=1)

                # A password is needed to access to the server's stats
                if self.get_servers_list()[
                        self.screen.active_server]['password'] is None:
                    # First of all, check if a password is available in the [passwords] section
                    clear_password = self.password.get_password(v['name'])
                    if (clear_password is None or self.get_servers_list()
                        [self.screen.active_server]['status'] == 'PROTECTED'):
                        # Else, the password should be enter by the user
                        # Display a popup to enter password
                        clear_password = self.screen.display_popup(
                            'Password needed for {0}: '.format(v['name']),
                            is_input=True)
                    # Store the password for the selected server
                    if clear_password is not None:
                        self.set_in_selected(
                            'password',
                            self.password.sha256_hash(clear_password))

                # Display the Glance client on the selected server
                logger.info("Connect Glances client to the {0} server".format(
                    self.get_servers_list()[self.screen.active_server]['key']))

                # Init the client
                args_server = self.args

                # Overwrite connection setting
                args_server.client = self.get_servers_list()[
                    self.screen.active_server]['ip']
                args_server.port = self.get_servers_list()[
                    self.screen.active_server]['port']
                args_server.username = self.get_servers_list()[
                    self.screen.active_server]['username']
                args_server.password = self.get_servers_list()[
                    self.screen.active_server]['password']
                client = GlancesClient(config=self.config,
                                       args=args_server,
                                       return_to_browser=True)

                # Test if client and server are in the same major version
                if not client.login():
                    self.screen.display_popup(
                        "Sorry, cannot connect to '{0}'\n"
                        "See 'glances.log' for more details".format(v['name']))

                    # Set the ONLINE status for the selected server
                    self.set_in_selected('status', 'OFFLINE')
                else:
                    # Start the client loop
                    # Return connection type: 'glances' or 'snmp'
                    connection_type = client.serve_forever()

                    try:
                        logger.debug(
                            "Disconnect Glances client from the {0} server".
                            format(self.get_servers_list()[
                                self.screen.active_server]['key']))
                    except IndexError:
                        # Server did not exist anymore
                        pass
                    else:
                        # Set the ONLINE status for the selected server
                        if connection_type == 'snmp':
                            self.set_in_selected('status', 'SNMP')
                        else:
                            self.set_in_selected('status', 'ONLINE')

                # Return to the browser (no server selected)
                self.screen.active_server = None
Example #27
0
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Manage on alert actions."""

from subprocess import Popen

from glances.logger import logger
from glances.timer import Timer

try:
    import pystache
except ImportError:
    logger.warning(
        "PyStache lib not installed (action script with mustache will not work)"
    )
    pystache_tag = False
else:
    pystache_tag = True


class GlancesActions(object):
    """This class manage action if an alert is reached."""
    def __init__(self, args=None):
        """Init GlancesActions class."""
        # Dict with the criticity status
        # - key: stat_name
        # - value: criticity
        # Goal: avoid to execute the same command twice
        self.status = {}
Example #28
0
"""Manage sparklines for Glances output."""

from __future__ import unicode_literals
from __future__ import division
import sys
from math import modf
from glances.logger import logger
from glances.compat import nativestr

sparklines_module = True

try:
    from sparklines import sparklines
except ImportError as e:
    logger.warning("Sparklines module not found ({})".format(e))
    sparklines_module = False

try:
    '┌┬┐╔╦╗╒╤╕╓╥╖│║─═├┼┤╠╬╣╞╪╡╟╫╢└┴┘╚╩╝╘╧╛╙╨╜'.encode(sys.stdout.encoding)
except (UnicodeEncodeError, TypeError):
    logger.warning("UTF-8 is mandatory for sparklines ({})".format(e))
    sparklines_module = False


class Sparkline(object):

    r"""Manage sparklines (see https://pypi.org/project/sparklines/)."""

    def __init__(self, size, pre_char='[', post_char=']', empty_char=' ', with_text=True):
        # If the sparklines python module available ?
Example #29
0
Check for admin access.  If no admin access, disable SMART plugin.

If smartmontools is not installed, we should catch the error upstream in plugin initialization.
"""

from glances.plugins.glances_plugin import GlancesPlugin
from glances.logger import logger
from glances.main import disable
from glances.compat import is_admin

# Import plugin specific dependency
try:
    from pySMART import DeviceList
except ImportError as e:
    import_error_tag = True
    logger.warning(
        "Missing Python Lib ({}), HDD Smart plugin is disabled".format(e))
else:
    import_error_tag = False


def convert_attribute_to_dict(attr):
    return {
        'name': attr.name,
        'num': attr.num,
        'flags': attr.flags,
        'raw': attr.raw,
        'value': attr.value,
        'worst': attr.worst,
        'threshold': attr.thresh,
        'type': attr.type,
        'updated': attr.updated,
Example #30
0
    def __serve_forever(self):
        """Main client loop."""
        while True:
            # No need to update the server list
            # It's done by the GlancesAutoDiscoverListener class (autodiscover.py)
            # Or define staticaly in the configuration file (module static_list.py)
            # For each server in the list, grab elementary stats (CPU, LOAD, MEM, OS...)
            # logger.debug(self.get_servers_list())
            try:
                for v in self.get_servers_list():
                    # Do not retreive stats for statics server
                    # Why ? Because for each offline servers, the timeout will be reached
                    # So ? The curse interface freezes
                    if v['type'] == 'STATIC' and v['status'] in ['UNKNOWN', 'SNMP', 'OFFLINE']:
                        continue

                    # Get the server URI
                    uri = self.__get_uri(v)

                    # Try to connect to the server
                    t = GlancesClientTransport()
                    t.set_timeout(3)

                    # Get common stats
                    try:
                        s = ServerProxy(uri, transport=t)
                    except Exception as e:
                        logger.warning(
                            "Client browser couldn't create socket {0}: {1}".format(uri, e))
                    else:
                        # Mandatory stats
                        try:
                            # CPU%
                            cpu_percent = 100 - json.loads(s.getCpu())['idle']
                            v['cpu_percent'] = '{0:.1f}'.format(cpu_percent)
                            # MEM%
                            v['mem_percent'] = json.loads(s.getMem())['percent']
                            # OS (Human Readable name)
                            v['hr_name'] = json.loads(s.getSystem())['hr_name']
                        except (socket.error, Fault, KeyError) as e:
                            logger.debug(
                                "Error while grabbing stats form {0}: {1}".format(uri, e))
                            v['status'] = 'OFFLINE'
                        except ProtocolError as e:
                            if e.errcode == 401:
                                # Error 401 (Authentication failed)
                                # Password is not the good one...
                                v['password'] = None
                                v['status'] = 'PROTECTED'
                            else:
                                v['status'] = 'OFFLINE'
                            logger.debug("Cannot grab stats from {0} ({1} {2})".format(uri, e.errcode, e.errmsg))
                        else:
                            # Status
                            v['status'] = 'ONLINE'

                            # Optional stats (load is not available on Windows OS)
                            try:
                                # LOAD
                                load_min5 = json.loads(s.getLoad())['min5']
                                v['load_min5'] = '{0:.2f}'.format(load_min5)
                            except Exception as e:
                                logger.warning(
                                    "Error while grabbing stats form {0}: {1}".format(uri, e))
            # List can change size during iteration...
            except RuntimeError:
                logger.debug(
                    "Server list dictionnary change inside the loop (wait next update)")

            # Update the screen (list or Glances client)
            if not self.screen.active_server:
                #  Display the Glances browser
                self.screen.update(self.get_servers_list())
            else:
                # Display the Glances client for the selected server
                logger.debug("Selected server: {0}".format(self.get_servers_list()[self.screen.active_server]))

                # Connection can take time
                # Display a popup
                self.screen.display_popup(
                    'Connect to {0}:{1}'.format(v['name'], v['port']), duration=1)

                # A password is needed to access to the server's stats
                if self.get_servers_list()[self.screen.active_server]['password'] is None:
                    # First of all, check if a password is available in the [passwords] section
                    clear_password = self.password.get_password(v['name'])
                    if (clear_password is None or self.get_servers_list()
                            [self.screen.active_server]['status'] == 'PROTECTED'):
                        # Else, the password should be enter by the user
                        # Display a popup to enter password
                        clear_password = self.screen.display_popup(
                            'Password needed for {0}: '.format(v['name']), is_input=True)
                    # Store the password for the selected server
                    if clear_password is not None:
                        self.set_in_selected('password', self.password.sha256_hash(clear_password))

                # Display the Glance client on the selected server
                logger.info("Connect Glances client to the {0} server".format(
                    self.get_servers_list()[self.screen.active_server]['key']))

                # Init the client
                args_server = self.args

                # Overwrite connection setting
                args_server.client = self.get_servers_list()[self.screen.active_server]['ip']
                args_server.port = self.get_servers_list()[self.screen.active_server]['port']
                args_server.username = self.get_servers_list()[self.screen.active_server]['username']
                args_server.password = self.get_servers_list()[self.screen.active_server]['password']
                client = GlancesClient(config=self.config, args=args_server, return_to_browser=True)

                # Test if client and server are in the same major version
                if not client.login():
                    self.screen.display_popup(
                        "Sorry, cannot connect to '{0}'\n"
                        "See 'glances.log' for more details".format(v['name']))

                    # Set the ONLINE status for the selected server
                    self.set_in_selected('status', 'OFFLINE')
                else:
                    # Start the client loop
                    # Return connection type: 'glances' or 'snmp'
                    connection_type = client.serve_forever()

                    try:
                        logger.debug("Disconnect Glances client from the {0} server".format(
                            self.get_servers_list()[self.screen.active_server]['key']))
                    except IndexError:
                        # Server did not exist anymore
                        pass
                    else:
                        # Set the ONLINE status for the selected server
                        if connection_type == 'snmp':
                            self.set_in_selected('status', 'SNMP')
                        else:
                            self.set_in_selected('status', 'ONLINE')

                # Return to the browser (no server selected)
                self.screen.active_server = None
Example #31
0
import operator

from glances.compat import nativestr, PY3
from glances.logger import logger
from glances.plugins.glances_plugin import GlancesPlugin

import psutil
# Use the Wifi Python lib (https://pypi.python.org/pypi/wifi)
# Linux-only
try:
    from wifi.scan import Cell
    from wifi.exceptions import InterfaceError
except ImportError as e:
    import_error_tag = True
    logger.warning("Missing Python Lib ({}), Wifi plugin is disabled".format(e))
else:
    import_error_tag = False

# Python 3 is not supported (see issue #1377)
if PY3:
    import_error_tag = True
    logger.warning("Wifi lib is not compliant with Python 3, Wifi plugin is disabled")


class Plugin(GlancesPlugin):
    """Glances Wifi plugin.

    Get stats of the current Wifi hotspots.
    """
Example #32
0
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""GPU plugin (limited to NVIDIA chipsets)."""

from glances.compat import nativestr
from glances.logger import logger
from glances.plugins.glances_plugin import GlancesPlugin

try:
    import pynvml
except Exception as e:
    import_error_tag = True
    # Display debu message if import KeyError
    logger.warning("Missing Python Lib ({}), Nvidia GPU plugin is disabled".format(e))
else:
    import_error_tag = False

# Define the history items list
# All items in this list will be historised if the --enable-history tag is set
items_history_list = [{'name': 'proc',
                       'description': 'GPU processor',
                       'y_unit': '%'},
                      {'name': 'mem',
                       'description': 'Memory consumption',
                       'y_unit': '%'}]


class Plugin(GlancesPlugin):
    """Glances GPU plugin (limited to NVIDIA chipsets).
Example #33
0
Check for admin access.  If no admin access, disable SMART plugin.

If smartmontools is not installed, we should catch the error upstream in plugin initialization.
"""

from glances.plugins.glances_plugin import GlancesPlugin
from glances.logger import logger
from glances.main import disable
import os

# Import plugin specific dependency
try:
    from pySMART import DeviceList
except ImportError as e:
    import_error_tag = True
    logger.warning("Missing Python Lib ({}), HDD Smart plugin is disabled".format(e))
else:
    import_error_tag = False

DEVKEY = "DeviceName"


def is_admin():
    """
    https://stackoverflow.com/a/19719292
    @return: True if the current user is an 'Admin' whatever that
    means (root on Unix), otherwise False.
    Warning: The inner function fails unless you have Windows XP SP2 or
    higher. The failure causes a traceback to be printed and this
    function to return False.
    """
Example #34
0
    def _init_colors(self):
        """Init the Curses color layout."""

        # Set curses options
        try:
            if hasattr(curses, 'start_color'):
                curses.start_color()
            if hasattr(curses, 'use_default_colors'):
                curses.use_default_colors()
        except Exception as e:
            logger.warning('Error initializing terminal color ({})'.format(e))

        # Init colors
        if self.args.disable_bold:
            A_BOLD = 0
            self.args.disable_bg = True
        else:
            A_BOLD = curses.A_BOLD

        self.title_color = A_BOLD
        self.title_underline_color = A_BOLD | curses.A_UNDERLINE
        self.help_color = A_BOLD

        if curses.has_colors():
            # The screen is compatible with a colored design
            if self.is_theme('white'):
                # White theme: black ==> white
                curses.init_pair(1, curses.COLOR_BLACK, -1)
            else:
                curses.init_pair(1, curses.COLOR_WHITE, -1)
            if self.args.disable_bg:
                curses.init_pair(2, curses.COLOR_RED, -1)
                curses.init_pair(3, curses.COLOR_GREEN, -1)
                curses.init_pair(4, curses.COLOR_BLUE, -1)
                curses.init_pair(5, curses.COLOR_MAGENTA, -1)
            else:
                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)

            # Colors text styles
            if curses.COLOR_PAIRS > 8:
                try:
                    curses.init_pair(9, curses.COLOR_MAGENTA, -1)
                except Exception:
                    if self.is_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 self.is_theme('white'):
                        curses.init_pair(10, curses.COLOR_BLACK, -1)
                    else:
                        curses.init_pair(10, curses.COLOR_WHITE, -1)

                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

            self.no_color = curses.color_pair(1)
            self.default_color = curses.color_pair(3) | A_BOLD
            self.nice_color = curses.color_pair(9)
            self.cpu_time_color = curses.color_pair(9)
            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)
            self.ifCAREFUL_color2 = curses.color_pair(8) | A_BOLD

        else:
            # The screen is NOT compatible with a colored design
            # switch to B&W text styles
            self.no_color = curses.A_NORMAL
            self.default_color = curses.A_NORMAL
            self.nice_color = A_BOLD
            self.cpu_time_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,
            'MAX': self.default_color2 | curses.A_BOLD,
            'FILTER': self.filter_color,
            'TITLE': self.title_color,
            'PROCESS': self.default_color2,
            'STATUS': self.default_color2,
            'NICE': self.nice_color,
            'CPU_TIME': self.cpu_time_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,
            'PASSWORD': curses.A_PROTECT
        }
Example #35
0
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""Graph generation class."""

import os

from glances.compat import iterkeys
from glances.logger import logger

try:
    from matplotlib import __version__ as matplotlib_version
    import matplotlib.pyplot as plt
except ImportError:
    matplotlib_check = False
    logger.warning('Cannot load Matplotlib library. Please install it using "pip install matplotlib"')
else:
    matplotlib_check = True
    logger.info("Load Matplotlib version %s" % matplotlib_version)


class GlancesGraph(object):

    """Thanks to this class, Glances can export history to graphs."""

    def __init__(self, output_folder):
        self.output_folder = output_folder

    def get_output_folder(self):
        """Return the output folder where the graph are generated."""
        return self.output_folder
Example #36
0
    def __init__(self, cache_timeout=60):
        """Init the class to collect stats about processes."""
        # Add internals caches because psutil do not cache all the stats
        # See: https://code.google.com/p/psutil/issues/detail?id=462
        self.username_cache = {}
        self.cmdline_cache = {}

        # The internals caches will be cleaned each 'cache_timeout' seconds
        self.cache_timeout = cache_timeout
        self.cache_timer = Timer(self.cache_timeout)

        # Init the io dict
        # key = pid
        # value = [ read_bytes_old, write_bytes_old ]
        self.io_old = {}

        # Init stats
        self.auto_sort = None
        self._sort_key = None
        # Default processes sort key is 'auto'
        # Can be overwrite from the configuration file (issue#1536) => See glances_processlist.py init
        self.set_sort_key('auto', auto=True)
        self.processlist = []
        self.reset_processcount()

        # Tag to enable/disable the processes stats (to reduce the Glances CPU consumption)
        # Default is to enable the processes stats
        self.disable_tag = False

        # Extended stats for top process is enable by default
        self.disable_extended_tag = False

        # Test if the system can grab io_counters
        try:
            p = psutil.Process()
            p.io_counters()
        except Exception as e:
            logger.warning(
                'PsUtil can not grab processes io_counters ({})'.format(e))
            self.disable_io_counters = True
        else:
            logger.debug('PsUtil can grab processes io_counters')
            self.disable_io_counters = False

        # Test if the system can grab gids
        try:
            p = psutil.Process()
            p.gids()
        except Exception as e:
            logger.warning('PsUtil can not grab processes gids ({})'.format(e))
            self.disable_gids = True
        else:
            logger.debug('PsUtil can grab processes gids')
            self.disable_gids = False

        # Maximum number of processes showed in the UI (None if no limit)
        self._max_processes = None

        # Process filter is a regular expression
        self._filter = GlancesFilter()

        # Whether or not to hide kernel threads
        self.no_kernel_threads = False

        # Store maximums values in a dict
        # Used in the UI to highlight the maximum value
        self._max_values_list = ('cpu_percent', 'memory_percent')
        # { 'cpu_percent': 0.0, 'memory_percent': 0.0 }
        self._max_values = {}
        self.reset_max_values()
Example #37
0
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""Manage on alert actions."""

from subprocess import Popen

from glances.logger import logger
from glances.timer import Timer

try:
    import pystache
except ImportError:
    logger.warning("PyStache lib not installed (action script with mustache will not work)")
    pystache_tag = False
else:
    pystache_tag = True


class GlancesActions(object):

    """This class manage action if an alert is reached."""

    def __init__(self, args=None):
        """Init GlancesActions class."""
        # Dict with the criticity status
        # - key: stat_name
        # - value: criticity
        # Goal: avoid to execute the same command twice
Example #38
0
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""History class."""

import os

from glances.compat import iterkeys
from glances.logger import logger

try:
    from matplotlib import __version__ as matplotlib_version
    import matplotlib.pyplot as plt
except ImportError:
    matplotlib_check = False
    logger.warning(
        'Cannot load Matplotlib library. Please install it using "pip install matplotlib"'
    )
else:
    matplotlib_check = True
    logger.info('Load Matplotlib version %s' % matplotlib_version)


class GlancesHistory(object):
    """This class define the object to manage stats history."""
    def __init__(self, output_folder):
        self.output_folder = output_folder

    def get_output_folder(self):
        """Return the output folder where the graph are generated."""
        return self.output_folder
Example #39
0
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""GPU plugin (limited to NVIDIA chipsets)."""

from glances.compat import nativestr, to_fahrenheit
from glances.logger import logger
from glances.plugins.glances_plugin import GlancesPlugin

# In Glances 3.1.4 or higher, we use the py3nvml lib (see issue #1523)
try:
    import py3nvml.py3nvml as pynvml
except Exception as e:
    import_error_tag = True
    # Display debu message if import KeyError
    logger.warning(
        "Missing Python Lib ({}), Nvidia GPU plugin is disabled".format(e))
else:
    import_error_tag = False

# Define the history items list
# All items in this list will be historised if the --enable-history tag is set
items_history_list = [{
    'name': 'proc',
    'description': 'GPU processor',
    'y_unit': '%'
}, {
    'name': 'mem',
    'description': 'Memory consumption',
    'y_unit': '%'
}]
Example #40
0
from glances.globals import WINDOWS, MACOS, BSD
from glances.ports_list import GlancesPortsList
from glances.web_list import GlancesWebList
from glances.timer import Timer, Counter
from glances.compat import bool_type
from glances.logger import logger
from glances.plugins.glances_plugin import GlancesPlugin

try:
    import requests
    requests_tag = True
except ImportError as e:
    requests_tag = False
    logger.warning(
        "Missing Python Lib ({}), Ports plugin is limited to port scanning".
        format(e))


class Plugin(GlancesPlugin):
    """Glances ports scanner plugin."""
    def __init__(self, args=None, config=None):
        """Init the plugin."""
        super(Plugin, self).__init__(args=args,
                                     config=config,
                                     stats_init_value=[])
        self.args = args
        self.config = config

        # We want to display the stat in the curse interface
        self.display_curse = True
Example #41
0
from glances.logger import logger
from glances.compat import iterkeys, itervalues, nativestr
from glances.timer import getTimeSinceLastUpdate
from glances.plugins.glances_plugin import GlancesPlugin
from glances.processes import sort_stats as sort_stats_processes, weighted, glances_processes

# Docker-py library (optional and Linux-only)
# https://github.com/docker/docker-py
try:
    import docker
except Exception as e:
    import_error_tag = True
    # Display debu message if import KeyError
    logger.warning(
        "Error loading Docker Python Lib. Docker plugin is disabled ({})".
        format(e))
else:
    import_error_tag = False

# Define the items history list (list of items to add to history)
# TODO: For the moment limited to the CPU. Had to change the graph exports
#       method to display one graph per container.
# items_history_list = [{'name': 'cpu_percent',
#                        'description': 'Container CPU consumption in %',
#                        'y_unit': '%'},
#                       {'name': 'memory_usage',
#                        'description': 'Container memory usage in bytes',
#                        'y_unit': 'B'},
#                       {'name': 'network_rx',
#                        'description': 'Container network RX bitrate in bits per second',
Example #42
0
"""Quicklook plugin."""

from glances.cpu_percent import cpu_percent
from glances.logger import logger
from glances.outputs.glances_bars import Bar
from glances.plugins.glances_plugin import GlancesPlugin

import psutil

# Import plugin specific dependency
try:
    from cpuinfo import cpuinfo
except ImportError as e:
    cpuinfo_tag = False
    logger.warning(
        "Missing Python Lib ({}), Quicklook plugin will not display CPU info".
        format(e))
else:
    cpuinfo_tag = True


class Plugin(GlancesPlugin):
    """Glances quicklook plugin.

    'stats' is a dictionary.
    """
    def __init__(self, args=None):
        """Init the quicklook plugin."""
        super(Plugin, self).__init__(args=args)

        # We want to display the stat in the curse interface
Example #43
0
import operator

from glances.compat import nativestr, PY3
from glances.logger import logger
from glances.plugins.glances_plugin import GlancesPlugin

import psutil
# Use the Wifi Python lib (https://pypi.python.org/pypi/wifi)
# Linux-only
try:
    from wifi.scan import Cell
    from wifi.exceptions import InterfaceError
except ImportError as e:
    import_error_tag = True
    logger.warning(
        "Missing Python Lib ({}), Wifi plugin is disabled".format(e))
else:
    import_error_tag = False

# Python 3 is not supported (see issue #1377)
if PY3:
    import_error_tag = True
    logger.warning(
        "Wifi lib is not compliant with Python 3, Wifi plugin is disabled")


class Plugin(GlancesPlugin):
    """Glances Wifi plugin.

    Get stats of the current Wifi hotspots.
    """