Beispiel #1
0
    def __init__(self, config_dir=None):
        self.config_dir = config_dir
        self.config_filename = 'glances.conf'
        self._loaded_config_file = None

        self.parser = ConfigParser()
        self.read()
Beispiel #2
0
    def __init__(self, config_dir=None):
        self.config_dir = config_dir
        self.config_filename = 'glances.conf'
        self._loaded_config_file = None

        # Re patern for optimize research of `foo`
        self.re_pattern = re.compile('(\`.+?\`)')

        self.parser = ConfigParser()
        self.read()
Beispiel #3
0
    def __init__(self, config_dir=None):
        self.config_dir = config_dir
        self.config_filename = 'glances.conf'
        self._loaded_config_file = None

        # Re patern for optimize research of `foo`
        self.re_pattern = re.compile(r'(\`.+?\`)')

        try:
            self.parser = ConfigParser(interpolation=None)
        except TypeError:
            self.parser = ConfigParser()

        self.read()
Beispiel #4
0
    def __init__(self, config_dir=None):
        self.config_dir = config_dir
        self.config_filename = 'glances.conf'
        self._loaded_config_file = None

        self.parser = ConfigParser()
        self.read()
Beispiel #5
0
    def __init__(self, config_dir=None):
        self.config_dir = config_dir
        self.config_filename = 'glances.conf'
        self._loaded_config_file = None

        # Re patern for optimize research of `foo`
        self.re_pattern = re.compile('(\`.+?\`)')

        self.parser = ConfigParser()
        self.read()
Beispiel #6
0
class Config(object):
    """This class is used to access/read config file, if it exists.

    :param config_dir: the path to search for config file
    :type config_dir: str or None
    """
    def __init__(self, config_dir=None):
        self.config_dir = config_dir
        self.config_filename = 'glances.conf'
        self._loaded_config_file = None

        self.parser = ConfigParser()
        self.read()

    def config_file_paths(self):
        r"""Get a list of config file paths.

        The list is built taking into account of the OS, priority and location.

        * custom path: /path/to/glances
        * Linux: ~/.config/glances, /etc/glances
        * BSD: ~/.config/glances, /usr/local/etc/glances
        * OS X: ~/Library/Application Support/glances, /usr/local/etc/glances
        * Windows: %APPDATA%\glances

        The config file will be searched in the following order of priority:
            * /path/to/file (via -C flag)
            * user's home directory (per-user settings)
            * system-wide directory (system-wide settings)
        """
        paths = []

        if self.config_dir:
            paths.append(self.config_dir)

        if LINUX or BSD:
            paths.append(
                os.path.join(
                    os.environ.get('XDG_CONFIG_HOME')
                    or os.path.expanduser('~/.config'), appname,
                    self.config_filename))
            if BSD:
                paths.append(
                    os.path.join(sys.prefix, 'etc', appname,
                                 self.config_filename))
            else:
                paths.append(
                    os.path.join('/etc', appname, self.config_filename))
        elif OSX:
            paths.append(
                os.path.join(
                    os.path.expanduser('~/Library/Application Support/'),
                    appname, self.config_filename))
            paths.append(
                os.path.join(sys_prefix, 'etc', appname, self.config_filename))
        elif WINDOWS:
            paths.append(
                os.path.join(os.environ.get('APPDATA'), appname,
                             self.config_filename))

        return paths

    def read(self):
        """Read the config file, if it exists. Using defaults otherwise."""
        for config_file in self.config_file_paths():
            if os.path.exists(config_file):
                try:
                    with open(config_file, encoding='utf-8') as f:
                        self.parser.read_file(f)
                        self.parser.read(f)
                    logger.info(
                        "Read configuration file '{0}'".format(config_file))
                except UnicodeDecodeError as err:
                    logger.error(
                        "Cannot decode configuration file '{0}': {1}".format(
                            config_file, err))
                    sys.exit(1)
                # Save the loaded configuration file path (issue #374)
                self._loaded_config_file = config_file
                break

        # Quicklook
        if not self.parser.has_section('quicklook'):
            self.parser.add_section('quicklook')
            self.parser.set('quicklook', 'cpu_careful', '50')
            self.parser.set('quicklook', 'cpu_warning', '70')
            self.parser.set('quicklook', 'cpu_critical', '90')
            self.parser.set('quicklook', 'mem_careful', '50')
            self.parser.set('quicklook', 'mem_warning', '70')
            self.parser.set('quicklook', 'mem_critical', '90')
            self.parser.set('quicklook', 'swap_careful', '50')
            self.parser.set('quicklook', 'swap_warning', '70')
            self.parser.set('quicklook', 'swap_critical', '90')

        # CPU
        if not self.parser.has_section('cpu'):
            self.parser.add_section('cpu')
            self.parser.set('cpu', 'user_careful', '50')
            self.parser.set('cpu', 'user_warning', '70')
            self.parser.set('cpu', 'user_critical', '90')
            self.parser.set('cpu', 'iowait_careful', '50')
            self.parser.set('cpu', 'iowait_warning', '70')
            self.parser.set('cpu', 'iowait_critical', '90')
            self.parser.set('cpu', 'system_careful', '50')
            self.parser.set('cpu', 'system_warning', '70')
            self.parser.set('cpu', 'system_critical', '90')
            self.parser.set('cpu', 'steal_careful', '50')
            self.parser.set('cpu', 'steal_warning', '70')
            self.parser.set('cpu', 'steal_critical', '90')

        # Per-CPU
        if not self.parser.has_section('percpu'):
            self.parser.add_section('percpu')
            self.parser.set('percpu', 'user_careful', '50')
            self.parser.set('percpu', 'user_warning', '70')
            self.parser.set('percpu', 'user_critical', '90')
            self.parser.set('percpu', 'iowait_careful', '50')
            self.parser.set('percpu', 'iowait_warning', '70')
            self.parser.set('percpu', 'iowait_critical', '90')
            self.parser.set('percpu', 'system_careful', '50')
            self.parser.set('percpu', 'system_warning', '70')
            self.parser.set('percpu', 'system_critical', '90')

        # Load
        if not self.parser.has_section('load'):
            self.parser.add_section('load')
            self.parser.set('load', 'careful', '0.7')
            self.parser.set('load', 'warning', '1.0')
            self.parser.set('load', 'critical', '5.0')

        # Mem
        if not self.parser.has_section('mem'):
            self.parser.add_section('mem')
            self.parser.set('mem', 'careful', '50')
            self.parser.set('mem', 'warning', '70')
            self.parser.set('mem', 'critical', '90')

        # Swap
        if not self.parser.has_section('memswap'):
            self.parser.add_section('memswap')
            self.parser.set('memswap', 'careful', '50')
            self.parser.set('memswap', 'warning', '70')
            self.parser.set('memswap', 'critical', '90')

        # FS
        if not self.parser.has_section('fs'):
            self.parser.add_section('fs')
            self.parser.set('fs', 'careful', '50')
            self.parser.set('fs', 'warning', '70')
            self.parser.set('fs', 'critical', '90')

        # Sensors
        if not self.parser.has_section('sensors'):
            self.parser.add_section('sensors')
            self.parser.set('sensors', 'temperature_core_careful', '60')
            self.parser.set('sensors', 'temperature_core_warning', '70')
            self.parser.set('sensors', 'temperature_core_critical', '80')
            self.parser.set('sensors', 'temperature_hdd_careful', '45')
            self.parser.set('sensors', 'temperature_hdd_warning', '52')
            self.parser.set('sensors', 'temperature_hdd_critical', '60')
            self.parser.set('sensors', 'battery_careful', '80')
            self.parser.set('sensors', 'battery_warning', '90')
            self.parser.set('sensors', 'battery_critical', '95')

        # Process list
        if not self.parser.has_section('processlist'):
            self.parser.add_section('processlist')
            self.parser.set('processlist', 'cpu_careful', '50')
            self.parser.set('processlist', 'cpu_warning', '70')
            self.parser.set('processlist', 'cpu_critical', '90')
            self.parser.set('processlist', 'mem_careful', '50')
            self.parser.set('processlist', 'mem_warning', '70')
            self.parser.set('processlist', 'mem_critical', '90')

    @property
    def loaded_config_file(self):
        """Return the loaded configuration file."""
        return self._loaded_config_file

    def items(self, section):
        """Return the items list of a section."""
        return self.parser.items(section)

    def has_section(self, section):
        """Return info about the existence of a section."""
        return self.parser.has_section(section)

    def get_value(self, section, option, default=None):
        """Get the value of an option, if it exists."""
        try:
            return self.parser.get(section, option)
        except NoOptionError:
            return default

    def get_float_value(self, section, option, default=0.0):
        """Get the float value of an option, if it exists."""
        try:
            return self.parser.getfloat(section, option)
        except NoOptionError:
            return float(default)
Beispiel #7
0
class Config(object):
    """This class is used to access/read config file, if it exists.

    :param config_dir: the path to search for config file
    :type config_dir: str or None
    """
    def __init__(self, config_dir=None):
        self.config_dir = config_dir
        self.config_filename = 'glances.conf'
        self._loaded_config_file = None

        self.parser = ConfigParser()
        self.read()

    def config_file_paths(self):
        r"""Get a list of config file paths.

        The list is built taking into account of the OS, priority and location.

        * custom path: /path/to/glances
        * Linux: ~/.config/glances, /etc/glances
        * *BSD: ~/.config/glances, /usr/local/etc/glances
        * macOS: ~/Library/Application Support/glances, /usr/local/etc/glances
        * Windows: %APPDATA%\glances

        The config file will be searched in the following order of priority:
            * /path/to/file (via -C flag)
            * user's home directory (per-user settings)
            * system-wide directory (system-wide settings)
        """
        paths = []

        if self.config_dir:
            paths.append(self.config_dir)

        if LINUX or BSD:
            paths.append(
                os.path.join(
                    os.environ.get('XDG_CONFIG_HOME')
                    or os.path.expanduser('~/.config'), 'glances',
                    self.config_filename))
            if BSD:
                paths.append(
                    os.path.join(sys.prefix, 'etc', 'glances',
                                 self.config_filename))
            else:
                paths.append(os.path.join('/etc/glances',
                                          self.config_filename))
        elif MACOS:
            paths.append(
                os.path.join(
                    os.path.expanduser(
                        '~/Library/Application Support/glances'),
                    self.config_filename))
            paths.append(
                os.path.join(sys_prefix, 'etc', 'glances',
                             self.config_filename))
        elif WINDOWS:
            paths.append(
                os.path.join(os.environ.get('APPDATA'), 'glances',
                             self.config_filename))

        return paths

    def read(self):
        """Read the config file, if it exists. Using defaults otherwise."""
        for config_file in self.config_file_paths():
            if os.path.exists(config_file):
                try:
                    with open(config_file, encoding='utf-8') as f:
                        self.parser.read_file(f)
                        self.parser.read(f)
                    logger.info(
                        "Read configuration file '{}'".format(config_file))
                except UnicodeDecodeError as err:
                    logger.error(
                        "Cannot decode configuration file '{}': {}".format(
                            config_file, err))
                    sys.exit(1)
                # Save the loaded configuration file path (issue #374)
                self._loaded_config_file = config_file
                break

        # Quicklook
        if not self.parser.has_section('quicklook'):
            self.parser.add_section('quicklook')
        self.set_default_cwc('quicklook', 'cpu')
        self.set_default_cwc('quicklook', 'mem')
        self.set_default_cwc('quicklook', 'swap')

        # CPU
        if not self.parser.has_section('cpu'):
            self.parser.add_section('cpu')
        self.set_default_cwc('cpu', 'user')
        self.set_default_cwc('cpu', 'system')
        self.set_default_cwc('cpu', 'steal')
        # By default I/O wait should be lower than 1/number of CPU cores
        iowait_bottleneck = (1.0 / multiprocessing.cpu_count()) * 100.0
        self.set_default_cwc('cpu', 'iowait', [
            str(iowait_bottleneck - (iowait_bottleneck * 0.20)),
            str(iowait_bottleneck - (iowait_bottleneck * 0.10)),
            str(iowait_bottleneck)
        ])
        ctx_switches_bottleneck = 56000 / multiprocessing.cpu_count()
        self.set_default_cwc('cpu', 'ctx_switches', [
            str(ctx_switches_bottleneck - (ctx_switches_bottleneck * 0.20)),
            str(ctx_switches_bottleneck - (ctx_switches_bottleneck * 0.10)),
            str(ctx_switches_bottleneck)
        ])

        # Per-CPU
        if not self.parser.has_section('percpu'):
            self.parser.add_section('percpu')
        self.set_default_cwc('percpu', 'user')
        self.set_default_cwc('percpu', 'system')

        # Load
        if not self.parser.has_section('load'):
            self.parser.add_section('load')
        self.set_default_cwc('load', cwc=['0.7', '1.0', '5.0'])

        # Mem
        if not self.parser.has_section('mem'):
            self.parser.add_section('mem')
        self.set_default_cwc('mem')

        # Swap
        if not self.parser.has_section('memswap'):
            self.parser.add_section('memswap')
        self.set_default_cwc('memswap')

        # NETWORK
        if not self.parser.has_section('network'):
            self.parser.add_section('network')
        self.set_default_cwc('network', 'rx')
        self.set_default_cwc('network', 'tx')

        # FS
        if not self.parser.has_section('fs'):
            self.parser.add_section('fs')
        self.set_default_cwc('fs')

        # Sensors
        if not self.parser.has_section('sensors'):
            self.parser.add_section('sensors')
        self.set_default_cwc('sensors',
                             'temperature_core',
                             cwc=['60', '70', '80'])
        self.set_default_cwc('sensors',
                             'temperature_hdd',
                             cwc=['45', '52', '60'])
        self.set_default_cwc('sensors', 'battery', cwc=['80', '90', '95'])

        # Process list
        if not self.parser.has_section('processlist'):
            self.parser.add_section('processlist')
        self.set_default_cwc('processlist', 'cpu')
        self.set_default_cwc('processlist', 'mem')

    @property
    def loaded_config_file(self):
        """Return the loaded configuration file."""
        return self._loaded_config_file

    def as_dict(self):
        """Return the configuration as a dict"""
        dictionary = {}
        for section in self.parser.sections():
            dictionary[section] = {}
            for option in self.parser.options(section):
                dictionary[section][option] = self.parser.get(section, option)
        return dictionary

    def sections(self):
        """Return a list of all sections."""
        return self.parser.sections()

    def items(self, section):
        """Return the items list of a section."""
        return self.parser.items(section)

    def has_section(self, section):
        """Return info about the existence of a section."""
        return self.parser.has_section(section)

    def set_default_cwc(self,
                        section,
                        option_header=None,
                        cwc=['50', '70', '90']):
        """Set default values for careful, warning and critical."""
        if option_header is None:
            header = ''
        else:
            header = option_header + '_'
        self.set_default(section, header + 'careful', cwc[0])
        self.set_default(section, header + 'warning', cwc[1])
        self.set_default(section, header + 'critical', cwc[2])

    def set_default(self, section, option, default):
        """If the option did not exist, create a default value."""
        if not self.parser.has_option(section, option):
            self.parser.set(section, option, default)

    def get_value(self, section, option, default=None):
        """Get the value of an option, if it exists."""
        try:
            return self.parser.get(section, option)
        except NoOptionError:
            return default

    def get_int_value(self, section, option, default=0):
        """Get the int value of an option, if it exists."""
        try:
            return self.parser.getint(section, option)
        except NoOptionError:
            return int(default)

    def get_float_value(self, section, option, default=0.0):
        """Get the float value of an option, if it exists."""
        try:
            return self.parser.getfloat(section, option)
        except NoOptionError:
            return float(default)
Beispiel #8
0
class Config(object):
    """This class is used to access/read config file, if it exists.

    :param config_dir: the path to search for config file
    :type config_dir: str or None
    """
    def __init__(self, config_dir=None):
        self.config_dir = config_dir
        self.config_filename = 'glances.conf'
        self._loaded_config_file = None

        # Re patern for optimize research of `foo`
        self.re_pattern = re.compile('(\`.+?\`)')

        self.parser = ConfigParser()
        self.read()

    def config_file_paths(self):
        r"""Get a list of config file paths.

        The list is built taking into account of the OS, priority and location.

        * custom path: /path/to/glances
        * Linux, SunOS: ~/.config/glances, /etc/glances
        * *BSD: ~/.config/glances, /usr/local/etc/glances
        * macOS: ~/Library/Application Support/glances, /usr/local/etc/glances
        * Windows: %APPDATA%\glances

        The config file will be searched in the following order of priority:
            * /path/to/file (via -C flag)
            * user's home directory (per-user settings)
            * system-wide directory (system-wide settings)
        """
        paths = []

        if self.config_dir:
            paths.append(self.config_dir)

        paths.append(os.path.join(user_config_dir(), self.config_filename))
        paths.append(os.path.join(system_config_dir(), self.config_filename))

        return paths

    def read(self):
        """Read the config file, if it exists. Using defaults otherwise."""
        for config_file in self.config_file_paths():
            logger.info('Search glances.conf file in {}'.format(config_file))
            if os.path.exists(config_file):
                try:
                    with open(config_file, encoding='utf-8') as f:
                        self.parser.read_file(f)
                        self.parser.read(f)
                    logger.info(
                        "Read configuration file '{}'".format(config_file))
                except UnicodeDecodeError as err:
                    logger.error(
                        "Can not read configuration file '{}': {}".format(
                            config_file, err))
                    sys.exit(1)
                # Save the loaded configuration file path (issue #374)
                self._loaded_config_file = config_file
                break

        # Quicklook
        if not self.parser.has_section('quicklook'):
            self.parser.add_section('quicklook')
        self.set_default_cwc('quicklook', 'cpu')
        self.set_default_cwc('quicklook', 'mem')
        self.set_default_cwc('quicklook', 'swap')

        # CPU
        if not self.parser.has_section('cpu'):
            self.parser.add_section('cpu')
        self.set_default_cwc('cpu', 'user')
        self.set_default_cwc('cpu', 'system')
        self.set_default_cwc('cpu', 'steal')
        # By default I/O wait should be lower than 1/number of CPU cores
        iowait_bottleneck = (1.0 / multiprocessing.cpu_count()) * 100.0
        self.set_default_cwc('cpu', 'iowait', [
            str(iowait_bottleneck - (iowait_bottleneck * 0.20)),
            str(iowait_bottleneck - (iowait_bottleneck * 0.10)),
            str(iowait_bottleneck)
        ])
        # Context switches bottleneck identification #1212
        ctx_switches_bottleneck = (500000 * 0.10) * multiprocessing.cpu_count()
        self.set_default_cwc('cpu', 'ctx_switches', [
            str(ctx_switches_bottleneck - (ctx_switches_bottleneck * 0.20)),
            str(ctx_switches_bottleneck - (ctx_switches_bottleneck * 0.10)),
            str(ctx_switches_bottleneck)
        ])

        # Per-CPU
        if not self.parser.has_section('percpu'):
            self.parser.add_section('percpu')
        self.set_default_cwc('percpu', 'user')
        self.set_default_cwc('percpu', 'system')

        # Load
        if not self.parser.has_section('load'):
            self.parser.add_section('load')
        self.set_default_cwc('load', cwc=['0.7', '1.0', '5.0'])

        # Mem
        if not self.parser.has_section('mem'):
            self.parser.add_section('mem')
        self.set_default_cwc('mem')

        # Swap
        if not self.parser.has_section('memswap'):
            self.parser.add_section('memswap')
        self.set_default_cwc('memswap')

        # NETWORK
        if not self.parser.has_section('network'):
            self.parser.add_section('network')
        self.set_default_cwc('network', 'rx')
        self.set_default_cwc('network', 'tx')

        # FS
        if not self.parser.has_section('fs'):
            self.parser.add_section('fs')
        self.set_default_cwc('fs')

        # Sensors
        if not self.parser.has_section('sensors'):
            self.parser.add_section('sensors')
        self.set_default_cwc('sensors',
                             'temperature_core',
                             cwc=['60', '70', '80'])
        self.set_default_cwc('sensors',
                             'temperature_hdd',
                             cwc=['45', '52', '60'])
        self.set_default_cwc('sensors', 'battery', cwc=['80', '90', '95'])

        # Process list
        if not self.parser.has_section('processlist'):
            self.parser.add_section('processlist')
        self.set_default_cwc('processlist', 'cpu')
        self.set_default_cwc('processlist', 'mem')

    @property
    def loaded_config_file(self):
        """Return the loaded configuration file."""
        return self._loaded_config_file

    def as_dict(self):
        """Return the configuration as a dict"""
        dictionary = {}
        for section in self.parser.sections():
            dictionary[section] = {}
            for option in self.parser.options(section):
                dictionary[section][option] = self.parser.get(section, option)
        return dictionary

    def sections(self):
        """Return a list of all sections."""
        return self.parser.sections()

    def items(self, section):
        """Return the items list of a section."""
        return self.parser.items(section)

    def has_section(self, section):
        """Return info about the existence of a section."""
        return self.parser.has_section(section)

    def set_default_cwc(self,
                        section,
                        option_header=None,
                        cwc=['50', '70', '90']):
        """Set default values for careful, warning and critical."""
        if option_header is None:
            header = ''
        else:
            header = option_header + '_'
        self.set_default(section, header + 'careful', cwc[0])
        self.set_default(section, header + 'warning', cwc[1])
        self.set_default(section, header + 'critical', cwc[2])

    def set_default(self, section, option, default):
        """If the option did not exist, create a default value."""
        if not self.parser.has_option(section, option):
            self.parser.set(section, option, default)

    def get_value(self, section, option, default=None):
        """Get the value of an option, if it exists.

        If it did not exist, then return the default value.

        It allows user to define dynamic configuration key (see issue#1204)
        Dynamic vlaue should starts and end with the ` char
        Example: prefix=`hostname`
        """
        ret = default
        try:
            ret = self.parser.get(section, option)
        except NoOptionError:
            pass

        # Search a substring `foo` and replace it by the result of its exec
        if ret is not None:
            try:
                match = self.re_pattern.findall(ret)
                for m in match:
                    ret = ret.replace(m, system_exec(m[1:-1]))
            except TypeError:
                pass
        return ret

    def get_int_value(self, section, option, default=0):
        """Get the int value of an option, if it exists."""
        try:
            return self.parser.getint(section, option)
        except NoOptionError:
            return int(default)

    def get_float_value(self, section, option, default=0.0):
        """Get the float value of an option, if it exists."""
        try:
            return self.parser.getfloat(section, option)
        except NoOptionError:
            return float(default)

    def get_bool_value(self, section, option, default=True):
        """Get the bool value of an option, if it exists."""
        try:
            return self.parser.getboolean(section, option)
        except NoOptionError:
            return bool(default)
Beispiel #9
0
class Config(object):

    """This class is used to access/read config file, if it exists.

    :param config_dir: the path to search for config file
    :type config_dir: str or None
    """

    def __init__(self, config_dir=None):
        self.config_dir = config_dir
        self.config_filename = 'glances.conf'
        self._loaded_config_file = None

        self.parser = ConfigParser()
        self.read()

    def config_file_paths(self):
        r"""Get a list of config file paths.

        The list is built taking into account of the OS, priority and location.

        * custom path: /path/to/glances
        * Linux, SunOS: ~/.config/glances, /etc/glances
        * *BSD: ~/.config/glances, /usr/local/etc/glances
        * macOS: ~/Library/Application Support/glances, /usr/local/etc/glances
        * Windows: %APPDATA%\glances

        The config file will be searched in the following order of priority:
            * /path/to/file (via -C flag)
            * user's home directory (per-user settings)
            * system-wide directory (system-wide settings)
        """
        paths = []

        if self.config_dir:
            paths.append(self.config_dir)

        paths.append(os.path.join(user_config_dir(), self.config_filename))
        paths.append(os.path.join(system_config_dir(), self.config_filename))

        return paths

    def read(self):
        """Read the config file, if it exists. Using defaults otherwise."""
        for config_file in self.config_file_paths():
            if os.path.exists(config_file):
                try:
                    with open(config_file, encoding='utf-8') as f:
                        self.parser.read_file(f)
                        self.parser.read(f)
                    logger.info("Read configuration file '{}'".format(config_file))
                except UnicodeDecodeError as err:
                    logger.error("Cannot decode configuration file '{}': {}".format(config_file, err))
                    sys.exit(1)
                # Save the loaded configuration file path (issue #374)
                self._loaded_config_file = config_file
                break

        # Quicklook
        if not self.parser.has_section('quicklook'):
            self.parser.add_section('quicklook')
        self.set_default_cwc('quicklook', 'cpu')
        self.set_default_cwc('quicklook', 'mem')
        self.set_default_cwc('quicklook', 'swap')

        # CPU
        if not self.parser.has_section('cpu'):
            self.parser.add_section('cpu')
        self.set_default_cwc('cpu', 'user')
        self.set_default_cwc('cpu', 'system')
        self.set_default_cwc('cpu', 'steal')
        # By default I/O wait should be lower than 1/number of CPU cores
        iowait_bottleneck = (1.0 / multiprocessing.cpu_count()) * 100.0
        self.set_default_cwc('cpu', 'iowait',
                             [str(iowait_bottleneck - (iowait_bottleneck * 0.20)),
                              str(iowait_bottleneck - (iowait_bottleneck * 0.10)),
                              str(iowait_bottleneck)])
        ctx_switches_bottleneck = 56000 / multiprocessing.cpu_count()
        self.set_default_cwc('cpu', 'ctx_switches',
                             [str(ctx_switches_bottleneck - (ctx_switches_bottleneck * 0.20)),
                              str(ctx_switches_bottleneck - (ctx_switches_bottleneck * 0.10)),
                              str(ctx_switches_bottleneck)])

        # Per-CPU
        if not self.parser.has_section('percpu'):
            self.parser.add_section('percpu')
        self.set_default_cwc('percpu', 'user')
        self.set_default_cwc('percpu', 'system')

        # Load
        if not self.parser.has_section('load'):
            self.parser.add_section('load')
        self.set_default_cwc('load', cwc=['0.7', '1.0', '5.0'])

        # Mem
        if not self.parser.has_section('mem'):
            self.parser.add_section('mem')
        self.set_default_cwc('mem')

        # Swap
        if not self.parser.has_section('memswap'):
            self.parser.add_section('memswap')
        self.set_default_cwc('memswap')

        # NETWORK
        if not self.parser.has_section('network'):
            self.parser.add_section('network')
        self.set_default_cwc('network', 'rx')
        self.set_default_cwc('network', 'tx')

        # FS
        if not self.parser.has_section('fs'):
            self.parser.add_section('fs')
        self.set_default_cwc('fs')

        # Sensors
        if not self.parser.has_section('sensors'):
            self.parser.add_section('sensors')
        self.set_default_cwc('sensors', 'temperature_core', cwc=['60', '70', '80'])
        self.set_default_cwc('sensors', 'temperature_hdd', cwc=['45', '52', '60'])
        self.set_default_cwc('sensors', 'battery', cwc=['80', '90', '95'])

        # Process list
        if not self.parser.has_section('processlist'):
            self.parser.add_section('processlist')
        self.set_default_cwc('processlist', 'cpu')
        self.set_default_cwc('processlist', 'mem')

    @property
    def loaded_config_file(self):
        """Return the loaded configuration file."""
        return self._loaded_config_file

    def as_dict(self):
        """Return the configuration as a dict"""
        dictionary = {}
        for section in self.parser.sections():
            dictionary[section] = {}
            for option in self.parser.options(section):
                dictionary[section][option] = self.parser.get(section, option)
        return dictionary

    def sections(self):
        """Return a list of all sections."""
        return self.parser.sections()

    def items(self, section):
        """Return the items list of a section."""
        return self.parser.items(section)

    def has_section(self, section):
        """Return info about the existence of a section."""
        return self.parser.has_section(section)

    def set_default_cwc(self, section,
                        option_header=None,
                        cwc=['50', '70', '90']):
        """Set default values for careful, warning and critical."""
        if option_header is None:
            header = ''
        else:
            header = option_header + '_'
        self.set_default(section, header + 'careful', cwc[0])
        self.set_default(section, header + 'warning', cwc[1])
        self.set_default(section, header + 'critical', cwc[2])

    def set_default(self, section, option, default):
        """If the option did not exist, create a default value."""
        if not self.parser.has_option(section, option):
            self.parser.set(section, option, default)

    def get_value(self, section, option, default=None):
        """Get the value of an option, if it exists."""
        try:
            return self.parser.get(section, option)
        except NoOptionError:
            return default

    def get_int_value(self, section, option, default=0):
        """Get the int value of an option, if it exists."""
        try:
            return self.parser.getint(section, option)
        except NoOptionError:
            return int(default)

    def get_float_value(self, section, option, default=0.0):
        """Get the float value of an option, if it exists."""
        try:
            return self.parser.getfloat(section, option)
        except NoOptionError:
            return float(default)
Beispiel #10
0
class Config(object):

    """This class is used to access/read config file, if it exists.

    :param config_dir: the path to search for config file
    :type config_dir: str or None
    """

    def __init__(self, config_dir=None):
        self.config_dir = config_dir
        self.config_filename = 'glances.conf'
        self._loaded_config_file = None

        self.parser = ConfigParser()
        self.read()

    def config_file_paths(self):
        r"""Get a list of config file paths.

        The list is built taking into account of the OS, priority and location.

        * custom path: /path/to/glances
        * Linux: ~/.config/glances, /etc/glances
        * BSD: ~/.config/glances, /usr/local/etc/glances
        * OS X: ~/Library/Application Support/glances, /usr/local/etc/glances
        * Windows: %APPDATA%\glances

        The config file will be searched in the following order of priority:
            * /path/to/file (via -C flag)
            * user's home directory (per-user settings)
            * system-wide directory (system-wide settings)
        """
        paths = []

        if self.config_dir:
            paths.append(self.config_dir)

        if LINUX or BSD:
            paths.append(
                os.path.join(os.environ.get('XDG_CONFIG_HOME') or
                             os.path.expanduser('~/.config'),
                             __appname__, self.config_filename))
            if BSD:
                paths.append(
                    os.path.join(sys.prefix, 'etc', __appname__, self.config_filename))
            else:
                paths.append(
                    os.path.join('/etc', __appname__, self.config_filename))
        elif OSX:
            paths.append(
                os.path.join(os.path.expanduser('~/Library/Application Support/'),
                             __appname__, self.config_filename))
            paths.append(
                os.path.join(sys_prefix, 'etc', __appname__, self.config_filename))
        elif WINDOWS:
            paths.append(
                os.path.join(os.environ.get('APPDATA'), __appname__, self.config_filename))

        return paths

    def read(self):
        """Read the config file, if it exists. Using defaults otherwise."""
        for config_file in self.config_file_paths():
            if os.path.exists(config_file):
                try:
                    with open(config_file, encoding='utf-8') as f:
                        self.parser.read_file(f)
                        self.parser.read(f)
                    logger.info("Read configuration file '{}'".format(config_file))
                except UnicodeDecodeError as err:
                    logger.error("Cannot decode configuration file '{}': {}".format(config_file, err))
                    sys.exit(1)
                # Save the loaded configuration file path (issue #374)
                self._loaded_config_file = config_file
                break

        # Quicklook
        if not self.parser.has_section('quicklook'):
            self.parser.add_section('quicklook')
        self.set_default('quicklook', 'cpu_careful', '50')
        self.set_default('quicklook', 'cpu_warning', '70')
        self.set_default('quicklook', 'cpu_critical', '90')
        self.set_default('quicklook', 'mem_careful', '50')
        self.set_default('quicklook', 'mem_warning', '70')
        self.set_default('quicklook', 'mem_critical', '90')
        self.set_default('quicklook', 'swap_careful', '50')
        self.set_default('quicklook', 'swap_warning', '70')
        self.set_default('quicklook', 'swap_critical', '90')

        # CPU
        if not self.parser.has_section('cpu'):
            self.parser.add_section('cpu')
        self.set_default('cpu', 'user_careful', '50')
        self.set_default('cpu', 'user_warning', '70')
        self.set_default('cpu', 'user_critical', '90')
        self.set_default('cpu', 'system_careful', '50')
        self.set_default('cpu', 'system_warning', '70')
        self.set_default('cpu', 'system_critical', '90')
        self.set_default('cpu', 'steal_careful', '50')
        self.set_default('cpu', 'steal_warning', '70')
        self.set_default('cpu', 'steal_critical', '90')
        # By default I/O wait should be lower than 1/number of CPU cores
        iowait_bottleneck = (1.0 / multiprocessing.cpu_count()) * 100.0
        self.set_default('cpu', 'iowait_careful', str(iowait_bottleneck - (iowait_bottleneck * 0.20)))
        self.set_default('cpu', 'iowait_warning', str(iowait_bottleneck - (iowait_bottleneck * 0.10)))
        self.set_default('cpu', 'iowait_critical', str(iowait_bottleneck))
        ctx_switches_bottleneck = 56000 / multiprocessing.cpu_count()
        self.set_default('cpu', 'ctx_switches_careful', str(ctx_switches_bottleneck - (ctx_switches_bottleneck * 0.20)))
        self.set_default('cpu', 'ctx_switches_warning', str(ctx_switches_bottleneck - (ctx_switches_bottleneck * 0.10)))
        self.set_default('cpu', 'ctx_switches_critical', str(ctx_switches_bottleneck))

        # Per-CPU
        if not self.parser.has_section('percpu'):
            self.parser.add_section('percpu')
        self.set_default('percpu', 'user_careful', '50')
        self.set_default('percpu', 'user_warning', '70')
        self.set_default('percpu', 'user_critical', '90')
        self.set_default('percpu', 'system_careful', '50')
        self.set_default('percpu', 'system_warning', '70')
        self.set_default('percpu', 'system_critical', '90')

        # Load
        if not self.parser.has_section('load'):
            self.parser.add_section('load')
        self.set_default('load', 'careful', '0.7')
        self.set_default('load', 'warning', '1.0')
        self.set_default('load', 'critical', '5.0')

        # Mem
        if not self.parser.has_section('mem'):
            self.parser.add_section('mem')
        self.set_default('mem', 'careful', '50')
        self.set_default('mem', 'warning', '70')
        self.set_default('mem', 'critical', '90')

        # Swap
        if not self.parser.has_section('memswap'):
            self.parser.add_section('memswap')
        self.set_default('memswap', 'careful', '50')
        self.set_default('memswap', 'warning', '70')
        self.set_default('memswap', 'critical', '90')

        # FS
        if not self.parser.has_section('fs'):
            self.parser.add_section('fs')
        self.set_default('fs', 'careful', '50')
        self.set_default('fs', 'warning', '70')
        self.set_default('fs', 'critical', '90')

        # Sensors
        if not self.parser.has_section('sensors'):
            self.parser.add_section('sensors')
        self.set_default('sensors', 'temperature_core_careful', '60')
        self.set_default('sensors', 'temperature_core_warning', '70')
        self.set_default('sensors', 'temperature_core_critical', '80')
        self.set_default('sensors', 'temperature_hdd_careful', '45')
        self.set_default('sensors', 'temperature_hdd_warning', '52')
        self.set_default('sensors', 'temperature_hdd_critical', '60')
        self.set_default('sensors', 'battery_careful', '80')
        self.set_default('sensors', 'battery_warning', '90')
        self.set_default('sensors', 'battery_critical', '95')

        # Process list
        if not self.parser.has_section('processlist'):
            self.parser.add_section('processlist')
        self.set_default('processlist', 'cpu_careful', '50')
        self.set_default('processlist', 'cpu_warning', '70')
        self.set_default('processlist', 'cpu_critical', '90')
        self.set_default('processlist', 'mem_careful', '50')
        self.set_default('processlist', 'mem_warning', '70')
        self.set_default('processlist', 'mem_critical', '90')

    @property
    def loaded_config_file(self):
        """Return the loaded configuration file."""
        return self._loaded_config_file

    def sections(self):
        """Return a list of all sections."""
        return self.parser.sections()

    def items(self, section):
        """Return the items list of a section."""
        return self.parser.items(section)

    def has_section(self, section):
        """Return info about the existence of a section."""
        return self.parser.has_section(section)

    def set_default(self, section, option, default):
        """If the option did not exist, create a default value."""
        if not self.parser.has_option(section, option):
            self.parser.set(section, option, default)

    def get_value(self, section, option, default=None):
        """Get the value of an option, if it exists."""
        try:
            return self.parser.get(section, option)
        except NoOptionError:
            return default

    def get_float_value(self, section, option, default=0.0):
        """Get the float value of an option, if it exists."""
        try:
            return self.parser.getfloat(section, option)
        except NoOptionError:
            return float(default)