コード例 #1
0
ファイル: amps_list.py プロジェクト: mondo0/testgl
    def update(self):
        """Update the command result attributed."""
        # Search application monitored processes by a regular expression
        processlist = gl_processes.getalllist()

        # Iter upon the AMPs dict
        for k, v in iteritems(self.get()):
            try:
                amps_list = [p for p in processlist for c in p['cmdline'] if re.search(v.regex(), c) is not None]
            except TypeError:
                continue
            if len(amps_list) > 0:
                # At least one process is matching the regex
                logger.debug("AMPS: {} process detected (PID={})".format(k, amps_list[0]['pid']))
                # Call the AMP update method
                thread = threading.Thread(target=v.update_wrapper, args=[amps_list])
                thread.start()
            else:
                # Set the process number to 0
                v.set_count(0)
                if v.count_min() is not None and v.count_min() > 0:
                    # Only display the "No running process message" is countmin is defined
                    v.set_result("No running process")

        return self.__amps_dict
コード例 #2
0
ファイル: processes_tree.py プロジェクト: mondo0/testgl
    def build_tree(process_dict, sort_key, sort_reverse, hide_kernel_threads,
                   excluded_processes):
        """Build a process tree using using parent/child relationships.

        Return the tree root node.
        """
        tree_root = ProcessTreeNode(root=True)
        nodes_to_add_last = collections.deque()

        # first pass: add nodes whose parent are in the tree
        for process, stats in iteritems(process_dict):
            new_node = ProcessTreeNode(process, stats, sort_key, sort_reverse)
            try:
                parent_process = process.parent()
            except psutil.NoSuchProcess:
                # parent is dead, consider no parent
                parent_process = None
            if (parent_process is None) or (parent_process
                                            in excluded_processes):
                # no parent, or excluded parent, add this node at the top level
                tree_root.children.append(new_node)
            else:
                parent_node = tree_root.find_process(parent_process)
                if parent_node is not None:
                    # parent is already in the tree, add a new child
                    parent_node.children.append(new_node)
                else:
                    # parent is not in tree, add this node later
                    nodes_to_add_last.append(new_node)

        # next pass(es): add nodes to their parents if it could not be done in
        # previous pass
        while nodes_to_add_last:
            # pop from left and append to right to avoid infinite loop
            node_to_add = nodes_to_add_last.popleft()
            try:
                parent_process = node_to_add.process.parent()
            except psutil.NoSuchProcess:
                # parent is dead, consider no parent, add this node at the top
                # level
                tree_root.children.append(node_to_add)
            else:
                if (parent_process is None) or (parent_process
                                                in excluded_processes):
                    # no parent, or excluded parent, add this node at the top level
                    tree_root.children.append(node_to_add)
                else:
                    parent_node = tree_root.find_process(parent_process)
                    if parent_node is not None:
                        # parent is already in the tree, add a new child
                        parent_node.children.append(node_to_add)
                    else:
                        # parent is not in tree, add this node later
                        nodes_to_add_last.append(node_to_add)

        return tree_root
コード例 #3
0
    def update(self):
        """Update the AMP list."""
        # Reset stats
        self.reset()

        if self.input_method == 'local':
            for k, v in iteritems(self.glances_amps.update()):
                # self.stats.append({k: v.result()})
                self.stats.append({
                    'key': k,
                    'name': v.NAME,
                    'result': v.result(),
                    'refresh': v.refresh(),
                    'timer': v.time_until_refresh(),
                    'count': v.count(),
                    'countmin': v.count_min(),
                    'countmax': v.count_max(),
                })
        else:
            # Not available in SNMP mode
            pass

        return self.stats
コード例 #4
0
    def __build_export(self, stats):
        """Build the export lists."""
        export_names = []
        export_values = []

        if isinstance(stats, dict):
            # Stats is a dict
            # Is there a key ?
            if 'key' in iterkeys(stats):
                pre_key = '{}.'.format(stats[stats['key']])
            else:
                pre_key = ''
            # Walk through the dict
            for key, value in iteritems(stats):
                if isinstance(value, list):
                    try:
                        value = value[0]
                    except IndexError:
                        value = ''
                if isinstance(value, dict):
                    item_names, item_values = self.__build_export(value)
                    item_names = [
                        pre_key + key.lower() + str(i) for i in item_names
                    ]
                    export_names += item_names
                    export_values += item_values
                else:
                    export_names.append(pre_key + key.lower())
                    export_values.append(value)
        elif isinstance(stats, list):
            # Stats is a list (of dict)
            # Recursive loop through the list
            for item in stats:
                item_names, item_values = self.__build_export(item)
                export_names += item_names
                export_values += item_values
        return export_names, export_values
コード例 #5
0
ファイル: processes.py プロジェクト: mondo0/testgl
    def update(self):
        """Update the processes stats."""
        # Reset the stats
        self.processlist = []
        self.processcount = {'total': 0, 'running': 0, 'sleeping': 0, 'thread': 0}

        # Do not process if disable tag is set
        if self.disable_tag:
            return

        # Get the time since last update
        time_since_update = getTimeSinceLastUpdate('process_disk')

        # Build an internal dict with only mandatories stats (sort keys)
        processdict = {}
        excluded_processes = set()
        for proc in psutil.process_iter():
            # Ignore kernel threads if needed
            if self.no_kernel_threads and is_kernel_thread(proc):
                continue

            # If self.max_processes is None: Only retrieve mandatory stats
            # Else: retrieve mandatory and standard stats
            s = self.__get_process_stats(proc,
                                         mandatory_stats=True,
                                         standard_stats=self.max_processes is None)
            # Check if s is note None (issue #879)
            # waiting for upstream patch from psutil
            if s is None:
                continue
            # Continue to the next process if it has to be filtered
            if self._filter.is_filtered(s):
                excluded_processes.add(proc)
                continue

            # Ok add the process to the list
            processdict[proc] = s
            # Update processcount (global statistics)
            try:
                self.processcount[str(proc.status())] += 1
            except KeyError:
                # Key did not exist, create it
                try:
                    self.processcount[str(proc.status())] = 1
                except psutil.NoSuchProcess:
                    pass
            except psutil.NoSuchProcess:
                pass
            else:
                self.processcount['total'] += 1
            # Update thread number (global statistics)
            try:
                self.processcount['thread'] += proc.num_threads()
            except Exception:
                pass

        if self._enable_tree:
            self.process_tree = ProcessTreeNode.build_tree(processdict,
                                                           self.sort_key,
                                                           self.sort_reverse,
                                                           self.no_kernel_threads,
                                                           excluded_processes)

            for i, node in enumerate(self.process_tree):
                # Only retreive stats for visible processes (max_processes)
                if self.max_processes is not None and i >= self.max_processes:
                    break

                # add standard stats
                new_stats = self.__get_process_stats(node.process,
                                                     mandatory_stats=False,
                                                     standard_stats=True,
                                                     extended_stats=False)
                if new_stats is not None:
                    node.stats.update(new_stats)

                # Add a specific time_since_update stats for bitrate
                node.stats['time_since_update'] = time_since_update

        else:
            # Process optimization
            # Only retreive stats for visible processes (max_processes)
            if self.max_processes is not None:
                # Sort the internal dict and cut the top N (Return a list of tuple)
                # tuple=key (proc), dict (returned by __get_process_stats)
                try:
                    processiter = sorted(iteritems(processdict),
                                         key=lambda x: x[1][self.sort_key],
                                         reverse=self.sort_reverse)
                except (KeyError, TypeError) as e:
                    logger.error("Cannot sort process list by {}: {}".format(self.sort_key, e))
                    logger.error('{}'.format(listitems(processdict)[0]))
                    # Fallback to all process (issue #423)
                    processloop = iteritems(processdict)
                    first = False
                else:
                    processloop = processiter[0:self.max_processes]
                    first = True
            else:
                # Get all processes stats
                processloop = iteritems(processdict)
                first = False

            for i in processloop:
                # Already existing mandatory stats
                procstat = i[1]
                if self.max_processes is not None:
                    # Update with standard stats
                    # and extended stats but only for TOP (first) process
                    s = self.__get_process_stats(i[0],
                                                 mandatory_stats=False,
                                                 standard_stats=True,
                                                 extended_stats=first)
                    if s is None:
                        continue
                    procstat.update(s)
                # Add a specific time_since_update stats for bitrate
                procstat['time_since_update'] = time_since_update
                # Update process list
                self.processlist.append(procstat)
                # Next...
                first = False

        # Build the all processes list used by the AMPs
        self.allprocesslist = [p for p in itervalues(processdict)]

        # Clean internals caches if timeout is reached
        if self.cache_timer.finished():
            self.username_cache = {}
            self.cmdline_cache = {}
            # Restart the timer
            self.cache_timer.reset()
コード例 #6
0
ファイル: glances_processlist.py プロジェクト: mondo0/testgl
    def get_process_curses_data(self, p, first, args):
        """Get curses data to display for a process."""
        ret = [self.curse_new_line()]
        # CPU
        if 'cpu_percent' in p and p[
                'cpu_percent'] is not None and p['cpu_percent'] != '':
            if args.disable_irix and self.nb_log_core != 0:
                msg = '{:>6.1f}'.format(p['cpu_percent'] /
                                        float(self.nb_log_core))
            else:
                msg = '{:>6.1f}'.format(p['cpu_percent'])
            ret.append(
                self.curse_add_line(
                    msg, self.get_alert(p['cpu_percent'], header="cpu")))
        else:
            msg = '{:>6}'.format('?')
            ret.append(self.curse_add_line(msg))
        # MEM
        if 'memory_percent' in p and p[
                'memory_percent'] is not None and p['memory_percent'] != '':
            msg = '{:>6.1f}'.format(p['memory_percent'])
            ret.append(
                self.curse_add_line(
                    msg, self.get_alert(p['memory_percent'], header="mem")))
        else:
            msg = '{:>6}'.format('?')
            ret.append(self.curse_add_line(msg))
        # VMS/RSS
        if 'memory_info' in p and p[
                'memory_info'] is not None and p['memory_info'] != '':
            # VMS
            msg = '{:>6}'.format(
                self.auto_unit(p['memory_info'][1], low_precision=False))
            ret.append(self.curse_add_line(msg, optional=True))
            # RSS
            msg = '{:>6}'.format(
                self.auto_unit(p['memory_info'][0], low_precision=False))
            ret.append(self.curse_add_line(msg, optional=True))
        else:
            msg = '{:>6}'.format('?')
            ret.append(self.curse_add_line(msg))
            ret.append(self.curse_add_line(msg))
        # PID
        msg = '{:>6}'.format(p['pid'])
        ret.append(self.curse_add_line(msg))
        # USER
        if 'username' in p:
            # docker internal users are displayed as ints only, therefore str()
            # Correct issue #886 on Windows OS
            msg = ' {:9}'.format(str(p['username'])[:9])
            ret.append(self.curse_add_line(msg))
        else:
            msg = ' {:9}'.format('?')
            ret.append(self.curse_add_line(msg))
        # NICE
        if 'nice' in p:
            nice = p['nice']
            if nice is None:
                nice = '?'
            msg = '{:>5}'.format(nice)
            if isinstance(nice, int) and (nice != 0):
                ret.append(self.curse_add_line(msg, decoration='NICE'))
            else:
                ret.append(self.curse_add_line(msg))
        else:
            msg = '{:>5}'.format('?')
            ret.append(self.curse_add_line(msg))
        # STATUS
        if 'status' in p:
            status = p['status']
            msg = '{:>2}'.format(status)
            if status == 'R':
                ret.append(self.curse_add_line(msg, decoration='STATUS'))
            else:
                ret.append(self.curse_add_line(msg))
        else:
            msg = '{:>2}'.format('?')
            ret.append(self.curse_add_line(msg))
        # TIME+
        if self.tag_proc_time:
            try:
                delta = timedelta(seconds=sum(p['cpu_times']))
            except (OverflowError, TypeError) as e:
                # Catch OverflowError on some Amazon EC2 server
                # See https://github.com/nicolargo/glances/issues/87
                # Also catch TypeError on Mac OS X
                # See: https://github.com/nicolargo/glances/issues/622
                logger.debug("Cannot get TIME+ ({})".format(e))
                self.tag_proc_time = False
            else:
                hours, minutes, seconds, microseconds = convert_timedelta(
                    delta)
                if hours:
                    msg = '{:>4}h'.format(hours)
                    ret.append(
                        self.curse_add_line(msg,
                                            decoration='CPU_TIME',
                                            optional=True))
                    msg = '{}:{}'.format(str(minutes).zfill(2), seconds)
                else:
                    msg = '{:>4}:{}.{}'.format(minutes, seconds, microseconds)
        else:
            msg = '{:>10}'.format('?')
        ret.append(self.curse_add_line(msg, optional=True))
        # IO read/write
        if 'io_counters' in p:
            # IO read
            io_rs = int((p['io_counters'][0] - p['io_counters'][2]) /
                        p['time_since_update'])
            if io_rs == 0:
                msg = '{:>6}'.format("0")
            else:
                msg = '{:>6}'.format(self.auto_unit(io_rs, low_precision=True))
            ret.append(self.curse_add_line(msg, optional=True,
                                           additional=True))
            # IO write
            io_ws = int((p['io_counters'][1] - p['io_counters'][3]) /
                        p['time_since_update'])
            if io_ws == 0:
                msg = '{:>6}'.format("0")
            else:
                msg = '{:>6}'.format(self.auto_unit(io_ws, low_precision=True))
            ret.append(self.curse_add_line(msg, optional=True,
                                           additional=True))
        else:
            msg = '{:>6}'.format("?")
            ret.append(self.curse_add_line(msg, optional=True,
                                           additional=True))
            ret.append(self.curse_add_line(msg, optional=True,
                                           additional=True))

        # Command line
        # If no command line for the process is available, fallback to
        # the bare process name instead
        cmdline = p['cmdline']
        try:
            # XXX: remove `cmdline != ['']` when we'll drop support for psutil<4.0.0
            if cmdline and cmdline != ['']:
                path, cmd, arguments = split_cmdline(cmdline)
                if os.path.isdir(path) and not args.process_short_name:
                    msg = ' {}'.format(path) + os.sep
                    ret.append(self.curse_add_line(msg, splittable=True))
                    if gl_processes.is_tree_enabled():
                        # mark position to add tree decoration
                        ret[-1]["_tree_decoration"] = True
                    ret.append(
                        self.curse_add_line(cmd,
                                            decoration='PROCESS',
                                            splittable=True))
                else:
                    msg = ' {}'.format(cmd)
                    ret.append(
                        self.curse_add_line(msg,
                                            decoration='PROCESS',
                                            splittable=True))
                    if gl_processes.is_tree_enabled():
                        # mark position to add tree decoration
                        ret[-1]["_tree_decoration"] = True
                if arguments:
                    msg = ' {}'.format(arguments)
                    ret.append(self.curse_add_line(msg, splittable=True))
            else:
                msg = ' {}'.format(p['name'])
                ret.append(self.curse_add_line(msg, splittable=True))
        except UnicodeEncodeError:
            ret.append(self.curse_add_line('', splittable=True))

        # Add extended stats but only for the top processes
        # !!! CPU consumption ???
        # TODO: extended stats into the web interface
        if first and 'extended_stats' in p:
            # Left padding
            xpad = ' ' * 13
            # First line is CPU affinity
            if 'cpu_affinity' in p and p['cpu_affinity'] is not None:
                ret.append(self.curse_new_line())
                msg = xpad + 'CPU affinity: ' + str(len(
                    p['cpu_affinity'])) + ' cores'
                ret.append(self.curse_add_line(msg, splittable=True))
            # Second line is memory info
            if 'memory_info' in p and p['memory_info'] is not None:
                ret.append(self.curse_new_line())
                msg = xpad + 'Memory info: '
                for k, v in iteritems(p['memory_info']._asdict()):
                    # Ignore rss and vms (already displayed)
                    if k not in ['rss', 'vms'] and v is not None:
                        msg += k + ' ' + self.auto_unit(
                            v, low_precision=False) + ' '
                if 'memory_swap' in p and p['memory_swap'] is not None:
                    msg += 'swap ' + self.auto_unit(p['memory_swap'],
                                                    low_precision=False)
                ret.append(self.curse_add_line(msg, splittable=True))
            # Third line is for open files/network sessions
            msg = ''
            if 'num_threads' in p and p['num_threads'] is not None:
                msg += 'threads ' + str(p['num_threads']) + ' '
            if 'num_fds' in p and p['num_fds'] is not None:
                msg += 'files ' + str(p['num_fds']) + ' '
            if 'num_handles' in p and p['num_handles'] is not None:
                msg += 'handles ' + str(p['num_handles']) + ' '
            if 'tcp' in p and p['tcp'] is not None:
                msg += 'TCP ' + str(p['tcp']) + ' '
            if 'udp' in p and p['udp'] is not None:
                msg += 'UDP ' + str(p['udp']) + ' '
            if msg != '':
                ret.append(self.curse_new_line())
                msg = xpad + 'Open: ' + msg
                ret.append(self.curse_add_line(msg, splittable=True))
            # Fouth line is IO nice level (only Linux and Windows OS)
            if 'ionice' in p and p['ionice'] is not None:
                ret.append(self.curse_new_line())
                msg = xpad + 'IO nice: '
                k = 'Class is '
                v = p['ionice'].ioclass
                # Linux: The scheduling class. 0 for none, 1 for real time, 2 for best-effort, 3 for idle.
                if v == 0:
                    msg += 'No specific I/O priority'
                elif v == 1:
                    msg += k + 'Real Time'
                elif v == 2:
                    msg += k + 'Best Effort'
                elif v == 3:
                    msg += k + 'IDLE'
                else:
                    msg += k + str(v)
                #  value is a number which goes from 0 to 7.
                # The higher the value, the lower the I/O priority of the process.
                if hasattr(p['ionice'], 'value') and p['ionice'].value != 0:
                    msg += ' (value %s/7)' % str(p['ionice'].value)
                ret.append(self.curse_add_line(msg, splittable=True))

        return ret