From d0783a21e1f86598aade1d18a79ab5fd7c6db654 Mon Sep 17 00:00:00 2001 From: nicolargo Date: Sun, 22 May 2016 18:01:02 +0200 Subject: [PATCH] Create a new GlancesFilter class --- glances/filter.py | 78 ++++++++++++++++++++++++++++++++++++++++++++ glances/processes.py | 36 ++++---------------- 2 files changed, 85 insertions(+), 29 deletions(-) create mode 100644 glances/filter.py diff --git a/glances/filter.py b/glances/filter.py new file mode 100644 index 00000000..d73379f9 --- /dev/null +++ b/glances/filter.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +# +# This file is part of Glances. +# +# Copyright (C) 2016 Nicolargo +# +# Glances is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Glances is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# 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 . + +import re + +from glances.logger import logger + + +class GlancesFilter(object): + + """Allow Glances to filter processes + + >>> f = GlancesFilter() + >>> f.filter = '.*python.*' + >>> f.filter + '.*python.*' + """ + + def __init__(self): + # Filter entered by the user (string) + self._filter = None + # Filter regular expression + self._filter_re = None + + @property + def filter(self): + """Return the filter (as a sting)""" + return self._filter + + @filter.setter + def filter(self, value): + """Set the filter (as a sting) and compute the regular expression""" + self._filter = value + self._filter_re = None + + if self.filter is not None: + logger.info("Set filter to {0}".format(self.filter)) + # Compute the regular expression + try: + self._filter_re = re.compile(self.filter) + logger.debug("Filter regex compilation OK: {0}".format(self.filter)) + except Exception as e: + logger.error("Cannot compile filter regex: {0} ({1})".format(self.filter, e)) + + @property + def filter_re(self): + """Return the filter regular expression""" + return self._filter_re + + def is_filtered(self, process, key='cmdline'): + """Return True if the process item match the current filter + The proces item is a dict. + The filter will be applyed on the process[key] (command line by default) + """ + if self.filter is None: + # No filter => Not filtered + return False + try: + return self._filter_re.match(' '.join(process[key])) is None + except AttributeError: + # Filter processes crashs with a bad regular expression pattern (issue #665) + return False diff --git a/glances/processes.py b/glances/processes.py index 8eab1cdf..7cf32f83 100644 --- a/glances/processes.py +++ b/glances/processes.py @@ -23,9 +23,10 @@ import re from glances.compat import iteritems, itervalues, listitems from glances.globals import BSD, LINUX, OSX, WINDOWS -from glances.logger import logger from glances.timer import Timer, getTimeSinceLastUpdate from glances.processes_tree import ProcessTreeNode +from glances.filter import GlancesFilter +from glances.logger import logger import psutil @@ -82,8 +83,7 @@ class GlancesProcesses(object): self._max_processes = None # Process filter is a regular expression - self._process_filter = None - self._process_filter_re = None + self._filter = GlancesFilter() # Whether or not to hide kernel threads self.no_kernel_threads = False @@ -119,39 +119,17 @@ class GlancesProcesses(object): @property def process_filter(self): """Get the process filter.""" - return self._process_filter + return self._filter.filter @process_filter.setter def 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.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 + self._filter.filter = value @property def process_filter_re(self): """Get the process regular expression compiled.""" - return self._process_filter_re - - def is_filtered(self, value): - """Return True if the value should be filtered.""" - if self.process_filter is None: - # No filter => Not filtered - return False - else: - try: - return self.process_filter_re.match(' '.join(value)) is None - except AttributeError: - # Filter processes crashs with a bad regular expression pattern (issue #665) - return False + return self._filter.filter_re def disable_kernel_threads(self): """Ignore kernel threads in process list.""" @@ -420,7 +398,7 @@ class GlancesProcesses(object): OSX and s['name'] == 'kernel_task'): continue # Continue to the next process if it has to be filtered - if s is None or (self.is_filtered(s['cmdline']) and self.is_filtered(s['name'])): + if s is None or (self._filter.is_filtered(s, 'cmdline') and self._filter.is_filtered(s, 'name')): excluded_processes.add(proc) continue