Exemplo n.º 1
0
    def run(self, stat_name, criticity, commands, mustache_dict=None):
        """Run the commands (in background).

        - stats_name: plugin_name (+ header)
        - criticity: criticity of the trigger
        - commands: a list of command line with optional {{mustache}}
        - mustache_dict: Plugin stats (can be use within {{mustache}})

        Return True if the commands have been ran.
        """
        if self.get(stat_name) == criticity or not self.start_timer.finished():
            # Action already executed => Exit
            return False

        logger.debug("Run action {} for {} ({}) with stats {}".format(
            commands, stat_name, criticity, mustache_dict))

        # Run all actions in background
        for cmd in commands:
            # Replace {{arg}} by the dict one (Thk to {Mustache})
            if pystache_tag:
                cmd_full = pystache.render(cmd, mustache_dict)
            else:
                cmd_full = cmd
            # Execute the action
            logger.info("Action triggered for {} ({}): {}".format(stat_name, criticity, cmd_full))
            logger.debug("Stats value for the trigger: {}".format(mustache_dict))
            try:
                Popen(cmd_full, shell=True)
            except OSError as e:
                logger.error("Can't execute the action ({})".format(e))

        self.set(stat_name, criticity)

        return True
Exemplo n.º 2
0
    def init(self):
        """Init the connection to the ES server."""
        if not self.export_enable:
            return None

        try:
            es = Elasticsearch(hosts=['{}:{}'.format(self.host, self.port)])
        except Exception as e:
            logger.critical(
                "Cannot connect to ElasticSearch server %s:%s (%s)" %
                (self.host, self.port, e))
            sys.exit(2)
        else:
            logger.info("Connected to the ElasticSearch server %s:%s" %
                        (self.host, self.port))

        try:
            index_count = es.count(index=self.index)['count']
        except Exception as e:
            # Index did not exist, it will be created at the first write
            # Create it...
            es.indices.create(self.index)
        else:
            logger.info(
                "There is already %s entries in the ElasticSearch %s index" %
                (index_count, self.index))

        return es
Exemplo n.º 3
0
def end():
    """Stop Glances."""
    worker.end()
    logger.info("Stop Glances (with CTRL-C)")

    # The end...
    sys.exit(0)
Exemplo n.º 4
0
def main():
    """Main entry point for Glances.

    Select the mode (standalone, client or server)
    Run it...
    """
    # Log Glances and PSutil version
    logger.info('Start Glances {}'.format(__version__))
    logger.info('{} {} and PSutil {} detected'.format(
        platform.python_implementation(), platform.python_version(),
        psutil_version))

    # Share global var
    global core, worker

    # Create the Glances main instance
    core = GlMain()

    # Catch the CTRL-C signal
    signal.signal(signal.SIGINT, __signal_handler)

    # Init the worker
    worker = Worker(config=core.get_config(), args=core.get_args())

    # Start the standalone (CLI) loop
    worker.run()
Exemplo n.º 5
0
    def filter(self, value):
        """Set the filter (as a sting) and compute the regular expression
        A filter could be one of the following:
        - python > Process name of cmd start with python
        - .*python.* > Process name of cmd contain python
        - username:nicolargo > Process of nicolargo user
        """
        self._filter_input = value
        if value is None:
            self._filter = None
            self._filter_key = None
        else:
            new_filter = value.split(':')
            if len(new_filter) == 1:
                self._filter = new_filter[0]
                self._filter_key = None
            else:
                self._filter = new_filter[1]
                self._filter_key = new_filter[0]

        self._filter_re = None
        if self.filter is not None:
            logger.info("Set filter to {} on key {}".format(
                self.filter, self.filter_key))
            # Compute the regular expression
            try:
                self._filter_re = re.compile(self.filter)
                logger.debug("Filter regex compilation OK: {}".format(
                    self.filter))
            except Exception as e:
                logger.error("Cannot compile filter regex: {} ({})".format(
                    self.filter, e))
                self._filter = None
                self._filter_re = None
                self._filter_key = None
Exemplo n.º 6
0
    def load(self, config):
        """Load the server list from the configuration file."""
        server_list = []

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

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

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

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

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

        return server_list
Exemplo n.º 7
0
    def _init_history(self):
        '''Init the history option'''

        self.reset_history_tag = False
        self.graph_tag = False
        if self.args.export_graph:
            logger.info('Export graphs function enabled with output path %s' %
                        self.args.path_graph)
            from gl.exports.graph import GlancesGraph
            self.glances_graph = GlancesGraph(self.args.path_graph)
            if not self.glances_graph.graph_enabled():
                self.args.export_graph = False
                logger.error('Export graphs disabled')
Exemplo n.º 8
0
    def __init__(self, config=None, args=None):
        logger.debug("[Worker.__init__]")
        # Quiet mode
        self._quiet = args.quiet
        self.refresh_time = args.time

        # Init stats
        self.stats = Stats(config=config, args=args)

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

        # Manage optionnal process filter
        if args.process_filter is not None:
            gl_processes.process_filter = args.process_filter

        if args.no_kernel_threads:
            # Ignore kernel threads in process list
            gl_processes.disable_kernel_threads()

        try:
            if args.process_tree:
                # Enable process tree view
                gl_processes.enable_tree()
        except AttributeError:
            pass

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

        if self.quiet:
            logger.info("Quiet mode is ON: Nothing will be displayed")
            # In quiet mode, nothing is displayed
            gl_processes.max_processes = 0
        else:
            # Default number of processes to displayed is set to 50
            gl_processes.max_processes = 50

            # Init screen
            self.screen = Screen(config=config, args=args)
Exemplo n.º 9
0
    def parse_tags(self, tags):
        """Parse tags into a dict.

        tags: a comma separated list of 'key:value' pairs.
            Example: foo:bar,spam:eggs
        dtags: a dict of tags.
            Example: {'foo': 'bar', 'spam': 'eggs'}
        """
        dtags = {}
        if tags:
            try:
                dtags = dict([x.split(':') for x in tags.split(',')])
            except ValueError:
                # one of the 'key:value' pairs was missing
                logger.info('Invalid tags passed: %s', tags)
                dtags = {}

        return dtags
Exemplo n.º 10
0
    def init(self):
        """Init the connection to the InfluxDB server."""
        if not self.export_enable:
            return None

        # Cluster
        try:
            cluster = Cluster([self.host],
                              port=int(self.port),
                              protocol_version=int(self.protocol_version))
            session = cluster.connect()
        except Exception as e:
            logger.critical(
                "Cannot connect to Cassandra cluster '%s:%s' (%s)" %
                (self.host, self.port, e))
            sys.exit(2)

        # Keyspace
        try:
            session.set_keyspace(self.keyspace)
        except InvalidRequest as e:
            logger.info("Create keyspace {} on the Cassandra cluster".format(
                self.keyspace))
            c = "CREATE KEYSPACE %s WITH replication = { 'class': 'SimpleStrategy', 'replication_factor': '%s' }" % (
                self.keyspace, self.replication_factor)
            session.execute(c)
            session.set_keyspace(self.keyspace)

        logger.info(
            "Stats will be exported to Cassandra cluster {0} ({1}) in keyspace {2}"
            .format(cluster.metadata.cluster_name,
                    cluster.metadata.all_hosts(), self.keyspace))

        # Table
        try:
            session.execute(
                "CREATE TABLE %s (plugin text, time timeuuid, stat map<text,float>, PRIMARY KEY (plugin, time)) WITH CLUSTERING ORDER BY (time DESC)"
                % self.table)
        except:
            logger.debug("Cassandra table %s already exist" % self.table)

        return cluster, session
Exemplo n.º 11
0
    def init(self):
        """Init the connection to the InfluxDB server."""
        if not self.export_enable:
            return None

        try:
            db = InfluxDBClient(host=self.host,
                                port=self.port,
                                username=self.user,
                                password=self.password,
                                database=self.db)
            get_all_db = [i['name'] for i in db.get_list_database()]
            self.version = INFLUXDB_09PLUS
        except InfluxDBClientError:
            # https://github.com/influxdb/influxdb-python/issues/138
            logger.info("Trying fallback to InfluxDB v0.8")
            db = InfluxDBClient08(host=self.host,
                                  port=self.port,
                                  username=self.user,
                                  password=self.password,
                                  database=self.db)
            get_all_db = [i['name'] for i in db.get_list_database()]
            self.version = INFLUXDB_08
        except InfluxDBClientError08 as e:
            logger.critical("Cannot connect to InfluxDB database '%s' (%s)" %
                            (self.db, e))
            sys.exit(2)

        if self.db in get_all_db:
            logger.info("Stats will be exported to InfluxDB server: {}".format(
                db._baseurl))
        else:
            logger.critical(
                "InfluxDB database '%s' did not exist. Please create it" %
                self.db)
            sys.exit(2)

        return db
Exemplo n.º 12
0
    def __init__(self, config=None, args=None):
        """Init the CSV export IF."""
        super(Export, self).__init__(config=config, args=args)

        # CSV file name
        self.csv_filename = args.export_csv

        # Set the CSV output file
        try:
            if PY3:
                self.csv_file = open(self.csv_filename, 'w', newline='')
            else:
                self.csv_file = open(self.csv_filename, 'wb')
            self.writer = csv.writer(self.csv_file)
        except IOError as e:
            logger.critical("Cannot create the CSV file: {}".format(e))
            sys.exit(2)

        logger.info("Stats exported to CSV file: {}".format(self.csv_filename))

        self.export_enable = True

        self.first_line = True
Exemplo n.º 13
0
import os

from gl.compat import iterkeys
from gl.logger import logger

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


class GlancesGraph(object):
    """Thanks to this class, Glances can export history to graphs."""
    def __init__(self, output_folder):
        self.output_folder = output_folder

    def get_output_folder(self):
        """Return the output folder where the graph are generated."""
        return self.output_folder

    def graph_enabled(self):
        """Return True if Glances can generate history graphs."""
        return matplotlib_check
Exemplo n.º 14
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)

        # 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

        # Manage full quicklook option
        if args.full_quicklook:
            logger.info("Disable QuickLook menu")
            args.disable_quicklook = False
            args.disable_cpu = True
            args.disable_mem = True
            args.disable_swap = True
            args.disable_load = False

        # Manage disable_top option
        if args.disable_top:
            logger.info("Disable top menu")
            args.disable_quicklook = True
            args.disable_cpu = True
            args.disable_mem = True
            args.disable_swap = True
            args.disable_load = True

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

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

        # For export graph, history is mandatory
        if args.export_graph and args.disable_history:
            logger.critical("Can not export graph if history is disabled")
            sys.exit(2)

        # Disable HDDTemp if sensors are disabled
        if args.disable_sensors:
            args.disable_hddtemp = True
            logger.debug("Sensors and HDDTemp are disabled")

        return args
Exemplo n.º 15
0
    def __catch_key(self, return_to_browser=False):
        # Catch the pressed key
        self.pressedkey = self.get_key(self.term_window)

        # Actions...
        if self.pressedkey == ord('\x1b') or self.pressedkey == ord('q'):
            # 'ESC'|'q' > Quit
            if return_to_browser:
                logger.info("Stop Glances client and return to the browser")
            else:
                self.end()
                logger.info("Stop Glances")
                sys.exit(0)
        elif self.pressedkey == 10:
            # 'ENTER' > Edit the process filter
            self.edit_filter = not self.edit_filter
        elif self.pressedkey == ord('0'):
            # '0' > Switch between IRIX and Solaris mode
            self.args.disable_irix = not self.args.disable_irix
        elif self.pressedkey == ord('1'):
            # '1' > Switch between CPU and PerCPU information
            self.args.percpu = not self.args.percpu
        elif self.pressedkey == ord('2'):
            # '2' > Enable/disable left sidebar
            self.args.disable_left_sidebar = not self.args.disable_left_sidebar
        elif self.pressedkey == ord('3'):
            # '3' > Enable/disable quicklook
            self.args.disable_quicklook = not self.args.disable_quicklook
        elif self.pressedkey == ord('4'):
            # '4' > Enable/disable all but quick look and load
            self.args.full_quicklook = not self.args.full_quicklook
            if self.args.full_quicklook:
                self.args.disable_quicklook = False
                self.args.disable_cpu = True
                self.args.disable_mem = True
                self.args.disable_swap = True
            else:
                self.args.disable_quicklook = False
                self.args.disable_cpu = False
                self.args.disable_mem = False
                self.args.disable_swap = False
        elif self.pressedkey == ord('5'):
            # '5' > Enable/disable top menu
            logger.info(self.args.disable_top)
            self.args.disable_top = not self.args.disable_top
            if self.args.disable_top:
                self.args.disable_quicklook = True
                self.args.disable_cpu = True
                self.args.disable_mem = True
                self.args.disable_swap = True
                self.args.disable_load = True
            else:
                self.args.disable_quicklook = False
                self.args.disable_cpu = False
                self.args.disable_mem = False
                self.args.disable_swap = False
                self.args.disable_load = False
        elif self.pressedkey == ord('/'):
            # '/' > Switch between short/long name for processes
            self.args.process_short_name = not self.args.process_short_name
        elif self.pressedkey == ord('a'):
            # 'a' > Sort processes automatically and reset to 'cpu_percent'
            gl_processes.auto_sort = True
            gl_processes.sort_key = 'cpu_percent'
        elif self.pressedkey == ord('A'):
            # 'A' > enable/disable AMP module
            self.args.disable_amps = not self.args.disable_amps
        elif self.pressedkey == ord('b'):
            # 'b' > Switch between bit/s and Byte/s for network IO
            self.args.byte = not self.args.byte
        elif self.pressedkey == ord('B'):
            # 'B' > Switch between bit/s and IO/s for Disk IO
            self.args.diskio_iops = not self.args.diskio_iops
        elif self.pressedkey == ord('c'):
            # 'c' > Sort processes by CPU usage
            gl_processes.auto_sort = False
            gl_processes.sort_key = 'cpu_percent'
        elif self.pressedkey == ord('d'):
            # 'd' > Show/hide disk I/O stats
            self.args.disable_diskio = not self.args.disable_diskio
        elif self.pressedkey == ord('D'):
            # 'D' > Show/hide Docker stats
            self.args.disable_docker = not self.args.disable_docker
        elif self.pressedkey == ord('e'):
            # 'e' > Enable/Disable extended stats for top process
            self.args.enable_process_extended = not self.args.enable_process_extended
            if not self.args.enable_process_extended:
                gl_processes.disable_extended()
            else:
                gl_processes.enable_extended()
        elif self.pressedkey == ord('E'):
            # 'E' > Erase the process filter
            logger.info("Erase process filter")
            gl_processes.process_filter = None
        elif self.pressedkey == ord('F'):
            # 'F' > Switch between FS available and free space
            self.args.fs_free_space = not self.args.fs_free_space
        elif self.pressedkey == ord('f'):
            # 'f' > Show/hide fs / folder stats
            self.args.disable_fs = not self.args.disable_fs
            self.args.disable_folder = not self.args.disable_folder
        elif self.pressedkey == ord('g'):
            # 'g' > Export graphs to file
            self.graph_tag = not self.graph_tag
        elif self.pressedkey == ord('h'):
            # 'h' > Show/hide help
            self.args.help_tag = not self.args.help_tag
        elif self.pressedkey == ord('i'):
            # 'i' > Sort processes by IO rate (not available on OS X)
            gl_processes.auto_sort = False
            gl_processes.sort_key = 'io_counters'
        elif self.pressedkey == ord('I'):
            # 'I' > Show/hide IP module
            self.args.disable_ip = not self.args.disable_ip
        elif self.pressedkey == ord('l'):
            # 'l' > Show/hide log messages
            self.args.disable_log = not self.args.disable_log
        elif self.pressedkey == ord('m'):
            # 'm' > Sort processes by MEM usage
            gl_processes.auto_sort = False
            gl_processes.sort_key = 'memory_percent'
        elif self.pressedkey == ord('M'):
            # 'M' > Reset processes summary min/max
            self.args.reset_minmax_tag = not self.args.reset_minmax_tag
        elif self.pressedkey == ord('n'):
            # 'n' > Show/hide network stats
            self.args.disable_network = not self.args.disable_network
        elif self.pressedkey == ord('p'):
            # 'p' > Sort processes by name
            gl_processes.auto_sort = False
            gl_processes.sort_key = 'name'
        elif self.pressedkey == ord('P'):
            # 'P' > Disable ports scan plugins
            self.args.disable_ports = not self.args.disable_ports
        elif self.pressedkey == ord('Q'):
            self.args.disable_irq = not self.args.disable_irq
        elif self.pressedkey == ord('r'):
            # 'r' > Reset history
            self.reset_history_tag = not self.reset_history_tag
        elif self.pressedkey == ord('R'):
            # 'R' > Hide RAID plugins
            self.args.disable_raid = not self.args.disable_raid
        elif self.pressedkey == ord('s'):
            # 's' > Show/hide sensors stats (Linux-only)
            self.args.disable_sensors = not self.args.disable_sensors
        elif self.pressedkey == ord('t'):
            # 't' > Sort processes by TIME usage
            gl_processes.auto_sort = False
            gl_processes.sort_key = 'cpu_times'
        elif self.pressedkey == ord('T'):
            # 'T' > View network traffic as sum Rx+Tx
            self.args.network_sum = not self.args.network_sum
        elif self.pressedkey == ord('u'):
            # 'u' > Sort processes by USER
            gl_processes.auto_sort = False
            gl_processes.sort_key = 'username'
        elif self.pressedkey == ord('U'):
            # 'U' > View cumulative network I/O (instead of bitrate)
            self.args.network_cumul = not self.args.network_cumul
        elif self.pressedkey == ord('w'):
            # 'w' > Delete finished warning logs
            glances_logs.clean()
        elif self.pressedkey == ord('x'):
            # 'x' > Delete finished warning and critical logs
            glances_logs.clean(critical=True)
        elif self.pressedkey == ord('z'):
            # 'z' > Enable/Disable processes stats (count + list + AMPs)
            # Enable/Disable display
            self.args.disable_process = not self.args.disable_process
            # Enable/Disable update
            if self.args.disable_process:
                gl_processes.disable()
            else:
                gl_processes.enable()
        # Return the key code
        return self.pressedkey