Пример #1
0
 def reset_stats_history(self):
     """Reset the stats history (dict of list)"""
     if self.args is not None and self.args.enable_history and self.get_items_history_list() is not None:
         reset_list = [i['name'] for i in self.get_items_history_list()]
         logger.debug("Reset history for plugin {0} (items: {0})".format(self.plugin_name, reset_list))
         self.stats_history = {}
     return self.stats_history
Пример #2
0
    def __init__(self, config=None, args=None):
        # Init stats
        self.stats = GlancesStats(config=config, args=args)

        # Default number of processes to displayed is set to 20
        glances_processes.set_max_processes(20)

        # If process extended stats is disabled by user
        if args.disable_process_extended:
            logger.info(_("Extended stats for top process is disabled"))
            glances_processes.disable_extended()
        else:
            logger.debug(
                _("Extended stats for top process is enabled (default behavor)"
                  ))
            glances_processes.enable_extended()

        # Manage optionnal process filter
        if args.process_filter is not None:
            glances_processes.set_process_filter(args.process_filter)

        # Initial system informations update
        self.stats.update()

        # Init CSV output
        if args.output_csv is not None:
            from glances.outputs.glances_csv import GlancesCSV

            self.csvoutput = GlancesCSV(args=args)
            self.csv_tag = True
        else:
            self.csv_tag = False

        # Init screen
        self.screen = GlancesCurses(args=args)
Пример #3
0
    def __init__(self, config=None, args=None, timeout=7, return_to_browser=False):
        # Store the arg/config
        self.args = args
        self.config = config

        # Client mode:
        self.set_mode()

        # Build the URI
        if args.password != "":
            uri = 'http://{0}:{1}@{2}:{3}'.format(args.username, args.password,
                                                  args.client, args.port)
        else:
            uri = 'http://{0}:{1}'.format(args.client, args.port)
        logger.debug("Try to connect to {0}".format(uri))

        # Try to connect to the URI
        transport = GlancesClientTransport()
        # Configure the server timeout
        transport.set_timeout(timeout)
        try:
            self.client = ServerProxy(uri, transport=transport)
        except Exception as e:
            msg = "Client couldn't create socket {0}: {1}".format(uri, e)
            if not return_to_browser:
                logger.critical(msg)
                sys.exit(2)
            else:
                logger.error(msg)
Пример #4
0
    def __init__(self, config=None, args=None):
        # Init stats
        self.stats = GlancesStats(config=config, args=args)

        # Default number of processes to displayed is set to 50
        glances_processes.set_max_processes(50)

        # If process extended stats is disabled by user
        if args.disable_process_extended:
            logger.info(_("Extended stats for top process is disabled"))
            glances_processes.disable_extended()
        else:
            logger.debug(_("Extended stats for top process is enabled (default behavor)"))
            glances_processes.enable_extended()

        # Manage optionnal process filter
        if args.process_filter is not None:
            glances_processes.set_process_filter(args.process_filter)

        # Initial system informations update
        self.stats.update()

        # Init CSV output
        if args.output_csv is not None:
            from glances.outputs.glances_csv import GlancesCSV

            self.csvoutput = GlancesCSV(args=args)
            self.csv_tag = True
        else:
            self.csv_tag = False

        # Init screen
        self.screen = GlancesCurses(args=args)
Пример #5
0
 def init_stats_history(self):
     """Init the stats history (dict of list)"""
     ret = None
     if self.args is not None and self.args.enable_history and self.get_items_history_list() is not None:
         init_list = [i['name'] for i in self.get_items_history_list()]
         logger.debug("Stats history activated for plugin {0} (items: {0})".format(self.plugin_name, init_list))
         ret = {}
     return ret
Пример #6
0
 def wrapper(*args, **kw):
     ret = fct(*args, **kw)
     if is_py3:
         logger.debug("%s %s %s return %s" % (args[0].__class__.__name__, args[
                      0].__class__.__module__[len('glances_'):], fct.__name__, ret))
     else:
         logger.debug("%s %s %s return %s" % (args[0].__class__.__name__, args[
                      0].__class__.__module__[len('glances_'):], fct.func_name, ret))
     return ret
Пример #7
0
 def __init__(self):
     """Init batteries stats."""
     try:
         self.bat = batinfo.batteries()
         self.initok = True
         self.bat_list = []
         self.update()
     except Exception as e:
         self.initok = False
         logger.debug("Cannot init GlancesGrabBat class (%s)" % e)
Пример #8
0
 def reset_stats_history(self):
     """Reset the stats history (dict of list)"""
     if self.args is not None and self.args.enable_history and self.get_items_history_list() is not None:
         iList = [i['name'] for i in self.get_items_history_list()]
         logger.debug(_("Reset history for plugin %s (items: %s)") % (self.plugin_name, iList))
         self.stats_history = {}
         # First column for the date
         self.stats_history['date'] = []
         for i in self.get_items_history_list():
             # One column per item
             self.stats_history[i['name']] = []
     return self.stats_history
Пример #9
0
 def remove_server(self, name):
     """Remove a server from the dict"""
     for i in self._server_list:
         if i['key'] == name:
             try:
                 self._server_list.remove(i)
                 logger.debug("Remove server %s from the list" % name)
                 logger.debug("Updated servers list (%s servers): %s" % (
                     len(self._server_list), self._server_list))
             except ValueError:
                 logger.error(
                     "Cannot remove server %s from the list" % name)
Пример #10
0
 def init_stats_history(self):
     """Init the stats history (dict of list)"""
     ret = None
     if self.args is not None and self.args.enable_history and self.get_items_history_list() is not None:
         iList = [i['name'] for i in self.get_items_history_list()]
         logger.debug(_("Stats history activated for plugin %s (items: %s)") % (self.plugin_name, iList))
         ret = {}
         # First column for the date
         ret['date'] = []
         for i in self.get_items_history_list():
             # One column per item
             ret[i['name']] = []
     return ret
Пример #11
0
 def add_server(self, name, ip, port):
     """Add a new server to the list"""
     new_server = {'key': name,  # Zeroconf name with both hostname and port
                   'name': name.split(':')[0],  # Short name
                   'ip': ip,  # IP address seen by the client
                   'port': port,  # TCP port
                   'username': '******',  # Default username
                   'password': '',  # Default password
                   'status': 'UNKNOWN',  # Server status: 'UNKNOWN', 'OFFLINE', 'ONLINE', 'PROTECTED'
                   'type': 'DYNAMIC',  # Server type: 'STATIC' or 'DYNAMIC'
                   }
     self._server_list.append(new_server)
     logger.debug("Updated servers list (%s servers): %s" %
                  (len(self._server_list), self._server_list))
Пример #12
0
 def set_process_filter(self, value):
     """Set the process filter"""
     logger.info(_("Set process filter to %s") % value)
     self.process_filter = value
     if value is not None:
         try:
             self.process_filter_re = re.compile(value)
             logger.debug(_("Process filter regular expression compilation OK: %s") % self.get_process_filter())
         except:
             logger.error(_("Can not compile process filter regular expression: %s") % value)
             self.process_filter_re = None
     else:
         self.process_filter_re = None
     return self.process_filter
Пример #13
0
 def set_plugins(self, input_plugins):
     """Set the plugin list according to the Glances server."""
     header = "glances_"
     for item in input_plugins:
         # Import the plugin
         plugin = __import__(header + item)
         # Add the plugin to the dictionary
         # The key is the plugin name
         # for example, the file glances_xxx.py
         # generate self._plugins_list["xxx"] = ...
         logger.debug(_("Init %s plugin") % item)
         self._plugins[item] = plugin.Plugin()
     # Restoring system path
     sys.path = sys_path
Пример #14
0
 def set_plugins(self, input_plugins):
     """Set the plugin list according to the Glances server."""
     header = "glances_"
     for item in input_plugins:
         # Import the plugin
         plugin = __import__(header + item)
         # Add the plugin to the dictionary
         # The key is the plugin name
         # for example, the file glances_xxx.py
         # generate self._plugins_list["xxx"] = ...            
         logger.debug(_("Init %s plugin") % item)
         self._plugins[item] = plugin.Plugin()
     # Restoring system path
     sys.path = sys_path
Пример #15
0
    def get_key(self, window):
        # Catch ESC key AND numlock key (issue #163)
        keycode = [0, 0]
        keycode[0] = window.getch()
        keycode[1] = window.getch()

        if keycode != [-1, -1]:
            logger.debug("Keypressed (code: %s)" % keycode)

        if keycode[0] == 27 and keycode[1] != -1:
            # Do not escape on specials keys
            return -1
        else:
            return keycode[0]
Пример #16
0
 def set_process_filter(self, value):
     """Set the process filter"""
     logger.info("Set process filter to {0}".format(value))
     self.process_filter = value
     if value is not None:
         try:
             self.process_filter_re = re.compile(value)
             logger.debug("Process filter regex compilation OK: {0}".format(self.get_process_filter()))
         except Exception:
             logger.error("Cannot compile process filter regex: {0}".format(value))
             self.process_filter_re = None
     else:
         self.process_filter_re = None
     return self.process_filter
Пример #17
0
    def __init__(self, config=None, args=None):
        # Init stats
        self.stats = GlancesStats(config=config, args=args)

        # If configured, set the maximum processes number to display
        try:
            max_processes = int(
                self.stats.get_plugin('processlist').get_conf_value(
                    'max_processes'))
            logger.debug(
                _("Limit maximum displayed processes to %s") % max_processes)
        except:
            max_processes = None
            logger.warning(
                _("Maximum displayed processes is not configured (high CPU consumption)"
                  ))
        glances_processes.set_max_processes(max_processes)

        # If process extended stats is disabled by user
        if args.disable_process_extended:
            logger.info(_("Extended stats for top process is disabled"))
            glances_processes.disable_extended()
        else:
            logger.debug(
                _("Extended stats for top process is enabled (default behavor)"
                  ))
            glances_processes.enable_extended()

        # Manage optionnal process filter
        if args.process_filter is not None:
            glances_processes.set_process_filter(args.process_filter)

        # Initial system informations update
        self.stats.update()

        # Init CSV output
        if args.output_csv is not None:
            from glances.outputs.glances_csv import GlancesCSV

            self.csvoutput = GlancesCSV(args=args)
            self.csv_tag = True
        else:
            self.csv_tag = False

        # Init screen
        self.screen = GlancesCurses(args=args)
Пример #18
0
    def load(self, config):
        """Load the server list from the configuration file"""

        server_list = []

        if config is None:
            logger.warning("No configuration file available. Cannot load server list.")
        elif not config.has_section(self._section):
            logger.warning("No [%s] section in the configuration file. Cannot load server list." % self._section)
        else:
            logger.info("Start reading the [%s] section in the configuration file" % self._section)
            for i in range(1, 256):
                new_server = {}
                postfix = 'server_%s_' % str(i)
                # Read the server name (mandatory)
                for s in ['name', 'port', 'alias']:
                    new_server[s] = config.get_raw_option(self._section, '%s%s' % (postfix, s))
                if new_server['name'] is not None:
                    # Manage optionnal information
                    if new_server['port'] is None:
                        new_server['port'] = 61209
                    new_server['username'] = '******'
                    new_server['password'] = ''
                    try:
                        new_server['ip'] = gethostbyname(new_server['name'])
                    except gaierror as e:
                        logger.error("Cannot get IP address for server %s (%s)" % (new_server['name'], e))
                        continue
                    new_server['key'] = new_server['name'] + ':' + new_server['port']

                    # Default status is 'UNKNOWN'
                    new_server['status'] = 'UNKNOWN'

                    # Server type is 'STATIC'
                    new_server['type'] = 'STATIC'

                    # Add the server to the list
                    logger.debug("Add server %s to the static list" % new_server['name'])
                    server_list.append(new_server)

            # Server list loaded
            logger.info("%s server(s) loaded from the configuration file" % len(server_list))
            logger.debug("Static server list: %s" % server_list)

        return server_list
Пример #19
0
 def set_process_filter(self, value):
     """Set the process filter"""
     logger.info(_("Set process filter to %s") % value)
     self.process_filter = value
     if value is not None:
         try:
             self.process_filter_re = re.compile(value)
             logger.debug(
                 _("Process filter regular expression compilation OK: %s") %
                 self.get_process_filter())
         except:
             logger.error(
                 _("Can not compile process filter regular expression: %s")
                 % value)
             self.process_filter_re = None
     else:
         self.process_filter_re = None
     return self.process_filter
Пример #20
0
    def __init__(self, config=None, args=None):
        # Init stats
        self.stats = GlancesStats(config=config, args=args)

        # Default number of processes to displayed is set to 50
        glances_processes.set_max_processes(50)

        # If process extended stats is disabled by user
        if not args.enable_process_extended:
            logger.info("Extended stats for top process are disabled (default behavior)")
            glances_processes.disable_extended()
        else:
            logger.debug("Extended stats for top process are enabled")
            glances_processes.enable_extended()

        # Manage optionnal process filter
        if args.process_filter is not None:
            glances_processes.set_process_filter(args.process_filter)

        if (not is_windows) and args.no_kernel_threads:
            # Ignore kernel threads in process list
            glances_processes.disable_kernel_threads()

        if args.process_tree:
            # Enable process tree view
            glances_processes.enable_tree()

        # Initial system informations update
        self.stats.update()

        # Init CSV output
        if args.output_csv is not None:
            from glances.outputs.glances_csv import GlancesCSV

            self.csvoutput = GlancesCSV(args=args)
            self.csv_tag = True
        else:
            self.csv_tag = False

        # Init screen
        self.screen = GlancesCursesStandalone(args=args)
Пример #21
0
 def load_plugins(self, args=None):
     """Load all plugins in the 'plugins' folder."""
     header = "glances_"
     for item in os.listdir(plugins_path):
         if (item.startswith(header) and
                 item.endswith(".py") and
                 item != (header + "plugin.py")):
             # Import the plugin
             plugin = __import__(os.path.basename(item)[:-3])
             # Add the plugin to the dictionary
             # The key is the plugin name
             # for example, the file glances_xxx.py
             # generate self._plugins_list["xxx"] = ...
             plugin_name = os.path.basename(item)[len(header):-3].lower()
             if plugin_name == 'help':
                 self._plugins[plugin_name] = plugin.Plugin(args=args, config=self.config)
             else:
                 self._plugins[plugin_name] = plugin.Plugin(args=args)
     # Restoring system path
     sys.path = sys_path
     # Log plugins list
     logger.debug(_("Available plugins list: %s"), self.getAllPlugins())
Пример #22
0
    def __init__(self, config=None, args=None):
        # Init stats
        self.stats = GlancesStats(config=config, args=args)

        # If configured, set the maximum processes number to display
        try:
            max_processes = int(self.stats.get_plugin('processlist').get_conf_value('max_processes'))
            logger.debug(_("Limit maximum displayed processes to %s") % max_processes)
        except:
            max_processes = None
            logger.warning(_("Maximum displayed processes is not configured (high CPU consumption)"))
        glances_processes.set_max_processes(max_processes)

        # If process extended stats is disabled by user
        if args.disable_process_extended:
            logger.info(_("Extended stats for top process is disabled"))
            glances_processes.disable_extended()
        else:
            logger.debug(_("Extended stats for top process is enabled (default behavor)"))
            glances_processes.enable_extended()

        # Manage optionnal process filter
        if args.process_filter is not None:
            glances_processes.set_process_filter(args.process_filter)

        # Initial system informations update
        self.stats.update()

        # Init CSV output
        if args.output_csv is not None:
            from glances.outputs.glances_csv import GlancesCSV

            self.csvoutput = GlancesCSV(args=args)
            self.csv_tag = True
        else:
            self.csv_tag = False

        # Init screen
        self.screen = GlancesCurses(args=args)
Пример #23
0
    def add_service(self, zeroconf, srv_type, srv_name):
        """Method called when a new Zeroconf client is detected
        Return True if the zeroconf client is a Glances server
        Note: the return code will never be used
        """
        if srv_type != zeroconf_type:
            return False
        logger.debug("Check new Zeroconf server: %s / %s" %
                     (srv_type, srv_name))
        info = zeroconf.get_service_info(srv_type, srv_name)
        if info:
            new_server_ip = socket.inet_ntoa(info.address)
            new_server_port = info.port

            # Add server to the global dict
            self.servers.add_server(srv_name, new_server_ip, new_server_port)
            logger.info("New Glances server detected (%s from %s:%s)" %
                        (srv_name, new_server_ip, new_server_port))
        else:
            logger.warning(
                "New Glances server detected, but Zeroconf info failed to be grabbed")
        return True
Пример #24
0
 def load_plugins(self, args=None):
     """Load all plugins in the 'plugins' folder."""
     header = "glances_"
     for item in os.listdir(plugins_path):
         if (item.startswith(header) and item.endswith(".py") and item !=
             (header + "plugin.py")):
             # Import the plugin
             plugin = __import__(os.path.basename(item)[:-3])
             # Add the plugin to the dictionary
             # The key is the plugin name
             # for example, the file glances_xxx.py
             # generate self._plugins_list["xxx"] = ...
             plugin_name = os.path.basename(item)[len(header):-3].lower()
             if plugin_name == 'help':
                 self._plugins[plugin_name] = plugin.Plugin(
                     args=args, config=self.config)
             else:
                 self._plugins[plugin_name] = plugin.Plugin(args=args)
     # Restoring system path
     sys.path = sys_path
     # Log plugins list
     logger.debug(_("Available plugins list: %s"), self.getAllPlugins())
Пример #25
0
    def __catch_key(self, servers_list):
        # Catch the browser pressed key
        self.pressedkey = self.get_key(self.term_window)

        # Actions...
        if self.pressedkey == ord('\x1b') or self.pressedkey == ord('q'):
            # 'ESC'|'q' > Quit
            self.end()
            logger.info("Stop Glances client browser")
            sys.exit(0)
        elif self.pressedkey == 10:
            # 'ENTER' > Run Glances on the selected server
            logger.debug("Server number %s selected" % (self.cursor_get() + 1))
            self.set_active(self.cursor_get())
        elif self.pressedkey == 259:
            # 'UP' > Up in the server list
            logger
            self.cursor_up(servers_list)
        elif self.pressedkey == 258:
            # 'DOWN' > Down in the server list
            self.cursor_down(servers_list)

        # Return the key code
        return self.pressedkey
Пример #26
0
    def generate_graph(self, stats):
        """
        Generate graphs from plugins history
        Return the number of output files generated by the function
        """
        if not self.graph_enabled():
            return 0

        index_all = 0
        for p in stats.getAllPlugins():
            h = stats.get_plugin(p).get_stats_history()
            # Data
            if h is None:
                # History (h) not available for plugin (p)
                continue
            # Init graph
            plt.clf()
            index_graph = 0
            handles = []
            labels = []
            for i in stats.get_plugin(p).get_items_history_list():
                if i['name'] in h.keys():
                    # The key exist
                    # Add the curves in the current chart
                    logger.debug("Generate graph: %s %s" % (p, i['name']))
                    index_graph += 1
                    # Labels
                    handles.append(plt.Rectangle((0, 0), 1, 1, fc=self.get_graph_color(i), ec=self.get_graph_color(i), linewidth=2))
                    labels.append(self.get_graph_legend(i))
                    # Legend
                    plt.ylabel(self.get_graph_yunit(i, pre_label=''))
                    # Curves
                    plt.grid(True)
                    plt.plot_date(h['date'], h[i['name']],
                                  fmt='', drawstyle='default', linestyle='-',
                                  color=self.get_graph_color(i),
                                  xdate=True, ydate=False)
                    if index_graph == 1:
                        # Title only on top of the first graph
                        plt.title(p.capitalize())
                else:
                    # The key did not exist
                    # Find if anothers key ends with the key
                    # Ex: key='tx' => 'ethernet_tx'
                    # Add one curve per chart
                    stats_history_filtered = [key for key in h.keys() if key.endswith('_' + i['name'])]
                    stats_history_filtered.sort()
                    logger.debug("Generate graphs: %s %s" %
                                 (p, stats_history_filtered))
                    if len(stats_history_filtered) > 0:
                        # Create 'n' graph
                        # Each graph iter through the stats
                        plt.clf()
                        index_item = 0
                        for k in stats_history_filtered:
                            index_item += 1
                            plt.subplot(
                                len(stats_history_filtered), 1, index_item)
                            plt.ylabel(self.get_graph_yunit(i, pre_label=k))
                            plt.grid(True)
                            plt.plot_date(h['date'], h[k],
                                          fmt='', drawstyle='default', linestyle='-',
                                          color=self.get_graph_color(i),
                                          xdate=True, ydate=False)
                            if index_item == 1:
                                # Title only on top of the first graph
                                plt.title(p.capitalize() + ' ' + i['name'])
                        # Save the graph to output file
                        fig = plt.gcf()
                        fig.set_size_inches(20, 5 * index_item)
                        plt.xlabel('Date')
                        plt.savefig(
                            os.path.join(self.output_folder, 'glances_%s_%s.png' % (p, i['name'])), dpi=72)
                        index_all += 1

            if index_graph > 0:
                # Save the graph to output file
                fig = plt.gcf()
                fig.set_size_inches(20, 10)
                plt.legend(handles, labels, loc=1, prop={'size': 9})
                plt.xlabel('Date')
                plt.savefig(
                    os.path.join(self.output_folder, 'glances_%s.png' % (p)), dpi=72)
                index_all += 1

            plt.close()

        return index_all
Пример #27
0
 def load_limits(self, config):
     """Load the monitored list from the conf file."""
     logger.debug("Monitor plugin configuration detected in the configuration file")
     self.glances_monitors = glancesMonitorList(config)
Пример #28
0
    def parse_args(self):
        """Parse command line arguments."""
        args = self.init_args().parse_args()

        # Load the configuration file, if it exists
        self.config = Config(args.conf_file)

        # Debug mode
        if args.debug:
            from logging import DEBUG
            logger.setLevel(DEBUG)

        # Client/server Port
        if args.port is None:
            if args.webserver:
                args.port = self.web_server_port
            else:
                args.port = self.server_port

        # Autodiscover
        if args.disable_autodiscover:
            logger.info("Auto discover mode is disabled")

        # In web server mode, defaul refresh time: 5 sec
        if args.webserver:
            args.time = 5

        # Server or client login/password
        args.username = self.username
        if args.password_arg is not None:
            from hashlib import sha256
            # Password is given as an argument
            # Hash with SHA256
            # Only the SHA will be transmit on the network
            args.password = sha256(args.password_arg).hexdigest()
        elif args.password_prompt:
            # Interactive or file password
            if args.server:
                args.password = self.__get_password(
                    description=_(
                        "Define the password for the Glances server"),
                    confirm=True)
            elif args.client:
                args.password = self.__get_password(
                    description=_("Enter the Glances server password"),
                    clear=True)
        else:
            # Default is no password
            args.password = self.password

        # By default help is hidden
        args.help_tag = False

        # Display Rx and Tx, not the sum for the network
        args.network_sum = False
        args.network_cumul = False

        # Control parameter and exit if it is not OK
        self.args = args

        # Filter is only available in standalone mode
        if args.process_filter is not None and not self.is_standalone():
            logger.critical("Process filter is only available in standalone mode")
            sys.exit(2)

        # Check graph output path
        if args.enable_history and args.path_history is not None:
            if not os.access(args.path_history, os.W_OK):
                logger.critical("History output path {0} do not exist or is not writable".format(args.path_history))
                sys.exit(2)
            logger.debug("History output path is set to {0}".format(args.path_history))

        return args
Пример #29
0
    def display(self, stats, cs_status="None"):
        """Display stats on the screen.

        stats: Stats database to display
        cs_status:
            "None": standalone or server mode
            "Connected": Client is connected to a Glances server
            "SNMP": Client is connected to a SNMP server
            "Disconnected": Client is disconnected from the server

        Return:
            True if the stats have been displayed
            False if the help have been displayed
        """
        # Init the internal line/column for Glances Curses
        self.init_line_column()

        # Get the screen size
        screen_x = self.screen.getmaxyx()[1]
        screen_y = self.screen.getmaxyx()[0]

        # No processes list in SNMP mode
        if cs_status == 'SNMP':
            # so... more space for others plugins
            plugin_max_width = 43
        else:
            plugin_max_width = None

        # Update the stats messages
        ###########################

        # Update the client server status
        self.args.cs_status = cs_status
        stats_system = stats.get_plugin('system').get_stats_display(
            args=self.args)
        stats_uptime = stats.get_plugin('uptime').get_stats_display()
        if self.args.percpu:
            stats_percpu = stats.get_plugin('percpu').get_stats_display()
        else:
            stats_cpu = stats.get_plugin('cpu').get_stats_display()
        stats_load = stats.get_plugin('load').get_stats_display()
        stats_mem = stats.get_plugin('mem').get_stats_display()
        stats_memswap = stats.get_plugin('memswap').get_stats_display()
        stats_network = stats.get_plugin('network').get_stats_display(
            args=self.args, max_width=plugin_max_width)
        stats_diskio = stats.get_plugin('diskio').get_stats_display(
            args=self.args)
        stats_fs = stats.get_plugin('fs').get_stats_display(
            args=self.args, max_width=plugin_max_width)
        stats_sensors = stats.get_plugin('sensors').get_stats_display(
            args=self.args)
        stats_now = stats.get_plugin('now').get_stats_display()
        stats_processcount = stats.get_plugin(
            'processcount').get_stats_display(args=self.args)
        stats_monitor = stats.get_plugin('monitor').get_stats_display(
            args=self.args)
        stats_alert = stats.get_plugin('alert').get_stats_display(
            args=self.args)

        # Adapt number of processes to the available space
        max_processes_displayed = screen_y - 11 - self.get_stats_display_height(
            stats_alert)
        if not self.args.disable_process_extended:
            max_processes_displayed -= 4
        if max_processes_displayed < 0:
            max_processes_displayed = 0
        if glances_processes.get_max_processes() is None or \
           glances_processes.get_max_processes() != max_processes_displayed:
            logger.debug(
                _("Set number of displayed processes to %s") %
                max_processes_displayed)
            glances_processes.set_max_processes(max_processes_displayed)

        stats_processlist = stats.get_plugin('processlist').get_stats_display(
            args=self.args)

        # Display the stats on the curses interface
        ###########################################

        # Help screen (on top of the other stats)
        if self.args.help_tag:
            # Display the stats...
            self.display_plugin(
                stats.get_plugin('help').get_stats_display(args=self.args))
            # ... and exit
            return False

        # Display first line (system+uptime)
        self.new_line()
        l = self.get_stats_display_width(
            stats_system) + self.get_stats_display_width(
                stats_uptime) + self.space_between_column
        self.display_plugin(stats_system, display_optional=(screen_x >= l))
        self.new_column()
        self.display_plugin(stats_uptime)

        # Display second line (CPU|PERCPU+LOAD+MEM+SWAP+<SUMMARY>)
        # CPU|PERCPU
        self.init_column()
        self.new_line()
        if self.args.percpu:
            l = self.get_stats_display_width(stats_percpu)
        else:
            l = self.get_stats_display_width(stats_cpu)
        l += self.get_stats_display_width(
            stats_load) + self.get_stats_display_width(
                stats_mem) + self.get_stats_display_width(stats_memswap)
        # Space between column
        space_number = int(stats_load['msgdict'] != []) + int(
            stats_mem['msgdict'] != []) + int(stats_memswap['msgdict'] != [])
        if space_number == 0:
            space_number = 1
        if screen_x > (space_number * self.space_between_column + l):
            self.space_between_column = int((screen_x - l) / space_number)
        # Display
        if self.args.percpu:
            self.display_plugin(stats_percpu)
        else:
            self.display_plugin(stats_cpu, display_optional=(screen_x >= 80))
        self.new_column()
        self.display_plugin(stats_load)
        self.new_column()
        self.display_plugin(
            stats_mem,
            display_optional=(screen_x >=
                              (space_number * self.space_between_column + l)))
        self.new_column()
        self.display_plugin(stats_memswap)
        # Space between column
        self.space_between_column = 3

        # Backup line position
        self.saved_line = self.next_line

        # Display left sidebar (NETWORK+DISKIO+FS+SENSORS+Current time)
        self.init_column()
        self.new_line()
        self.display_plugin(stats_network)
        self.new_line()
        self.display_plugin(stats_diskio)
        self.new_line()
        self.display_plugin(stats_fs)
        self.new_line()
        self.display_plugin(stats_sensors)
        self.new_line()
        self.display_plugin(stats_now)

        # If space available...
        if screen_x > 52:
            # Restore line position
            self.next_line = self.saved_line

            # Display right sidebar (PROCESS_COUNT+MONITORED+PROCESS_LIST+ALERT)
            self.new_column()
            self.new_line()
            self.display_plugin(stats_processcount)
            if glances_processes.get_process_filter(
            ) == None and cs_status == 'None':
                # Do not display stats monitor list if a filter exist
                self.new_line()
                self.display_plugin(stats_monitor)
            self.new_line()
            self.display_plugin(
                stats_processlist,
                display_optional=(screen_x > 102),
                display_additional=(is_mac == False),
                max_y=(screen_y - self.get_stats_display_height(stats_alert) -
                       2))
            self.new_line()
            self.display_plugin(stats_alert)

        # History option
        # Generate history graph
        if self.history_tag and self.args.enable_history:
            self.display_popup(
                _("Graphs history generated in %s") %
                self.glances_history.get_output_folder())
            self.glances_history.generate_graph(stats)
        elif self.reset_history_tag and self.args.enable_history:
            self.display_popup(_("Reset history"))
            self.glances_history.reset(stats)
        elif (self.history_tag
              or self.reset_history_tag) and not self.args.enable_history:
            self.display_popup(
                _("History disabled\nEnable it using --enable-history"))
        self.history_tag = False
        self.reset_history_tag = False

        # Display edit filter popup
        # Only in standalone mode (cs_status == 'None')
        if self.edit_filter and cs_status == 'None':
            new_filter = self.display_popup(
                _("Process filter pattern: "),
                is_input=True,
                input_value=glances_processes.get_process_filter())
            glances_processes.set_process_filter(new_filter)
        elif self.edit_filter and cs_status != 'None':
            self.display_popup(
                _("Process filter only available in standalone mode"))
        self.edit_filter = False

        return True
Пример #30
0
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""Battery plugin."""

# Import Glances libs
from glances.core.glances_globals import logger
from glances.plugins.glances_plugin import GlancesPlugin

# Batinfo library (optional; Linux-only)
try:
    import batinfo
except ImportError:
    logger.debug(_("Cannot grab battery sensor. Missing BatInfo library."))


class Plugin(GlancesPlugin):

    """Glances' battery capacity plugin.

    stats is a list
    """

    def __init__(self, args=None):
        """Init the plugin."""
        GlancesPlugin.__init__(self, args=args)

        # Init the sensor class
        self.glancesgrabbat = GlancesGrabBat()
Пример #31
0
    def display_popup(self,
                      message,
                      size_x=None,
                      size_y=None,
                      duration=3,
                      is_input=False,
                      input_size=30,
                      input_value=None):
        """
        If is_input is False:
         Display a centered popup with the given message during duration seconds
         If size_x and size_y: set the popup size
         else set it automatically
         Return True if the popup could be displayed
        If is_input is True:
         Display a centered popup with the given message and a input field
         If size_x and size_y: set the popup size
         else set it automatically
         Return the input string or None if the field is empty        
        """

        # Center the popup
        if size_x is None:
            size_x = len(message) + 4
            # Add space for the input field
            if is_input:
                size_x += input_size
        if size_y is None:
            size_y = message.count('\n') + 1 + 4
        screen_x = self.screen.getmaxyx()[1]
        screen_y = self.screen.getmaxyx()[0]
        if size_x > screen_x or size_y > screen_y:
            # No size to display the popup => abord
            return False
        pos_x = int((screen_x - size_x) / 2)
        pos_y = int((screen_y - size_y) / 2)

        # Create the popup
        popup = curses.newwin(size_y, size_x, pos_y, pos_x)

        # Fill the popup
        popup.border()

        # Add the message
        y = 0
        for m in message.split('\n'):
            popup.addnstr(2 + y, 2, m, len(m))
            y += 1

        if is_input and not is_windows:
            # Create a subwindow for the text field
            subpop = popup.derwin(1, input_size, 2, 2 + len(m))
            subpop.attron(self.__colors_list['FILTER'])
            # Init the field with the current value
            if input_value is not None:
                subpop.addnstr(0, 0, input_value, len(input_value))
            # Display the popup
            popup.refresh()
            subpop.refresh()
            # Create the textbox inside the subwindows
            self.set_cursor(2)
            textbox = glances_textbox(subpop, insert_mode=False)
            textbox.edit()
            self.set_cursor(0)
            if textbox.gather() != '':
                logger.debug(
                    _("User enters the following process filter patern: %s") %
                    textbox.gather())
                return textbox.gather()[:-1]
            else:
                logger.debug(_("User clears the process filter patern"))
                return None
        else:
            # Display the popup
            popup.refresh()
            curses.napms(duration * 1000)
            return True
Пример #32
0
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""Battery plugin."""

# Import Glances libs
from glances.core.glances_globals import logger
from glances.plugins.glances_plugin import GlancesPlugin

# Batinfo library (optional; Linux-only)
try:
    import batinfo
except ImportError:
    logger.debug("Batinfo library not found. Glances cannot grab battery info.")
    pass


class Plugin(GlancesPlugin):

    """Glances' battery capacity plugin.

    stats is a list
    """

    def __init__(self, args=None):
        """Init the plugin."""
        GlancesPlugin.__init__(self, args=args)

        # Init the sensor class
Пример #33
0
 def load_limits(self, config):
     """Load the monitored list from the conf file."""
     logger.debug(_("Monitor plugin configuration detected in the configuration file"))
     self.glances_monitors = glancesMonitorList(config)
Пример #34
0
    def display(self, stats, cs_status="None"):
        """Display stats on the screen.

        stats: Stats database to display
        cs_status:
            "None": standalone or server mode
            "Connected": Client is connected to a Glances server
            "SNMP": Client is connected to a SNMP server
            "Disconnected": Client is disconnected from the server

        Return:
            True if the stats have been displayed
            False if the help have been displayed
        """
        # Init the internal line/column for Glances Curses
        self.init_line_column()

        # Get the screen size
        screen_x = self.screen.getmaxyx()[1]
        screen_y = self.screen.getmaxyx()[0]

        # No processes list in SNMP mode
        if cs_status == 'SNMP':
            # so... more space for others plugins
            plugin_max_width = 43
        else:
            plugin_max_width = None

        # Update the stats messages
        ###########################

        # Update the client server status
        self.args.cs_status = cs_status
        stats_system = stats.get_plugin(
            'system').get_stats_display(args=self.args)
        stats_uptime = stats.get_plugin('uptime').get_stats_display()
        if self.args.percpu:
            stats_percpu = stats.get_plugin('percpu').get_stats_display()
        else:
            stats_cpu = stats.get_plugin('cpu').get_stats_display()
        stats_load = stats.get_plugin('load').get_stats_display()
        stats_mem = stats.get_plugin('mem').get_stats_display()
        stats_memswap = stats.get_plugin('memswap').get_stats_display()
        stats_network = stats.get_plugin('network').get_stats_display(
            args=self.args, max_width=plugin_max_width)
        stats_diskio = stats.get_plugin(
            'diskio').get_stats_display(args=self.args)
        stats_fs = stats.get_plugin('fs').get_stats_display(
            args=self.args, max_width=plugin_max_width)
        stats_sensors = stats.get_plugin(
            'sensors').get_stats_display(args=self.args)
        stats_now = stats.get_plugin('now').get_stats_display()
        stats_processcount = stats.get_plugin(
            'processcount').get_stats_display(args=self.args)
        stats_monitor = stats.get_plugin(
            'monitor').get_stats_display(args=self.args)
        stats_alert = stats.get_plugin(
            'alert').get_stats_display(args=self.args)

        # Adapt number of processes to the available space
        max_processes_displayed = screen_y - 11 - \
            self.get_stats_display_height(stats_alert)
        if self.args.enable_process_extended and not self.args.process_tree:
            max_processes_displayed -= 4
        if max_processes_displayed < 0:
            max_processes_displayed = 0
        if glances_processes.get_max_processes() is None or \
           glances_processes.get_max_processes() != max_processes_displayed:
            logger.debug("Set number of displayed processes to %s" %
                         max_processes_displayed)
            glances_processes.set_max_processes(max_processes_displayed)

        stats_processlist = stats.get_plugin(
            'processlist').get_stats_display(args=self.args)

        # Display the stats on the curses interface
        ###########################################

        # Help screen (on top of the other stats)
        if self.args.help_tag:
            # Display the stats...
            self.display_plugin(
                stats.get_plugin('help').get_stats_display(args=self.args))
            # ... and exit
            return False

        # Display first line (system+uptime)
        self.new_line()
        l = self.get_stats_display_width(
            stats_system) + self.get_stats_display_width(stats_uptime) + self.space_between_column
        self.display_plugin(stats_system, display_optional=(screen_x >= l))
        self.new_column()
        self.display_plugin(stats_uptime)

        # Display second line (CPU|PERCPU+LOAD+MEM+SWAP+<SUMMARY>)
        # CPU|PERCPU
        self.init_column()
        self.new_line()
        if self.args.percpu:
            l = self.get_stats_display_width(stats_percpu)
        else:
            l = self.get_stats_display_width(stats_cpu)
        l += self.get_stats_display_width(stats_load) + self.get_stats_display_width(
            stats_mem) + self.get_stats_display_width(stats_memswap)
        # Space between column
        space_number = int(stats_load['msgdict'] != [
        ]) + int(stats_mem['msgdict'] != []) + int(stats_memswap['msgdict'] != [])
        if space_number == 0:
            space_number = 1
        if screen_x > (space_number * self.space_between_column + l):
            self.space_between_column = int((screen_x - l) / space_number)
        # Display
        if self.args.percpu:
            self.display_plugin(stats_percpu)
        else:
            self.display_plugin(stats_cpu, display_optional=(screen_x >= 80))
        self.new_column()
        self.display_plugin(stats_load)
        self.new_column()
        self.display_plugin(stats_mem, display_optional=(
            screen_x >= (space_number * self.space_between_column + l)))
        self.new_column()
        self.display_plugin(stats_memswap)
        # Space between column
        self.space_between_column = 3

        # Backup line position
        self.saved_line = self.next_line

        # Display left sidebar (NETWORK+DISKIO+FS+SENSORS+Current time)
        self.init_column()
        if (not (self.args.disable_network and self.args.disable_diskio
                 and self.args.disable_fs and self.args.disable_sensors)) \
                and not self.args.disable_left_sidebar:
            self.new_line()
            self.display_plugin(stats_network)
            self.new_line()
            self.display_plugin(stats_diskio)
            self.new_line()
            self.display_plugin(stats_fs)
            self.new_line()
            self.display_plugin(stats_sensors)
            self.new_line()
            self.display_plugin(stats_now)

        # If space available...
        if screen_x > 52:
            # Restore line position
            self.next_line = self.saved_line

            # Display right sidebar
            # (PROCESS_COUNT+MONITORED+PROCESS_LIST+ALERT)
            self.new_column()
            self.new_line()
            self.display_plugin(stats_processcount)
            if glances_processes.get_process_filter() is None and cs_status == 'None':
                # Do not display stats monitor list if a filter exist
                self.new_line()
                self.display_plugin(stats_monitor)
            self.new_line()
            self.display_plugin(stats_processlist,
                                display_optional=(screen_x > 102),
                                display_additional=(not is_mac),
                                max_y=(screen_y - self.get_stats_display_height(stats_alert) - 2))
            self.new_line()
            self.display_plugin(stats_alert)

        # History option
        # Generate history graph
        if self.history_tag and self.args.enable_history:
            self.display_popup(
                _("Generate graphs history in %s\nPlease wait...") % self.glances_history.get_output_folder())
            self.display_popup(
                _("Generate graphs history in %s\nDone: %s graphs generated") % (self.glances_history.get_output_folder(), self.glances_history.generate_graph(stats)))
        elif self.reset_history_tag and self.args.enable_history:
            self.display_popup(_("Reset history"))
            self.glances_history.reset(stats)
        elif (self.history_tag or self.reset_history_tag) and not self.args.enable_history:
            try:
                self.glances_history.graph_enabled()
            except Exception:
                self.display_popup(
                    _("History disabled\nEnable it using --enable-history"))
            else:
                self.display_popup(
                    _("History disabled\nPlease install MatPlotLib"))
        self.history_tag = False
        self.reset_history_tag = False

        # Display edit filter popup
        # Only in standalone mode (cs_status == 'None')
        if self.edit_filter and cs_status == 'None':
            new_filter = self.display_popup(_("Process filter pattern: "),
                                            is_input=True,
                                            input_value=glances_processes.get_process_filter())
            glances_processes.set_process_filter(new_filter)
        elif self.edit_filter and cs_status != 'None':
            self.display_popup(
                _("Process filter only available in standalone mode"))
        self.edit_filter = False

        return True
Пример #35
0
    def login(self, return_to_browser=False):
        """Logon to the server."""
        ret = True

        if not self.args.snmp_force:
            # First of all, trying to connect to a Glances server
            self.set_mode('glances')
            client_version = None
            try:
                client_version = self.client.init()
            except socket.error as err:
                # Fallback to SNMP
                logger.error("Connection to Glances server failed (%s)" % err)
                self.set_mode('snmp')
                fallbackmsg = _("Trying fallback to SNMP...")
                if not return_to_browser:
                    print(fallbackmsg)
                else:
                    logger.info(fallbackmsg)
            except ProtocolError as err:
                # Others errors
                if str(err).find(" 401 ") > 0:
                    msg = "Connection to server failed (bad password)"
                else:
                    msg = "Connection to server failed ({0})".format(err)
                if not return_to_browser:
                    logger.critical(msg)
                    sys.exit(2)
                else:
                    logger.error(msg)
                    return False

            if self.get_mode() == 'glances' and version[:3] == client_version[:3]:
                # Init stats
                self.stats = GlancesStatsClient()
                self.stats.set_plugins(json.loads(self.client.getAllPlugins()))
                logger.debug(
                    "Client version: %s / Server version: %s" % (version, client_version))
            else:
                logger.error(
                    "Client and server not compatible: Client version: %s / Server version: %s" % (version, client_version))

        else:
            self.set_mode('snmp')

        if self.get_mode() == 'snmp':
            logger.info("Trying to grab stats by SNMP...")
            # Fallback to SNMP if needed
            from glances.core.glances_stats import GlancesStatsClientSNMP

            # Init stats
            self.stats = GlancesStatsClientSNMP(args=self.args)

            if not self.stats.check_snmp():
                logger.error("Connection to SNMP server failed")
                if not return_to_browser:
                    sys.exit(2)
                else:
                    return False

        if ret:
            # Load limits from the configuration file
            # Each client can choose its owns limits
            self.stats.load_limits(self.config)

            # Init screen
            self.screen = GlancesCursesClient(args=self.args)

        # Return result
        return ret
Пример #36
0
    def display_popup(self, message,
                      size_x=None, size_y=None,
                      duration=3,
                      is_input=False,
                      input_size=30,
                      input_value=None):
        """
        If is_input is False:
         Display a centered popup with the given message during duration seconds
         If size_x and size_y: set the popup size
         else set it automatically
         Return True if the popup could be displayed
        If is_input is True:
         Display a centered popup with the given message and a input field
         If size_x and size_y: set the popup size
         else set it automatically
         Return the input string or None if the field is empty
        """

        # Center the popup
        sentence_list = message.split('\n')
        if size_x is None:
            size_x = len(max(sentence_list, key=len)) + 4
            # Add space for the input field
            if is_input:
                size_x += input_size
        if size_y is None:
            size_y = len(sentence_list) + 4
        screen_x = self.screen.getmaxyx()[1]
        screen_y = self.screen.getmaxyx()[0]
        if size_x > screen_x or size_y > screen_y:
            # No size to display the popup => abord
            return False
        pos_x = int((screen_x - size_x) / 2)
        pos_y = int((screen_y - size_y) / 2)

        # Create the popup
        popup = curses.newwin(size_y, size_x, pos_y, pos_x)

        # Fill the popup
        popup.border()

        # Add the message
        y = 0
        for m in message.split('\n'):
            popup.addnstr(2 + y, 2, m, len(m))
            y += 1

        if is_input and not is_windows:
            # Create a subwindow for the text field
            subpop = popup.derwin(1, input_size, 2, 2 + len(m))
            subpop.attron(self.colors_list['FILTER'])
            # Init the field with the current value
            if input_value is not None:
                subpop.addnstr(0, 0, input_value, len(input_value))
            # Display the popup
            popup.refresh()
            subpop.refresh()
            # Create the textbox inside the subwindows
            self.set_cursor(2)
            textbox = GlancesTextbox(subpop, insert_mode=False)
            textbox.edit()
            self.set_cursor(0)
            if textbox.gather() != '':
                logger.debug(
                    "User enters the following process filter patern: %s" % textbox.gather())
                return textbox.gather()[:-1]
            else:
                logger.debug("User clears the process filter patern")
                return None
        else:
            # Display the popup
            popup.refresh()
            curses.napms(duration * 1000)
            return True
Пример #37
0
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Battery plugin."""

# Import Glances libs
from glances.core.glances_globals import logger
from glances.plugins.glances_plugin import GlancesPlugin

# Batinfo library (optional; Linux-only)
try:
    import batinfo
except ImportError:
    logger.debug(_("Cannot grab battery sensor. Missing BatInfo library."))


class Plugin(GlancesPlugin):
    """Glances' battery capacity plugin.

    stats is a list
    """
    def __init__(self, args=None):
        """Init the plugin."""
        GlancesPlugin.__init__(self, args=args)

        # Init the sensor class
        self.glancesgrabbat = GlancesGrabBat()

        # We do not want to display the stat in a dedicated area
Пример #38
0
        ServiceBrowser,
        ServiceInfo,
        Zeroconf
    )
    zeroconf_tag = True
except ImportError:
    zeroconf_tag = False

# Import Glances libs
from glances.core.glances_globals import appname, logger

# Zeroconf 0.16 or higher is needed
if zeroconf_tag:
    zeroconf_min_version = (0, 16, 0)
    zeroconf_version = tuple([int(num) for num in __zeroconf_version.split('.')])
    logger.debug("Zeroconf version {0} detected.".format(__zeroconf_version))
    if zeroconf_version < zeroconf_min_version:
        logger.critical("Please install zeroconf 0.16 or higher.")
        sys.exit(1)

# Global var
zeroconf_type = "_%s._tcp." % appname


class AutoDiscovered(object):

    """Class to manage the auto discovered servers dict"""

    def __init__(self):
        # server_dict is a list of dict (JSON compliant)
        # [ {'key': 'zeroconf name', ip': '172.1.2.3', 'port': 61209, 'cpu': 3, 'mem': 34 ...} ... ]
Пример #39
0
    def display(self, servers_list):
        """Display the servers list
        Return:
            True if the stats have been displayed
            False if the stats have not been displayed (no server available)
        """
        # Init the internal line/column for Glances Curses
        self.init_line_column()

        # Get the current screen size
        screen_x = self.screen.getmaxyx()[1]
        screen_y = self.screen.getmaxyx()[0]

        # Init position
        x = 0
        y = 0

        # Display top header
        if len(servers_list) == 0:
            if self.first_scan and not self.args.disable_autodiscover:
                msg = _("Glances is scanning your network (please wait)...")
                self.first_scan = False
            else:
                msg = _("No Glances servers available")
        elif len(servers_list) == 1:
            msg = _("One Glances server available")
        else:
            msg = _("%d Glances servers available" %
                    len(servers_list))
        if self.args.disable_autodiscover:
            msg += ' ' + _("(auto discover is disabled)")
        self.term_window.addnstr(y, x,
                                 msg,
                                 screen_x - x,
                                 self.colors_list['TITLE'])

        if len(servers_list) == 0:
            return False

        # Display the Glances server list
        #================================

        # Table of table
        # Item description: [stats_id, column name, column size]
        column_def = [
            ['name', _('Name'), 16],
            ['alias', None, None],
            ['load_min5', _('LOAD'), 6],
            ['cpu_percent', _('CPU%'), 5],
            ['mem_percent', _('MEM%'), 5],
            ['status', _('STATUS'), 8],
            ['ip', _('IP'), 15],
            # ['port', _('PORT'), 5],
            ['hr_name', _('OS'), 16],
        ]
        y = 2

        # Display table header
        cpt = 0
        xc = x + 2
        for c in column_def:
            if xc < screen_x and y < screen_y and c[1] is not None:
                self.term_window.addnstr(y, xc,
                                         c[1],
                                         screen_x - x,
                                         self.colors_list['BOLD'])
                xc += c[2] + self.space_between_column
            cpt += 1
        y += 1

        # If a servers has been deleted from the list...
        # ... and if the cursor is in the latest position
        if self.cursor_get() > len(servers_list) - 1:
            # Set the cursor position to the latest item
            self.cursor_set(len(servers_list) - 1)

        # Display table
        line = 0
        for v in servers_list:
            # Get server stats
            server_stat = {}
            for c in column_def:
                try:
                    server_stat[c[0]] = v[c[0]]
                except KeyError as e:
                    logger.debug(
                        "Cannot grab stats {0} from server (KeyError: {1})".format(c[0], e))
                    server_stat[c[0]] = '?'
                # Display alias instead of name
                try:
                    if c[0] == 'alias' and v[c[0]] is not None:
                        server_stat['name'] = v[c[0]]
                except KeyError as e:
                    pass

            # Display line for server stats
            cpt = 0
            xc = x

            # Is the line selected ?
            if line == self.cursor_get():
                # Display cursor
                self.term_window.addnstr(y, xc,
                                         ">",
                                         screen_x - xc,
                                         self.colors_list['BOLD'])

            # Display alias instead of name
            server_stat

            # Display the line
            xc += 2
            for c in column_def:
                if xc < screen_x and y < screen_y and c[1] is not None:
                    # Display server stats
                    self.term_window.addnstr(y, xc,
                                             "%s" % server_stat[c[0]],
                                             c[2],
                                             self.colors_list[v['status']])
                    xc += c[2] + self.space_between_column
                cpt += 1
            # Next line, next server...
            y += 1
            line += 1

        return True