Beispiel #1
0
 def get_stats_display_width(self, curse_msg, without_option=False):
     """Return the width of the formatted curses message."""
     try:
         if without_option:
             # Size without options
             c = len(
                 max(''.join([
                     (u(u(nativestr(i['msg'])).encode('ascii', 'replace'))
                      if not i['optional'] else "")
                     for i in curse_msg['msgdict']
                 ]).split('\n'),
                     key=len))
         else:
             # Size with all options
             c = len(
                 max(''.join([
                     u(u(nativestr(i['msg'])).encode('ascii', 'replace'))
                     for i in curse_msg['msgdict']
                 ]).split('\n'),
                     key=len))
     except Exception as e:
         logger.debug('ERROR: Can not compute plugin width ({})'.format(e))
         return 0
     else:
         return c
Beispiel #2
0
 def update_stats_history(self):
     """Update stats history."""
     # If the plugin data is a dict, the dict's key should be used
     if self.get_key() is None:
         item_name = ''
     else:
         item_name = self.get_key()
     # Build the history
     if self.get_export() and self.history_enable():
         for i in self.get_items_history_list():
             if isinstance(self.get_export(), list):
                 # Stats is a list of data
                 # Iter throught it (for exemple, iter throught network
                 # interface)
                 for l in self.get_export():
                     self.stats_history.add(
                         nativestr(l[item_name]) + '_' +
                         nativestr(i['name']),
                         l[i['name']],
                         description=i['description'],
                         history_max_size=self._limits['history_size'])
             else:
                 # Stats is not a list
                 # Add the item to the history directly
                 self.stats_history.add(
                     nativestr(i['name']),
                     self.get_export()[i['name']],
                     description=i['description'],
                     history_max_size=self._limits['history_size'])
Beispiel #3
0
 def update_stats_history(self):
     """Update stats history."""
     # If the plugin data is a dict, the dict's key should be used
     if self.get_key() is None:
         item_name = ''
     else:
         item_name = self.get_key()
     # Build the history
     if self.get_export() and self._history_enable():
         for i in self.get_items_history_list():
             if isinstance(self.get_export(), list):
                 # Stats is a list of data
                 # Iter throught it (for exemple, iter throught network
                 # interface)
                 for l in self.get_export():
                     self.stats_history.add(
                         nativestr(l[item_name]) + '_' + nativestr(i['name']),
                         l[i['name']],
                         description=i['description'],
                         history_max_size=self._limits['history_size'])
             else:
                 # Stats is not a list
                 # Add the item to the history directly
                 self.stats_history.add(nativestr(i['name']),
                                        self.get_export()[i['name']],
                                        description=i['description'],
                                        history_max_size=self._limits['history_size'])
Beispiel #4
0
    def __update__(self):
        """Update the stats."""
        # Reset the list
        self.reset()

        # Only update if --disable-hddtemp is not set
        if self.args is None or self.args.disable_hddtemp:
            return

        # Fetch the data
        # data = ("|/dev/sda|WDC WD2500JS-75MHB0|44|C|"
        #         "|/dev/sdb|WDC WD2500JS-75MHB0|35|C|"
        #         "|/dev/sdc|WDC WD3200AAKS-75B3A0|45|C|"
        #         "|/dev/sdd|WDC WD3200AAKS-75B3A0|45|C|"
        #         "|/dev/sde|WDC WD3200AAKS-75B3A0|43|C|"
        #         "|/dev/sdf|???|ERR|*|"
        #         "|/dev/sdg|HGST HTS541010A9E680|SLP|*|"
        #         "|/dev/sdh|HGST HTS541010A9E680|UNK|*|")
        data = self.fetch()

        # Exit if no data
        if data == "":
            return

        # Safety check to avoid malformed data
        # Considering the size of "|/dev/sda||0||" as the minimum
        if len(data) < 14:
            data = self.cache if len(self.cache) > 0 else self.fetch()
        self.cache = data

        try:
            fields = data.split(b'|')
        except TypeError:
            fields = ""
        devices = (len(fields) - 1) // 5
        for item in range(devices):
            offset = item * 5
            hddtemp_current = {}
            device = os.path.basename(nativestr(fields[offset + 1]))
            temperature = fields[offset + 3]
            unit = nativestr(fields[offset + 4])
            hddtemp_current['label'] = device
            try:
                hddtemp_current['value'] = float(temperature)
            except ValueError:
                # Temperature could be 'ERR', 'SLP' or 'UNK' (see issue #824)
                # Improper bytes/unicode in glances_hddtemp.py (see issue #887)
                hddtemp_current['value'] = nativestr(temperature)
            hddtemp_current['unit'] = unit
            self.hddtemp_list.append(hddtemp_current)
Beispiel #5
0
    def __update__(self):
        """Update the stats."""
        # Reset the list
        self.reset()

        # Only update if --disable-hddtemp is not set
        if self.args is None or self.args.disable_hddtemp:
            return

        # Fetch the data
        # data = ("|/dev/sda|WDC WD2500JS-75MHB0|44|C|"
        #         "|/dev/sdb|WDC WD2500JS-75MHB0|35|C|"
        #         "|/dev/sdc|WDC WD3200AAKS-75B3A0|45|C|"
        #         "|/dev/sdd|WDC WD3200AAKS-75B3A0|45|C|"
        #         "|/dev/sde|WDC WD3200AAKS-75B3A0|43|C|"
        #         "|/dev/sdf|???|ERR|*|"
        #         "|/dev/sdg|HGST HTS541010A9E680|SLP|*|"
        #         "|/dev/sdh|HGST HTS541010A9E680|UNK|*|")
        data = self.fetch()

        # Exit if no data
        if data == "":
            return

        # Safety check to avoid malformed data
        # Considering the size of "|/dev/sda||0||" as the minimum
        if len(data) < 14:
            data = self.cache if len(self.cache) > 0 else self.fetch()
        self.cache = data

        try:
            fields = data.split(b'|')
        except TypeError:
            fields = ""
        devices = (len(fields) - 1) // 5
        for item in range(devices):
            offset = item * 5
            hddtemp_current = {}
            device = os.path.basename(nativestr(fields[offset + 1]))
            temperature = fields[offset + 3]
            unit = nativestr(fields[offset + 4])
            hddtemp_current['label'] = device
            try:
                hddtemp_current['value'] = float(temperature)
            except ValueError:
                # Temperature could be 'ERR', 'SLP' or 'UNK' (see issue #824)
                # Improper bytes/unicode in glances_hddtemp.py (see issue #887)
                hddtemp_current['value'] = nativestr(temperature)
            hddtemp_current['unit'] = unit
            self.hddtemp_list.append(hddtemp_current)
Beispiel #6
0
def __secure_popen(cmd):
    """A more or less secure way to execute system command
    Manage redirection (>) and pipes (|)
    """
    ret = ''

    # Split by redirection '>'
    cmd_split_redirect = cmd.split('>')
    if len(cmd_split_redirect) > 2:
        return 'Glances error: Only one file redirection allowed ({})'.format(
            cmd)
    elif len(cmd_split_redirect) == 2:
        stdout_redirect = cmd_split_redirect[1].strip()
        cmd = cmd_split_redirect[0]
    else:
        stdout_redirect = None

    sub_cmd_stdin = None
    p_last = None
    # Split by pipe '|'
    for sub_cmd in cmd.split('|'):
        # Split by space ' '
        sub_cmd_split = [i for i in sub_cmd.split(' ') if i]
        p = Popen(sub_cmd_split,
                  shell=False,
                  stdin=sub_cmd_stdin,
                  stdout=PIPE,
                  stderr=PIPE)
        if p_last is not None:
            # Allow p_last to receive a SIGPIPE if p exits.
            p_last.stdout.close()
        p_last = p
        sub_cmd_stdin = p.stdout

    p_ret = p_last.communicate()

    if nativestr(p_ret[1]) == '':
        # No error
        ret = nativestr(p_ret[0])
        if stdout_redirect is not None:
            # Write result to redirection file
            with open(stdout_redirect, "w") as stdout_redirect_file:
                stdout_redirect_file.write(ret)
    else:
        # Error
        ret = nativestr(p_ret[1])

    return ret
Beispiel #7
0
    def __set_folder_list(self, section):
        """Init the monitored folder list.

        The list is defined in the Glances configuration file.
        """
        for l in range(1, self.__folder_list_max_size + 1):
            value = {}
            key = 'folder_' + str(l) + '_'

            # Path is mandatory
            value['indice'] = str(l)
            value['path'] = self.config.get_value(section, key + 'path')
            if value['path'] is None:
                continue
            else:
                value['path'] = nativestr(value['path'])

            # Optional conf keys
            for i in ['careful', 'warning', 'critical']:
                # Read threshold
                value[i] = self.config.get_value(section, key + i)
                if value[i] is not None:
                    logger.debug("{} threshold for folder {} is {}".format(i, value["path"], value[i]))
                # Read action
                action = self.config.get_value(section, key + i + '_action')
                if action is not None:
                    value[i + '_action'] = action
                    logger.debug("{} action for folder {} is {}".format(i, value["path"], value[i + '_action']))

            # Add the item to the list
            self.__folder_list.append(value)
Beispiel #8
0
    def msg_curse(self, args=None, max_width=None):
        """Return the dict to display in the curse interface."""
        # Init the return message
        ret = []

        # Only process if stats exist and display plugin enable...
        if not self.stats or self.is_disable():
            return ret

        # Max size for the interface name
        name_max_width = max_width - 7

        # Header
        msg = '{:{width}}'.format('FOLDERS', width=name_max_width)
        ret.append(self.curse_add_line(msg, "TITLE"))

        # Data
        for i in self.stats:
            ret.append(self.curse_new_line())
            if len(i['path']) > name_max_width:
                # Cut path if it is too long
                path = '_' + i['path'][-name_max_width + 1:]
            else:
                path = i['path']
            msg = '{:{width}}'.format(nativestr(path), width=name_max_width)
            ret.append(self.curse_add_line(msg))
            try:
                msg = '{:>9}'.format(self.auto_unit(i['size']))
            except (TypeError, ValueError):
                msg = '{:>9}'.format(i['size'])
            ret.append(
                self.curse_add_line(
                    msg, self.get_alert(i, header='folder_' + i['indice'])))

        return ret
Beispiel #9
0
    def __set_folder_list(self, section):
        """Init the monitored folder list.

        The list is defined in the Glances configuration file.
        """
        for l in range(1, self.__folder_list_max_size + 1):
            value = {}
            key = 'folder_' + str(l) + '_'

            # Path is mandatory
            value['path'] = self.config.get_value(section, key + 'path')
            if value['path'] is None:
                continue
            else:
                value['path'] = nativestr(value['path'])

            # Optional conf keys
            for i in ['careful', 'warning', 'critical']:
                value[i] = self.config.get_value(section, key + i)
                if value[i] is None:
                    logger.debug("No {} threshold for folder {}".format(
                        i, value["path"]))

            # Add the item to the list
            self.__folder_list.append(value)
Beispiel #10
0
    def msg_curse(self, args=None, max_width=None):
        """Return the dict to display in the curse interface."""
        # Init the return message
        ret = []

        # Only process if stats exist and display plugin enable...
        if not self.stats or self.is_disable():
            return ret

        # Max size for the interface name
        name_max_width = max_width - 7

        # Header
        msg = '{:{width}}'.format('FOLDERS',
                                  width=name_max_width)
        ret.append(self.curse_add_line(msg, "TITLE"))

        # Data
        for i in self.stats:
            ret.append(self.curse_new_line())
            if len(i['path']) > name_max_width:
                # Cut path if it is too long
                path = '_' + i['path'][-name_max_width + 1:]
            else:
                path = i['path']
            msg = '{:{width}}'.format(nativestr(path),
                                      width=name_max_width)
            ret.append(self.curse_add_line(msg))
            try:
                msg = '{:>9}'.format(self.auto_unit(i['size']))
            except (TypeError, ValueError):
                msg = '{:>9}'.format(i['size'])
            ret.append(self.curse_add_line(msg, self.get_alert(i)))

        return ret
Beispiel #11
0
    def _update_pypi_version(self):
        """Get the latest PyPI version (as a string) via the RESTful JSON API"""
        logger.debug(
            "Get latest Glances version from the PyPI RESTful API ({})".format(
                PYPI_API_URL))

        # Update the current time
        self.data[u'refresh_date'] = datetime.now()

        try:
            res = urlopen(PYPI_API_URL, timeout=3).read()
        except (HTTPError, URLError, CertificateError) as e:
            logger.debug(
                "Cannot get Glances version from the PyPI RESTful API ({})".
                format(e))
        else:
            self.data[u'latest_version'] = json.loads(
                nativestr(res))['info']['version']
            logger.debug("Save Glances version to the cache file")

        # Save result to the cache file
        # Note: also saved if the Glances PyPI version cannot be grabbed
        self._save_cache()

        return self.data
Beispiel #12
0
 def get(self):
     """Return the sparkline."""
     ret = sparklines(self.percents)[0]
     if self.__with_text:
         percents_without_none = [x for x in self.percents if x is not None]
         if len(percents_without_none) > 0:
             ret = '{}{:5.1f}%'.format(ret, percents_without_none[-1])
     return nativestr(ret)
Beispiel #13
0
    def msg_curse(self, args=None, max_width=None):
        """Return the dict to display in the curse interface."""
        # Init the return message
        ret = []

        # Only process if stats exist and display plugin enable...
        if not self.stats or self.is_disable():
            return ret

        # Max size for the interface name
        name_max_width = max_width - 12

        # Build the string message
        # Header
        msg = '{:{width}}'.format('FILE SYS', width=name_max_width)
        ret.append(self.curse_add_line(msg, "TITLE"))
        if args.fs_free_space:
            msg = '{:>7}'.format('Free')
        else:
            msg = '{:>7}'.format('Used')
        ret.append(self.curse_add_line(msg))
        msg = '{:>7}'.format('Total')
        ret.append(self.curse_add_line(msg))

        # Filesystem list (sorted by name)
        for i in sorted(self.stats, key=operator.itemgetter(self.get_key())):
            # New line
            ret.append(self.curse_new_line())
            if i['device_name'] == '' or i['device_name'] == 'none':
                mnt_point = i['mnt_point'][-name_max_width + 1:]
            elif len(i['mnt_point']) + len(
                    i['device_name'].split('/')[-1]) <= name_max_width - 3:
                # If possible concatenate mode info... Glances touch inside :)
                mnt_point = i['mnt_point'] + ' (' + i['device_name'].split(
                    '/')[-1] + ')'
            elif len(i['mnt_point']) > name_max_width:
                # Cut mount point name if it is too long
                mnt_point = '_' + i['mnt_point'][-name_max_width + 1:]
            else:
                mnt_point = i['mnt_point']
            msg = '{:{width}}'.format(nativestr(mnt_point),
                                      width=name_max_width)
            ret.append(self.curse_add_line(msg))
            if args.fs_free_space:
                msg = '{:>7}'.format(self.auto_unit(i['free']))
            else:
                msg = '{:>7}'.format(self.auto_unit(i['used']))
            ret.append(
                self.curse_add_line(
                    msg,
                    self.get_views(item=i[self.get_key()],
                                   key='used',
                                   option='decoration')))
            msg = '{:>7}'.format(self.auto_unit(i['size']))
            ret.append(self.curse_add_line(msg))

        return ret
Beispiel #14
0
    def msg_curse(self, args=None, max_width=None):
        """Return the dict to display in the curse interface."""
        # Init the return message
        ret = []

        # Only process if stats exist and display plugin enable...
        if not self.stats or self.is_disable():
            return ret

        # Header
        if self.net_connections_enabled or self.nf_conntrack_enabled:
            msg = '{}'.format('TCP CONNECTIONS')
            ret.append(self.curse_add_line(msg, "TITLE"))
        # Connections status
        if self.net_connections_enabled:
            for s in [
                    psutil.CONN_LISTEN, 'initiated', psutil.CONN_ESTABLISHED,
                    'terminated'
            ]:
                ret.append(self.curse_new_line())
                msg = '{:{width}}'.format(nativestr(s).capitalize(),
                                          width=len(s))
                ret.append(self.curse_add_line(msg))
                msg = '{:>{width}}'.format(self.stats[s],
                                           width=max_width - len(s) + 2)
                ret.append(self.curse_add_line(msg))
        # Connections track
        if self.nf_conntrack_enabled:
            s = 'Tracked'
            ret.append(self.curse_new_line())
            msg = '{:{width}}'.format(nativestr(s).capitalize(), width=len(s))
            ret.append(self.curse_add_line(msg))
            msg = '{:>{width}}'.format('{:0.0f}/{:0.0f}'.format(
                self.stats['nf_conntrack_count'],
                self.stats['nf_conntrack_max']),
                                       width=max_width - len(s) + 2)
            ret.append(
                self.curse_add_line(
                    msg,
                    self.get_views(key='nf_conntrack_percent',
                                   option='decoration')))

        return ret
Beispiel #15
0
    def msg_curse(self, args=None, max_width=None):
        """Return the dict to display in the curse interface."""
        # Init the return message
        ret = []

        # Only process if stats exist and display plugin enable...
        if not self.stats or self.is_disable():
            return ret

        # Max size for the interface name
        name_max_width = max_width - 12

        # Build the string message
        # Header
        msg = '{:{width}}'.format('FILE SYS', width=name_max_width)
        ret.append(self.curse_add_line(msg, "TITLE"))
        if args.fs_free_space:
            msg = '{:>7}'.format('Free')
        else:
            msg = '{:>7}'.format('Used')
        ret.append(self.curse_add_line(msg))
        msg = '{:>7}'.format('Total')
        ret.append(self.curse_add_line(msg))

        # Filesystem list (sorted by name)
        for i in sorted(self.stats, key=operator.itemgetter(self.get_key())):
            # New line
            ret.append(self.curse_new_line())
            if i['device_name'] == '' or i['device_name'] == 'none':
                mnt_point = i['mnt_point'][-name_max_width + 1:]
            elif len(i['mnt_point']) + len(i['device_name'].split('/')[-1]) <= name_max_width - 3:
                # If possible concatenate mode info... Glances touch inside :)
                mnt_point = i['mnt_point'] + ' (' + i['device_name'].split('/')[-1] + ')'
            elif len(i['mnt_point']) > name_max_width:
                # Cut mount point name if it is too long
                mnt_point = '_' + i['mnt_point'][-name_max_width + 1:]
            else:
                mnt_point = i['mnt_point']
            msg = '{:{width}}'.format(nativestr(mnt_point),
                                      width=name_max_width)
            ret.append(self.curse_add_line(msg))
            if args.fs_free_space:
                msg = '{:>7}'.format(self.auto_unit(i['free']))
            else:
                msg = '{:>7}'.format(self.auto_unit(i['used']))
            ret.append(self.curse_add_line(msg, self.get_views(item=i[self.get_key()],
                                                               key='used',
                                                               option='decoration')))
            msg = '{:>7}'.format(self.auto_unit(i['size']))
            ret.append(self.curse_add_line(msg))

        return ret
Beispiel #16
0
    def __update__(self):
        """Update the stats."""
        # Reset the list
        self.reset()

        # Only update if --disable-hddtemp is not set
        if self.args is None or self.args.disable_hddtemp:
            return

        # Fetch the data
        data = self.fetch()

        # Exit if no data
        if data == "":
            return

        # Safety check to avoid malformed data
        # Considering the size of "|/dev/sda||0||" as the minimum
        if len(data) < 14:
            data = self.cache if len(self.cache) > 0 else self.fetch()
        self.cache = data

        try:
            fields = data.split(b'|')
        except TypeError:
            fields = ""
        devices = (len(fields) - 1) // 5
        for item in range(devices):
            offset = item * 5
            hddtemp_current = {}
            device = os.path.basename(nativestr(fields[offset + 1]))
            temperature = fields[offset + 3]
            unit = nativestr(fields[offset + 4])
            hddtemp_current['label'] = device
            hddtemp_current['value'] = float(
                temperature) if temperature != b'ERR' else temperature
            hddtemp_current['unit'] = unit
            self.hddtemp_list.append(hddtemp_current)
Beispiel #17
0
    def __update__(self):
        """Update the stats."""
        # Reset the list
        self.reset()

        # Only update if --disable-hddtemp is not set
        if self.args is None or self.args.disable_hddtemp:
            return

        # Fetch the data
        data = self.fetch()

        # Exit if no data
        if data == "":
            return

        # Safety check to avoid malformed data
        # Considering the size of "|/dev/sda||0||" as the minimum
        if len(data) < 14:
            data = self.cache if len(self.cache) > 0 else self.fetch()
        self.cache = data

        try:
            fields = data.split(b'|')
        except TypeError:
            fields = ""
        devices = (len(fields) - 1) // 5
        for item in range(devices):
            offset = item * 5
            hddtemp_current = {}
            device = os.path.basename(nativestr(fields[offset + 1]))
            temperature = fields[offset + 3]
            unit = nativestr(fields[offset + 4])
            hddtemp_current['label'] = device
            # Temperature could be 'ERR' or 'SLP' (see issue#824)
            hddtemp_current['value'] = float(temperature) if isinstance(temperature, numbers.Number) else temperature
            hddtemp_current['unit'] = unit
            self.hddtemp_list.append(hddtemp_current)
Beispiel #18
0
    def msg_curse(self, args=None, max_width=None):
        """Return the dict to display in the curse interface."""
        # Init the return message
        ret = []

        # Only process if stats exist and display plugin enable...
        if not self.stats or import_error_tag or self.is_disable():
            return ret

        # Max size for the interface name
        ifname_max_width = max_width - 5

        # Build the string message
        # Header
        msg = '{:{width}}'.format('WIFI', width=ifname_max_width)
        ret.append(self.curse_add_line(msg, "TITLE"))
        msg = '{:>7}'.format('dBm')
        ret.append(self.curse_add_line(msg))

        # Hotspot list (sorted by name)
        for i in sorted(self.stats, key=operator.itemgetter(self.get_key())):
            # Do not display hotspot with no name (/ssid)...
            # of ssid None... See issue #1151
            if i['ssid'] == '' or i['ssid'] is None:
                continue
            ret.append(self.curse_new_line())
            # New hotspot
            hotspotname = i['ssid']
            # Add the encryption type (if it is available)
            if i['encrypted']:
                hotspotname += ' {}'.format(i['encryption_type'])
            # Cut hotspotname if it is too long
            if len(hotspotname) > ifname_max_width:
                hotspotname = '_' + hotspotname[-ifname_max_width + 1:]
            # Add the new hotspot to the message
            msg = '{:{width}}'.format(nativestr(hotspotname),
                                      width=ifname_max_width)
            ret.append(self.curse_add_line(msg))
            msg = '{:>7}'.format(i['signal'], width=ifname_max_width)
            ret.append(
                self.curse_add_line(
                    msg,
                    self.get_views(item=i[self.get_key()],
                                   key='signal',
                                   option='decoration')))

        return ret
Beispiel #19
0
    def msg_curse(self, args=None, max_width=None):
        """Return the dict to display in the curse interface."""
        # Init the return message
        ret = []

        # Only process if stats exist and display plugin enable...
        if not self.stats or import_error_tag or self.is_disable():
            return ret

        # Max size for the interface name
        ifname_max_width = max_width - 5

        # Build the string message
        # Header
        msg = '{:{width}}'.format('WIFI', width=ifname_max_width)
        ret.append(self.curse_add_line(msg, "TITLE"))
        msg = '{:>7}'.format('dBm')
        ret.append(self.curse_add_line(msg))

        # Hotspot list (sorted by name)
        for i in sorted(self.stats, key=operator.itemgetter(self.get_key())):
            # Do not display hotspot with no name (/ssid)...
            # of ssid None... See issue #1151
            if i['ssid'] == '' or i['ssid'] is None:
                continue
            ret.append(self.curse_new_line())
            # New hotspot
            hotspotname = i['ssid']
            # Add the encryption type (if it is available)
            if i['encrypted']:
                hotspotname += ' {}'.format(i['encryption_type'])
            # Cut hotspotname if it is too long
            if len(hotspotname) > ifname_max_width:
                hotspotname = '_' + hotspotname[-ifname_max_width + 1:]
            # Add the new hotspot to the message
            msg = '{:{width}}'.format(nativestr(hotspotname),
                                      width=ifname_max_width)
            ret.append(self.curse_add_line(msg))
            msg = '{:>7}'.format(i['signal'], width=ifname_max_width)
            ret.append(self.curse_add_line(msg,
                                           self.get_views(item=i[self.get_key()],
                                                          key='signal',
                                                          option='decoration')))

        return ret
Beispiel #20
0
    def _update_pypi_version(self):
        """Get the latest PyPI version (as a string) via the RESTful JSON API"""
        logger.debug("Get latest Glances version from the PyPI RESTful API ({})".format(PYPI_API_URL))

        # Update the current time
        self.data[u'refresh_date'] = datetime.now()

        try:
            res = urlopen(PYPI_API_URL, timeout=3).read()
        except (HTTPError, URLError) as e:
            logger.debug("Cannot get Glances version from the PyPI RESTful API ({})".format(e))
        else:
            self.data[u'latest_version'] = json.loads(nativestr(res))['info']['version']
            logger.debug("Save Glances version to the cache file")

        # Save result to the cache file
        # Note: also saved if the Glances PyPI version cannot be grabbed
        self._save_cache()

        return self.data
Beispiel #21
0
    def __set_folder_list(self, section):
        """Init the monitored folder list.

        The list is defined in the Glances configuration file.
        """
        for l in range(1, self.__folder_list_max_size + 1):
            value = {}
            key = 'folder_' + str(l) + '_'

            # Path is mandatory
            value['indice'] = str(l)
            value['path'] = self.config.get_value(section, key + 'path')
            if value['path'] is None:
                continue
            else:
                value['path'] = nativestr(value['path'])

            # Optional conf keys
            # Refresh time
            value['refresh'] = int(
                self.config.get_value(section,
                                      key + 'refresh',
                                      default=self.__default_refresh))
            self.timer_folders.append(Timer(value['refresh']))
            # Thesholds
            for i in ['careful', 'warning', 'critical']:
                # Read threshold
                value[i] = self.config.get_value(section, key + i)
                if value[i] is not None:
                    logger.debug("{} threshold for folder {} is {}".format(
                        i, value["path"], value[i]))
                # Read action
                action = self.config.get_value(section, key + i + '_action')
                if action is not None:
                    value[i + '_action'] = action
                    logger.debug("{} action for folder {} is {}".format(
                        i, value["path"], value[i + '_action']))

            # Add the item to the list
            self.__folder_list.append(value)
Beispiel #22
0
    def msg_curse(self, args=None, max_width=None):
        """Return the dict to display in the curse interface."""
        # Init the return message
        ret = []

        # Only process if stats exist and display plugin enable...
        if not self.stats or self.is_disable():
            return ret

        # Max size for the interface name
        name_max_width = max_width - 12

        # Header
        msg = '{:{width}}'.format('DISK I/O', width=name_max_width)
        ret.append(self.curse_add_line(msg, "TITLE"))
        if args.diskio_iops:
            msg = '{:>7}'.format('IOR/s')
            ret.append(self.curse_add_line(msg))
            msg = '{:>7}'.format('IOW/s')
            ret.append(self.curse_add_line(msg))
        else:
            msg = '{:>7}'.format('R/s')
            ret.append(self.curse_add_line(msg))
            msg = '{:>7}'.format('W/s')
            ret.append(self.curse_add_line(msg))
        # Disk list (sorted by name)
        for i in self.sorted_stats():
            # Is there an alias for the disk name ?
            disk_real_name = i['disk_name']
            disk_name = self.has_alias(i['disk_name'])
            if disk_name is None:
                disk_name = disk_real_name
            # New line
            ret.append(self.curse_new_line())
            if len(disk_name) > name_max_width:
                # Cut disk name if it is too long
                disk_name = '_' + disk_name[-name_max_width:]
            msg = '{:{width}}'.format(nativestr(disk_name),
                                      width=name_max_width)
            ret.append(self.curse_add_line(msg))
            if args.diskio_iops:
                # count
                txps = self.auto_unit(
                    int(i['read_count'] // i['time_since_update']))
                rxps = self.auto_unit(
                    int(i['write_count'] // i['time_since_update']))
                msg = '{:>7}'.format(txps)
                ret.append(self.curse_add_line(msg,
                                               self.get_views(item=i[self.get_key()],
                                                              key='read_count',
                                                              option='decoration')))
                msg = '{:>7}'.format(rxps)
                ret.append(self.curse_add_line(msg,
                                               self.get_views(item=i[self.get_key()],
                                                              key='write_count',
                                                              option='decoration')))
            else:
                # Bitrate
                txps = self.auto_unit(
                    int(i['read_bytes'] // i['time_since_update']))
                rxps = self.auto_unit(
                    int(i['write_bytes'] // i['time_since_update']))
                msg = '{:>7}'.format(txps)
                ret.append(self.curse_add_line(msg,
                                               self.get_views(item=i[self.get_key()],
                                                              key='read_bytes',
                                                              option='decoration')))
                msg = '{:>7}'.format(rxps)
                ret.append(self.curse_add_line(msg,
                                               self.get_views(item=i[self.get_key()],
                                                              key='write_bytes',
                                                              option='decoration')))

        return ret
    def msg_curse(self, args=None, max_width=None):
        """Return the dict to display in the curse interface."""
        # Init the return message
        ret = []

        # Only process if stats exist and display plugin enable...
        if not self.stats or self.is_disable():
            return ret

        # Max size for the interface name
        name_max_width = max_width - 12

        # Header
        msg = '{:{width}}'.format('DISK I/O', width=name_max_width)
        ret.append(self.curse_add_line(msg, "TITLE"))
        if args.diskio_iops:
            msg = '{:>7}'.format('IOR/s')
            ret.append(self.curse_add_line(msg))
            msg = '{:>7}'.format('IOW/s')
            ret.append(self.curse_add_line(msg))
        else:
            msg = '{:>7}'.format('R/s')
            ret.append(self.curse_add_line(msg))
            msg = '{:>7}'.format('W/s')
            ret.append(self.curse_add_line(msg))
        # Disk list (sorted by name)
        for i in self.sorted_stats():
            # Is there an alias for the disk name ?
            disk_real_name = i['disk_name']
            disk_name = self.has_alias(i['disk_name'])
            if disk_name is None:
                disk_name = disk_real_name
            # New line
            ret.append(self.curse_new_line())
            if len(disk_name) > name_max_width:
                # Cut disk name if it is too long
                disk_name = '_' + disk_name[-name_max_width:]
            msg = '{:{width}}'.format(nativestr(disk_name),
                                      width=name_max_width)
            ret.append(self.curse_add_line(msg))
            if args.diskio_iops:
                # count
                txps = self.auto_unit(
                    int(i['read_count'] // i['time_since_update']))
                rxps = self.auto_unit(
                    int(i['write_count'] // i['time_since_update']))
                msg = '{:>7}'.format(txps)
                ret.append(self.curse_add_line(msg,
                                               self.get_views(item=i[self.get_key()],
                                                              key='read_count',
                                                              option='decoration')))
                msg = '{:>7}'.format(rxps)
                ret.append(self.curse_add_line(msg,
                                               self.get_views(item=i[self.get_key()],
                                                              key='write_count',
                                                              option='decoration')))
            else:
                # Bitrate
                txps = self.auto_unit(
                    int(i['read_bytes'] // i['time_since_update']))
                rxps = self.auto_unit(
                    int(i['write_bytes'] // i['time_since_update']))
                msg = '{:>7}'.format(txps)
                ret.append(self.curse_add_line(msg,
                                               self.get_views(item=i[self.get_key()],
                                                              key='read_bytes',
                                                              option='decoration')))
                msg = '{:>7}'.format(rxps)
                ret.append(self.curse_add_line(msg,
                                               self.get_views(item=i[self.get_key()],
                                                              key='write_bytes',
                                                              option='decoration')))

        return ret
Beispiel #24
0
def get_device_name(device_handle):
    """Get GPU device name."""
    try:
        return nativestr(pynvml.nvmlDeviceGetName(device_handle))
    except pynvml.NVMlError:
        return "NVIDIA"
Beispiel #25
0
    def update(self):
        """Update Docker stats using the input method."""
        # Init new stats
        stats = self.get_init_value()

        # The Docker-py lib is mandatory
        if import_error_tag:
            return self.stats

        if self.input_method == 'local':
            # Update stats

            # Docker version
            # Exemple: {
            #     "KernelVersion": "3.16.4-tinycore64",
            #     "Arch": "amd64",
            #     "ApiVersion": "1.15",
            #     "Version": "1.3.0",
            #     "GitCommit": "c78088f",
            #     "Os": "linux",
            #     "GoVersion": "go1.3.3"
            # }
            try:
                stats['version'] = self.docker_client.version()
            except Exception as e:
                # Correct issue#649
                logger.error("{} plugin - Cannot get Docker version ({})".format(self.plugin_name, e))
                return self.stats

            # Update current containers list
            try:
                # Issue #1152: Docker module doesn't export details about stopped containers
                # The Docker/all key of the configuration file should be set to True
                containers = self.docker_client.containers.list(all=self._all_tag()) or []
            except Exception as e:
                logger.error("{} plugin - Cannot get containers list ({})".format(self.plugin_name, e))
                return self.stats

            # Start new thread for new container
            for container in containers:
                if container.id not in self.thread_list:
                    # Thread did not exist in the internal dict
                    # Create it and add it to the internal dict
                    logger.debug("{} plugin - Create thread for container {}".format(self.plugin_name, container.id[:12]))
                    t = ThreadDockerGrabber(container)
                    self.thread_list[container.id] = t
                    t.start()

            # Stop threads for non-existing containers
            nonexisting_containers = set(iterkeys(self.thread_list)) - set([c.id for c in containers])
            for container_id in nonexisting_containers:
                # Stop the thread
                logger.debug("{} plugin - Stop thread for old container {}".format(self.plugin_name, container_id[:12]))
                self.thread_list[container_id].stop()
                # Delete the item from the dict
                del self.thread_list[container_id]

            # Get stats for all containers
            stats['containers'] = []
            for container in containers:
                # Init the stats for the current container
                container_stats = {}
                # The key is the container name and not the Id
                container_stats['key'] = self.get_key()
                # Export name (first name in the Names list, without the /)
                container_stats['name'] = nativestr(container.name)
                # Export global Names (used by the WebUI)
                container_stats['Names'] = [ nativestr(container.name)]
                # Container Id
                container_stats['Id'] = container.id
                # Container Image
                container_stats['Image'] = container.image.tags
                # Global stats (from attrs)
                container_stats['Status'] = container.attrs['State']['Status']
                container_stats['Command'] = container.attrs['Config']['Entrypoint']
                # Standards stats
                if container_stats['Status'] in ('running', 'paused'):
                    container_stats['cpu'] = self.get_docker_cpu(container.id, self.thread_list[container.id].stats)
                    container_stats['cpu_percent'] = container_stats['cpu'].get('total', None)
                    container_stats['memory'] = self.get_docker_memory(container.id, self.thread_list[container.id].stats)
                    container_stats['memory_usage'] = container_stats['memory'].get('usage', None)
                    container_stats['io'] = self.get_docker_io(container.id, self.thread_list[container.id].stats)
                    container_stats['io_r'] = container_stats['io'].get('ior', None)
                    container_stats['io_w'] = container_stats['io'].get('iow', None)
                    container_stats['network'] = self.get_docker_network(container.id, self.thread_list[container.id].stats)
                    container_stats['network_rx'] = container_stats['network'].get('rx', None)
                    container_stats['network_tx'] = container_stats['network'].get('tx', None)
                else:
                    container_stats['cpu'] = {}
                    container_stats['cpu_percent'] = None
                    container_stats['memory'] = {}
                    container_stats['memory_percent'] = None
                    container_stats['io'] = {}
                    container_stats['io_r'] = None
                    container_stats['io_w'] = None
                    container_stats['network'] = {}
                    container_stats['network_rx'] = None
                    container_stats['network_tx'] = None
                # Add current container stats to the stats list
                stats['containers'].append(container_stats)

        elif self.input_method == 'snmp':
            # Update stats using SNMP
            # Not available
            pass

        # Update the stats
        self.stats = stats

        return self.stats
Beispiel #26
0
def get_device_name(device_handle):
    """Get GPU device name."""
    try:
        return nativestr(pynvml.nvmlDeviceGetName(device_handle))
    except pynvml.NVMlError:
        return "NVIDIA"
Beispiel #27
0
    def update(self):
        """Update Docker stats using the input method."""
        # Init new stats
        stats = self.get_init_value()

        # The Docker-py lib is mandatory
        if import_error_tag:
            return self.stats

        if self.input_method == 'local':
            # Update stats

            # Docker version
            # Exemple: {
            #     "KernelVersion": "3.16.4-tinycore64",
            #     "Arch": "amd64",
            #     "ApiVersion": "1.15",
            #     "Version": "1.3.0",
            #     "GitCommit": "c78088f",
            #     "Os": "linux",
            #     "GoVersion": "go1.3.3"
            # }
            try:
                stats['version'] = self.docker_client.version()
            except Exception as e:
                # Correct issue#649
                logger.error(
                    "{} plugin - Cannot get Docker version ({})".format(
                        self.plugin_name, e))
                # We may have lost connection remove version info
                if 'version' in self.stats:
                    del self.stats['version']
                self.stats['containers'] = []
                return self.stats

            # Update current containers list
            try:
                # Issue #1152: Docker module doesn't export details about stopped containers
                # The Docker/all key of the configuration file should be set to True
                containers = self.docker_client.containers.list(
                    all=self._all_tag()) or []
            except Exception as e:
                logger.error(
                    "{} plugin - Cannot get containers list ({})".format(
                        self.plugin_name, e))
                # We may have lost connection empty the containers list.
                self.stats['containers'] = []
                return self.stats

            # Start new thread for new container
            for container in containers:
                if container.id not in self.thread_list:
                    # Thread did not exist in the internal dict
                    # Create it and add it to the internal dict
                    logger.debug(
                        "{} plugin - Create thread for container {}".format(
                            self.plugin_name, container.id[:12]))
                    t = ThreadDockerGrabber(container)
                    self.thread_list[container.id] = t
                    t.start()

            # Stop threads for non-existing containers
            nonexisting_containers = set(iterkeys(self.thread_list)) - set(
                [c.id for c in containers])
            for container_id in nonexisting_containers:
                # Stop the thread
                logger.debug(
                    "{} plugin - Stop thread for old container {}".format(
                        self.plugin_name, container_id[:12]))
                self.thread_list[container_id].stop()
                # Delete the item from the dict
                del self.thread_list[container_id]

            # Get stats for all containers
            stats['containers'] = []
            for container in containers:
                # Init the stats for the current container
                container_stats = {}
                # The key is the container name and not the Id
                container_stats['key'] = self.get_key()
                # Export name (first name in the Names list, without the /)
                container_stats['name'] = nativestr(container.name)
                # Export global Names (used by the WebUI)
                container_stats['Names'] = [nativestr(container.name)]
                # Container Id
                container_stats['Id'] = container.id
                # Container Image
                container_stats['Image'] = container.image.tags
                # Global stats (from attrs)
                container_stats['Status'] = container.attrs['State']['Status']
                container_stats['Command'] = container.attrs['Config'][
                    'Entrypoint']
                # Standards stats
                if container_stats['Status'] in ('running', 'paused'):
                    container_stats['cpu'] = self.get_docker_cpu(
                        container.id, self.thread_list[container.id].stats)
                    container_stats['cpu_percent'] = container_stats[
                        'cpu'].get('total', None)
                    container_stats['memory'] = self.get_docker_memory(
                        container.id, self.thread_list[container.id].stats)
                    container_stats['memory_usage'] = container_stats[
                        'memory'].get('usage', None)
                    container_stats['io'] = self.get_docker_io(
                        container.id, self.thread_list[container.id].stats)
                    container_stats['io_r'] = container_stats['io'].get(
                        'ior', None)
                    container_stats['io_w'] = container_stats['io'].get(
                        'iow', None)
                    container_stats['network'] = self.get_docker_network(
                        container.id, self.thread_list[container.id].stats)
                    container_stats['network_rx'] = container_stats[
                        'network'].get('rx', None)
                    container_stats['network_tx'] = container_stats[
                        'network'].get('tx', None)
                else:
                    container_stats['cpu'] = {}
                    container_stats['cpu_percent'] = None
                    container_stats['memory'] = {}
                    container_stats['memory_percent'] = None
                    container_stats['io'] = {}
                    container_stats['io_r'] = None
                    container_stats['io_w'] = None
                    container_stats['network'] = {}
                    container_stats['network_rx'] = None
                    container_stats['network_tx'] = None
                # Add current container stats to the stats list
                stats['containers'].append(container_stats)

        elif self.input_method == 'snmp':
            # Update stats using SNMP
            # Not available
            pass

        # Sort and update the stats
        self.stats = sort_stats(stats)

        return self.stats