Export individual processes stats #794

This commit is contained in:
nicolargo 2024-04-06 17:46:42 +02:00
parent 71a77bc8ca
commit f87e7d7fe6
8 changed files with 241 additions and 173 deletions

View File

@ -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

View File

@ -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

View File

@ -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,56 +863,17 @@ 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,
"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},
{"cpu_number": 1,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 67.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},
{"cpu_number": 2,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 66.0,
"iowait": 0.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"steal": 0.0,
"system": 1.0,
"total": 34.0,
"user": 8.0},
{"cpu_number": 3,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 40.0,
"idle": 10.0,
"iowait": 0.0,
"irq": 0.0,
"key": "cpu_number",
@ -923,9 +881,48 @@ Get plugin stats::
"softirq": 0.0,
"steal": 0.0,
"system": 4.0,
"total": 60.0,
"user": 30.0}],
"swap": 20.7}
"total": 90.0,
"user": 52.0},
{"cpu_number": 1,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 53.0,
"iowait": 0.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"steal": 0.0,
"system": 2.0,
"total": 47.0,
"user": 11.0},
{"cpu_number": 2,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 62.0,
"iowait": 0.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"steal": 0.0,
"system": 1.0,
"total": 38.0,
"user": 2.0},
{"cpu_number": 3,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 62.0,
"iowait": 0.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"steal": 0.0,
"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)
--------------------------------

View File

@ -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

View File

@ -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)

View File

@ -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:

View File

@ -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):

View File

@ -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')