diff options
author | nicolargo <nicolas@nicolargo.com> | 2024-04-06 17:46:42 +0200 |
---|---|---|
committer | nicolargo <nicolas@nicolargo.com> | 2024-04-06 17:46:42 +0200 |
commit | f87e7d7fe69599de434cfacb0ab65cc9810f7f99 (patch) | |
tree | ab16866df32d23d991d3e983e62183e8deb11107 | |
parent | 71a77bc8ca86bb8a55c6116eb3073a570f56fdb8 (diff) |
Export individual processes stats #794
-rw-r--r-- | conf/glances.conf | 6 | ||||
-rw-r--r-- | docs/aoa/ps.rst | 8 | ||||
-rw-r--r-- | docs/api.rst | 223 | ||||
-rw-r--r-- | docs/man/glances.1 | 2 | ||||
-rw-r--r-- | glances/filter.py | 63 | ||||
-rw-r--r-- | glances/plugins/processlist/__init__.py | 2 | ||||
-rw-r--r-- | glances/processes.py | 31 | ||||
-rwxr-xr-x | unitest.py | 25 |
8 files changed, 214 insertions, 146 deletions
diff --git a/conf/glances.conf b/conf/glances.conf index a1435372..5f993981 100644 --- a/conf/glances.conf +++ b/conf/glances.conf @@ -359,10 +359,8 @@ nice_warning=-20,-19,-18,-17,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2 #nice_critical=15,16,17,18,19 # # Define the list of processes to export using: -# a comma-separated list of regular expression (apply on name and cmdline) -#export=.*firefox.* -# or an uniq key:value filter -#export=pid:1234 +# a comma-separated list of Glances filter +#export=.*firefox.*,pid:1234 [ports] disable=False diff --git a/docs/aoa/ps.rst b/docs/aoa/ps.rst index fe788cf3..e0a57eec 100644 --- a/docs/aoa/ps.rst +++ b/docs/aoa/ps.rst @@ -208,11 +208,9 @@ Glances version 4 introduces a new feature to export specifics processes. In ord feature, you need to use the export option in the processlist section of the Glances configuration file or the --export-process-filter option in the command line. -The export option is one of the following: -- a comma separated list of process names or regular expressions -- a single Glances filter (see above) +The export option is a list of Glances filters. -Example number one, export all processes with the name 'python': +Example number one, export all processes named 'python' (or with a command line containing 'python'): .. code-block:: ini @@ -230,7 +228,7 @@ Example number two, export all processes with the name 'python' or 'bash': Note: or the --export-process-filter ".*python.*,.*bash.*" option in the command line. -Example number three, export all processes belong to the user 'nicolargo': +Example number three, export all processes belong to 'nicolargo' user: .. code-block:: ini diff --git a/docs/api.rst b/docs/api.rst index 0965f802..50ac6908 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -141,7 +141,7 @@ Get plugin stats:: "refresh": 3.0, "regex": True, "result": None, - "timer": 0.4065737724304199}, + "timer": 0.3346278667449951}, {"count": 0, "countmax": 20.0, "countmin": None, @@ -150,7 +150,7 @@ Get plugin stats:: "refresh": 3.0, "regex": True, "result": None, - "timer": 0.4064033031463623}] + "timer": 0.3344759941101074}] Fields descriptions: @@ -178,7 +178,7 @@ Get a specific item when field matches the given value:: "refresh": 3.0, "regex": True, "result": None, - "timer": 0.4065737724304199}]} + "timer": 0.3346278667449951}]} GET cloud --------- @@ -226,18 +226,18 @@ Get plugin stats:: "engine": "docker", "id": "3abd51c615968482d9ccff5afc629f267f6dda113ed68b75b432615fae3b49fb", "image": ["portainer/portainer-ce:2.9.3"], - "io": {"cumulative_ior": 40960, "cumulative_iow": 741376}, + "io": {"cumulative_ior": 110592, "cumulative_iow": 962560}, "key": "name", "memory": {"cache": None, "limit": 7823568896, "max_usage": None, "rss": None, - "usage": 14016512}, - "memory_usage": 14016512, + "usage": 15851520}, + "memory_usage": 15851520, "name": "portainer", - "network": {"cumulative_rx": 1280393, "cumulative_tx": 1496}, + "network": {"cumulative_rx": 1803247, "cumulative_tx": 1636}, "status": "running", - "uptime": "5 days"}] + "uptime": "6 days"}] Fields descriptions: @@ -273,18 +273,18 @@ Get a specific item when field matches the given value:: "engine": "docker", "id": "3abd51c615968482d9ccff5afc629f267f6dda113ed68b75b432615fae3b49fb", "image": ["portainer/portainer-ce:2.9.3"], - "io": {"cumulative_ior": 40960, "cumulative_iow": 741376}, + "io": {"cumulative_ior": 110592, "cumulative_iow": 962560}, "key": "name", "memory": {"cache": None, "limit": 7823568896, "max_usage": None, "rss": None, - "usage": 14016512}, - "memory_usage": 14016512, + "usage": 15851520}, + "memory_usage": 15851520, "name": "portainer", - "network": {"cumulative_rx": 1280393, "cumulative_tx": 1496}, + "network": {"cumulative_rx": 1803247, "cumulative_tx": 1636}, "status": "running", - "uptime": "5 days"}]} + "uptime": "6 days"}]} GET core -------- @@ -311,19 +311,19 @@ Get plugin stats:: # curl http://localhost:61208/api/4/cpu {"cpucore": 4, - "ctx_switches": 1046087238, + "ctx_switches": 1083773007, "guest": 0.0, - "idle": 71.1, - "interrupts": 480749229, + "idle": 71.2, + "interrupts": 497643356, "iowait": 0.0, "irq": 0.0, "nice": 0.0, - "soft_interrupts": 213157924, + "soft_interrupts": 222951171, "steal": 0.0, "syscalls": 0, - "system": 4.8, - "total": 28.9, - "user": 24.1} + "system": 3.1, + "total": 28.8, + "user": 25.8} Fields descriptions: @@ -356,7 +356,7 @@ Fields descriptions: Get a specific field:: # curl http://localhost:61208/api/4/cpu/total - {"total": 28.9} + {"total": 28.8} GET diskio ---------- @@ -366,10 +366,10 @@ Get plugin stats:: # curl http://localhost:61208/api/4/diskio [{"disk_name": "sda", "key": "disk_name", - "read_bytes": 103830181888, - "read_count": 5595135, - "write_bytes": 205683687424, - "write_count": 2538561}, + "read_bytes": 106861217280, + "read_count": 5848339, + "write_bytes": 209200316416, + "write_count": 2631934}, {"disk_name": "sda1", "key": "disk_name", "read_bytes": 24269824, @@ -404,10 +404,10 @@ Get a specific item when field matches the given value:: # curl http://localhost:61208/api/4/diskio/disk_name/sda {"sda": [{"disk_name": "sda", "key": "disk_name", - "read_bytes": 103830181888, - "read_count": 5595135, - "write_bytes": 205683687424, - "write_count": 2538561}]} + "read_bytes": 106861217280, + "read_count": 5848339, + "write_bytes": 209200316416, + "write_count": 2631934}]} GET folders ----------- @@ -434,13 +434,13 @@ Get plugin stats:: # curl http://localhost:61208/api/4/fs [{"device_name": "/dev/mapper/ubuntu--gnome--vg-root", - "free": 36362539008, + "free": 35840458752, "fs_type": "ext4", "key": "mnt_point", "mnt_point": "/", - "percent": 84.3, + "percent": 84.5, "size": 243334156288, - "used": 194584162304}, + "used": 195106242560}, {"device_name": "zsfpool", "free": 31195136, "fs_type": "zfs", @@ -469,13 +469,13 @@ Get a specific item when field matches the given value:: # curl http://localhost:61208/api/4/fs/mnt_point// {"/": [{"device_name": "/dev/mapper/ubuntu--gnome--vg-root", - "free": 36362539008, + "free": 35840458752, "fs_type": "ext4", "key": "mnt_point", "mnt_point": "/", - "percent": 84.3, + "percent": 84.5, "size": 243334156288, - "used": 194584162304}]} + "used": 195106242560}]} GET gpu ------- @@ -548,10 +548,7 @@ GET load Get plugin stats:: # curl http://localhost:61208/api/4/load - {"cpucore": 4, - "min1": 1.11474609375, - "min15": 1.30419921875, - "min5": 1.060546875} + {"cpucore": 4, "min1": 0.1416015625, "min15": 0.970703125, "min5": 0.765625} Fields descriptions: @@ -563,7 +560,7 @@ Fields descriptions: Get a specific field:: # curl http://localhost:61208/api/4/load/min1 - {"min1": 1.11474609375} + {"min1": 0.1416015625} GET mem ------- @@ -571,16 +568,16 @@ GET mem Get plugin stats:: # curl http://localhost:61208/api/4/mem - {"active": 2653958144, - "available": 2423255040, - "buffers": 676577280, - "cached": 2417643520, - "free": 2423255040, - "inactive": 3602350080, - "percent": 69.0, - "shared": 699977728, + {"active": 2535997440, + "available": 2432135168, + "buffers": 501940224, + "cached": 2622812160, + "free": 2432135168, + "inactive": 3695976448, + "percent": 68.9, + "shared": 652316672, "total": 7823568896, - "used": 5400313856} + "used": 5391433728} Fields descriptions: @@ -607,13 +604,13 @@ GET memswap Get plugin stats:: # curl http://localhost:61208/api/4/memswap - {"free": 6406701056, - "percent": 20.7, - "sin": 8078508032, - "sout": 16575467520, + {"free": 6828023808, + "percent": 15.5, + "sin": 8335540224, + "sout": 16940646400, "time_since_update": 1, "total": 8082419712, - "used": 1675718656} + "used": 1254395904} Fields descriptions: @@ -638,15 +635,15 @@ Get plugin stats:: # curl http://localhost:61208/api/4/network [{"alias": None, "bytes_all": 0, - "bytes_all_gauge": 9306142258, + "bytes_all_gauge": 9770615278, "bytes_recv": 0, - "bytes_recv_gauge": 8752265243, + "bytes_recv_gauge": 9183565245, "bytes_sent": 0, - "bytes_sent_gauge": 553877015, + "bytes_sent_gauge": 587050033, "interface_name": "wlp2s0", "key": "interface_name", "speed": 0, - "time_since_update": 0.30997323989868164}, + "time_since_update": 0.22126293182373047}, {"alias": None, "bytes_all": 0, "bytes_all_gauge": 0, @@ -657,7 +654,7 @@ Get plugin stats:: "interface_name": "br-40875d2e2716", "key": "interface_name", "speed": 0, - "time_since_update": 0.30997323989868164}] + "time_since_update": 0.22126293182373047}] Fields descriptions: @@ -693,15 +690,15 @@ Get a specific item when field matches the given value:: # curl http://localhost:61208/api/4/network/interface_name/wlp2s0 {"wlp2s0": [{"alias": None, "bytes_all": 0, - "bytes_all_gauge": 9306142258, + "bytes_all_gauge": 9770615278, "bytes_recv": 0, - "bytes_recv_gauge": 8752265243, + "bytes_recv_gauge": 9183565245, "bytes_sent": 0, - "bytes_sent_gauge": 553877015, + "bytes_sent_gauge": 587050033, "interface_name": "wlp2s0", "key": "interface_name", "speed": 0, - "time_since_update": 0.30997323989868164}]} + "time_since_update": 0.22126293182373047}]} GET now ------- @@ -709,7 +706,7 @@ GET now Get plugin stats:: # curl http://localhost:61208/api/4/now - "2024-04-05 19:39:57 CEST" + "2024-04-06 17:45:25 CEST" GET percpu ---------- @@ -720,29 +717,29 @@ Get plugin stats:: [{"cpu_number": 0, "guest": 0.0, "guest_nice": 0.0, - "idle": 42.0, + "idle": 10.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", "nice": 0.0, "softirq": 0.0, "steal": 0.0, - "system": 6.0, - "total": 58.0, - "user": 27.0}, + "system": 4.0, + "total": 90.0, + "user": 52.0}, {"cpu_number": 1, "guest": 0.0, "guest_nice": 0.0, - "idle": 67.0, + "idle": 53.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", "nice": 0.0, "softirq": 0.0, "steal": 0.0, - "system": 3.0, - "total": 33.0, - "user": 6.0}] + "system": 2.0, + "total": 47.0, + "user": 11.0}] Fields descriptions: @@ -776,7 +773,7 @@ Get plugin stats:: "port": 0, "refresh": 30, "rtt_warning": None, - "status": 0.005854, + "status": 0.007423, "timeout": 3}] Fields descriptions: @@ -804,7 +801,7 @@ Get a specific item when field matches the given value:: "port": 0, "refresh": 30, "rtt_warning": None, - "status": 0.005854, + "status": 0.007423, "timeout": 3}]} GET processcount @@ -813,7 +810,7 @@ GET processcount Get plugin stats:: # curl http://localhost:61208/api/4/processcount - {"pid_max": 0, "running": 2, "sleeping": 336, "thread": 1575, "total": 404} + {"pid_max": 0, "running": 1, "sleeping": 333, "thread": 1520, "total": 403} Fields descriptions: @@ -826,7 +823,7 @@ Fields descriptions: Get a specific field:: # curl http://localhost:61208/api/4/processcount/total - {"total": 404} + {"total": 403} GET processlist --------------- @@ -866,43 +863,43 @@ GET quicklook Get plugin stats:: # curl http://localhost:61208/api/4/quicklook - {"cpu": 28.9, + {"cpu": 28.8, "cpu_hz": 2025000000.0, - "cpu_hz_current": 1723951750.0, + "cpu_hz_current": 1723628500.0, "cpu_name": "Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz", "cpucore": 4, - "load": 32.6, - "mem": 69.0, + "load": 24.3, + "mem": 68.9, "percpu": [{"cpu_number": 0, "guest": 0.0, "guest_nice": 0.0, - "idle": 42.0, + "idle": 10.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", "nice": 0.0, "softirq": 0.0, "steal": 0.0, - "system": 6.0, - "total": 58.0, - "user": 27.0}, + "system": 4.0, + "total": 90.0, + "user": 52.0}, {"cpu_number": 1, "guest": 0.0, "guest_nice": 0.0, - "idle": 67.0, + "idle": 53.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", "nice": 0.0, "softirq": 0.0, "steal": 0.0, - "system": 3.0, - "total": 33.0, - "user": 6.0}, + "system": 2.0, + "total": 47.0, + "user": 11.0}, {"cpu_number": 2, "guest": 0.0, "guest_nice": 0.0, - "idle": 66.0, + "idle": 62.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", @@ -910,22 +907,22 @@ Get plugin stats:: "softirq": 0.0, "steal": 0.0, "system": 1.0, - "total": 34.0, - "user": 8.0}, + "total": 38.0, + "user": 2.0}, {"cpu_number": 3, "guest": 0.0, "guest_nice": 0.0, - "idle": 40.0, + "idle": 62.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", "nice": 0.0, "softirq": 0.0, "steal": 0.0, - "system": 4.0, - "total": 60.0, - "user": 30.0}], - "swap": 20.7} + "system": 1.0, + "total": 38.0, + "user": 2.0}], + "swap": 15.5} Fields descriptions: @@ -1045,7 +1042,7 @@ GET uptime Get plugin stats:: # curl http://localhost:61208/api/4/uptime - "32 days, 10:39:09" + "33 days, 8:44:36" GET version ----------- @@ -1105,34 +1102,34 @@ GET stats history History of a plugin:: # curl http://localhost:61208/api/4/cpu/history - {"system": [["2024-04-05T19:39:59.495699", 4.8], - ["2024-04-05T19:40:00.515910", 1.8], - ["2024-04-05T19:40:01.696855", 1.8]], - "user": [["2024-04-05T19:39:59.495685", 24.1], - ["2024-04-05T19:40:00.515902", 7.0], - ["2024-04-05T19:40:01.696838", 7.0]]} + {"system": [["2024-04-06T17:45:26.720681", 3.1], + ["2024-04-06T17:45:27.742109", 2.2], + ["2024-04-06T17:45:28.929983", 2.2]], + "user": [["2024-04-06T17:45:26.720667", 25.8], + ["2024-04-06T17:45:27.742099", 7.5], + ["2024-04-06T17:45:28.929968", 7.5]]} Limit history to last 2 values:: # curl http://localhost:61208/api/4/cpu/history/2 - {"system": [["2024-04-05T19:40:00.515910", 1.8], - ["2024-04-05T19:40:01.696855", 1.8]], - "user": [["2024-04-05T19:40:00.515902", 7.0], - ["2024-04-05T19:40:01.696838", 7.0]]} + {"system": [["2024-04-06T17:45:27.742109", 2.2], + ["2024-04-06T17:45:28.929983", 2.2]], + "user": [["2024-04-06T17:45:27.742099", 7.5], + ["2024-04-06T17:45:28.929968", 7.5]]} History for a specific field:: # curl http://localhost:61208/api/4/cpu/system/history - {"system": [["2024-04-05T19:39:57.916788", 4.8], - ["2024-04-05T19:39:59.495699", 4.8], - ["2024-04-05T19:40:00.515910", 1.8], - ["2024-04-05T19:40:01.696855", 1.8]]} + {"system": [["2024-04-06T17:45:25.061145", 3.1], + ["2024-04-06T17:45:26.720681", 3.1], + ["2024-04-06T17:45:27.742109", 2.2], + ["2024-04-06T17:45:28.929983", 2.2]]} Limit history for a specific field to last 2 values:: # curl http://localhost:61208/api/4/cpu/system/history - {"system": [["2024-04-05T19:40:00.515910", 1.8], - ["2024-04-05T19:40:01.696855", 1.8]]} + {"system": [["2024-04-06T17:45:27.742109", 2.2], + ["2024-04-06T17:45:28.929983", 2.2]]} GET limits (used for thresholds) -------------------------------- diff --git a/docs/man/glances.1 b/docs/man/glances.1 index 684a5672..d6d56ccb 100644 --- a/docs/man/glances.1 +++ b/docs/man/glances.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "GLANCES" "1" "Apr 05, 2024" "4.0.0_beta01" "Glances" +.TH "GLANCES" "1" "Apr 06, 2024" "4.0.0_beta01" "Glances" .SH NAME glances \- An eye on your system .SH SYNOPSIS diff --git a/glances/filter.py b/glances/filter.py index 727bf695..d54e889d 100644 --- a/glances/filter.py +++ b/glances/filter.py @@ -12,6 +12,49 @@ import re from glances.logger import logger +class GlancesFilterList(object): + """Manage a lis of GlancesFilter objects + + >>> fl = GlancesFilterList() + >>> fl.filter = '.*python.*,user:nicolargo' + >>> fl.is_filtered({'name': 'python is in the place'}) + True + >>> fl.is_filtered({'name': 'snake is in the place'}) + False + >>> fl.is_filtered({'name': 'snake is in the place', 'username': 'nicolargo'}) + True + >>> fl.is_filtered({'name': 'snake is in the place', 'username': 'notme'}) + False + """ + + def __init__(self): + self._filter = [] + + @property + def filter(self): + """Return the current filter to be applied""" + return self._filter + + @filter.setter + def filter(self, value): + """Add a comma separated list of filters""" + for f in value.split(','): + self._add_filter(f) + + def _add_filter(self, filter_input): + """Add a filter""" + f = GlancesFilter() + f.filter = filter_input + self._filter.append(f) + + def is_filtered(self, process): + """Return True if the process is filtered by at least one filter""" + for f in self._filter: + if f.is_filtered(process): + return True + return False + + class GlancesFilter(object): """Allow Glances to filter processes @@ -20,13 +63,13 @@ class GlancesFilter(object): >>> f.filter = '.*python.*' >>> f.filter '.*python.*' - >>> f.key + >>> f.filter_key None - >>> f.filter = 'user:nicolargo' + >>> f.filter = 'username:nicolargo' >>> f.filter 'nicolargo' - >>> f.key - 'user' + >>> f.filter_key + 'username' >>> f.filter = 'username:.*nico.*' >>> f.filter '.*nico.*' @@ -60,9 +103,9 @@ class GlancesFilter(object): """Set the filter (as a string) 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 + - python > Process name start with python + - .*python.* > Process name contain python + - user:nicolargo > Process belong to nicolargo user """ self._filter_input = value if value is None: @@ -125,7 +168,9 @@ class GlancesFilter(object): try: # If the item process[key] is a list, convert it to a string # in order to match it with the current regular expression - if isinstance(process[key], list): + if isinstance(process[key], list) and key == 'cmdline' and len(process[key]) > 0: + value = process[key][0] + elif isinstance(process[key], list): value = ' '.join(process[key]) else: value = process[key] @@ -133,7 +178,7 @@ class GlancesFilter(object): # If the key did not exist return False try: - return self._filter_re.fullmatch(value) is None + return self._filter_re.fullmatch(value) is not None except (AttributeError, TypeError): # AttributeError - Filter processes crashes with a bad regular expression pattern (issue #665) # TypeError - Filter processes crashes if value is None (issue #1105) diff --git a/glances/plugins/processlist/__init__.py b/glances/plugins/processlist/__init__.py index f3d2c284..e5cdec0f 100644 --- a/glances/plugins/processlist/__init__.py +++ b/glances/plugins/processlist/__init__.py @@ -191,7 +191,7 @@ class PluginModel(GlancesPluginModel): glances_processes.export_process_filter = config.as_dict()['processlist']['export'] if args.export: logger.info("Export process filter is set to: {}".format( - glances_processes.export_process_filter)) + config.as_dict()['processlist']['export'])) # The default sort key could also be overwrite by command line (see #1903) if args.sort_processes_key is not None: diff --git a/glances/processes.py b/glances/processes.py index 1c9d1de5..7ba12eb7 100644 --- a/glances/processes.py +++ b/glances/processes.py @@ -12,7 +12,7 @@ import os from glances.globals import BSD, LINUX, MACOS, WINDOWS, iterkeys from glances.globals import namedtuple_to_dict, list_of_namedtuple_to_list_of_dict from glances.timer import Timer, getTimeSinceLastUpdate -from glances.filter import GlancesFilter +from glances.filter import GlancesFilterList, GlancesFilter from glances.programs import processes_to_programs from glances.logger import logger @@ -69,8 +69,9 @@ class GlancesProcesses(object): # Cache is a dict with key=pid and value = dict of cached value self.processlist_cache = {} - # List of processes stats to export (filtred by the _filter_export) - self._filter_export = GlancesFilter() + # List of processes stats to export + # Only process matching one of the filter will be exported + self._filter_export = GlancesFilterList() self.processlist_export = [] # Tag to enable/disable the processes stats (to reduce the Glances CPU consumption) @@ -106,7 +107,7 @@ class GlancesProcesses(object): # Maximum number of processes showed in the UI (None if no limit) self._max_processes = None - # Process filter is a regular expression + # Process filter self._filter = GlancesFilter() # Whether or not to hide kernel threads @@ -237,13 +238,13 @@ class GlancesProcesses(object): @property def export_process_filter(self): - """Get the export process filter (current export filter).""" + """Get the export process filter (current export process filter list).""" return self._filter_export.filter @export_process_filter.setter def export_process_filter(self, value): - """Set the export process filter.""" - self._filter_export.filter = '|'.join(value.split(',')) + """Set the export process filter list.""" + self._filter_export.filter = value # Kernel threads @@ -502,12 +503,12 @@ class GlancesProcesses(object): except KeyError: pass - # Filter and transform process list - processlist = self.update_list(processlist) - # Filter and transform process export list self.processlist_export = self.update_export_list(processlist) + # Filter and transform process list + processlist = self.update_list(processlist) + # Compute the maximum value for keys in self._max_values_list: CPU, MEM # Useful to highlight the processes with maximum values for k in self._max_values_list: @@ -522,14 +523,18 @@ class GlancesProcesses(object): def update_list(self, processlist): """Return the process list after filtering and transformation (namedtuple to dict).""" - ret = list(filter(lambda p: not self._filter.is_filtered(p), processlist)) + if self._filter.filter is None: + return list_of_namedtuple_to_list_of_dict(processlist) + ret = list(filter(lambda p: self._filter.is_filtered(p), + processlist)) return list_of_namedtuple_to_list_of_dict(ret) def update_export_list(self, processlist): """Return the process export list after filtering and transformation (namedtuple to dict).""" - if self._filter_export.filter is None: + if self._filter_export.filter == []: return [] - ret = list(filter(lambda p: not self._filter_export.is_filtered(p), processlist)) + ret = list(filter(lambda p: self._filter_export.is_filtered(p), + processlist)) return list_of_namedtuple_to_list_of_dict(ret) def get_count(self): @@ -33,6 +33,7 @@ from glances.plugins.plugin.model import GlancesPluginModel from glances.programs import processes_to_programs from glances.secure import secure_popen from glances.events_list import GlancesEventsList +from glances.filter import GlancesFilterList, GlancesFilter # Global variables # ================= @@ -345,6 +346,30 @@ class TestGlances(unittest.TestCase): events.clean() self.assertEqual(len(events.get()), 1) + def test_020_filter(self): + """Test filter classes""" + print('INFO: [TEST_020] Test filter') + gf = GlancesFilter() + gf.filter = '.*python.*' + self.assertEqual(gf.filter, '.*python.*') + self.assertEqual(gf.filter_key, None) + self.assertTrue(gf.is_filtered({'name': 'python'})) + self.assertTrue(gf.is_filtered({'name': '/usr/bin/python -m glances'})) + self.assertFalse(gf.is_filtered({'noname': 'python'})) + self.assertFalse(gf.is_filtered({'name': 'snake'})) + gf.filter = 'username:nicolargo' + self.assertEqual(gf.filter, 'nicolargo') + self.assertEqual(gf.filter_key, 'username') + self.assertTrue(gf.is_filtered({'username': 'nicolargo'})) + self.assertFalse(gf.is_filtered({'username': 'notme'})) + self.assertFalse(gf.is_filtered({'notuser': 'nicolargo'})) + gfl = GlancesFilterList() + gfl.filter = '.*python.*,username:nicolargo' + self.assertTrue(gfl.is_filtered({'name': 'python is in the place'})) + self.assertFalse(gfl.is_filtered({'name': 'snake is in the place'})) + self.assertTrue(gfl.is_filtered({'name': 'snake is in the place', 'username': 'nicolargo'})) + self.assertFalse(gfl.is_filtered({'name': 'snake is in the place', 'username': 'notme'})) + def test_094_thresholds(self): """Test thresholds classes""" print('INFO: [TEST_094] Thresholds') |