Optimize basic HTTP authentication

This commit is contained in:
nicolargo 2023-12-15 19:06:33 +01:00
parent e27fd5f102
commit 3215bf5c63
12 changed files with 366 additions and 315 deletions

View File

@ -12,12 +12,16 @@ The Glances Restfull/API server could be ran using the following command line:
API URL
-------
The default root API URL is ``http://localhost:61208/api/3``.
The default root API URL is ``http://localhost:61208/api/4``.
Warning: if you use Glances 3.x then the API URL is ``http://localhost:61208/api/3``.
The bind address and port could be changed using the ``--bind`` and ``--port`` command line options.
It is also possible to define an URL prefix using the ``url_prefix`` option from the [outputs] section
of the Glances configuration file. The url_prefix should always end with a slash (``/``).
of the Glances configuration file.
Note: The url_prefix should always end with a slash (``/``).
For example:
@ -25,19 +29,25 @@ For example:
[outputs]
url_prefix = /glances/
will change the root API URL to ``http://localhost:61208/glances/api/3`` and the Web UI URL to
will change the root API URL to ``http://localhost:61208/glances/api/4`` and the Web UI URL to
``http://localhost:61208/glances/``
Web UI refresh
--------------
It is possible to change the Web UI refresh rate (default is 2 seconds) using the following option in the URL:
``http://localhost:61208/glances/?refresh=5``
GET API status
--------------
This entry point should be used to check the API status.
It will return nothing but a 200 return code if everything is OK.
It will the Glances version and a 200 return code if everything is OK.
Get the Rest API status::
# curl -I http://localhost:61208/api/3/status
# curl -I http://localhost:61208/api/4/status
"HTTP/1.0 200 OK"
GET plugins list
@ -45,7 +55,7 @@ GET plugins list
Get the plugins list::
# curl http://localhost:61208/api/3/pluginslist
# curl http://localhost:61208/api/4/pluginslist
["alert",
"amps",
"cloud",
@ -83,15 +93,15 @@ GET alert
Get plugin stats::
# curl http://localhost:61208/api/3/alert
[[1702235550.0,
# curl http://localhost:61208/api/4/alert
[[1702657018.0,
-1,
"WARNING",
"MEM",
77.46614626280395,
77.46614626280395,
77.46614626280395,
77.46614626280395,
71.53233807403451,
71.53233807403451,
71.53233807403451,
71.53233807403451,
1,
[],
"",
@ -102,7 +112,7 @@ GET amps
Get plugin stats::
# curl http://localhost:61208/api/3/amps
# curl http://localhost:61208/api/4/amps
[{"count": 0,
"countmax": None,
"countmin": 1.0,
@ -111,7 +121,7 @@ Get plugin stats::
"refresh": 3.0,
"regex": True,
"result": None,
"timer": 0.326155424118042},
"timer": 0.40151143074035645},
{"count": 0,
"countmax": 20.0,
"countmin": None,
@ -120,16 +130,16 @@ Get plugin stats::
"refresh": 3.0,
"regex": True,
"result": None,
"timer": 0.32600831985473633}]
"timer": 0.4013493061065674}]
Get a specific field::
# curl http://localhost:61208/api/3/amps/name
# curl http://localhost:61208/api/4/amps/name
{"name": ["Dropbox", "Python", "Conntrack", "Nginx", "Systemd", "SystemV"]}
Get a specific item when field matches the given value::
# curl http://localhost:61208/api/3/amps/name/Dropbox
# curl http://localhost:61208/api/4/amps/name/Dropbox
{"Dropbox": [{"count": 0,
"countmax": None,
"countmin": 1.0,
@ -138,19 +148,19 @@ Get a specific item when field matches the given value::
"refresh": 3.0,
"regex": True,
"result": None,
"timer": 0.326155424118042}]}
"timer": 0.40151143074035645}]}
GET connections
---------------
Get plugin stats::
# curl http://localhost:61208/api/3/connections
# curl http://localhost:61208/api/4/connections
{"net_connections_enabled": True, "nf_conntrack_enabled": True}
Get a specific field::
# curl http://localhost:61208/api/3/connections/net_connections_enabled
# curl http://localhost:61208/api/4/connections/net_connections_enabled
{"net_connections_enabled": True}
GET containers
@ -158,22 +168,45 @@ GET containers
Get plugin stats::
# curl http://localhost:61208/api/3/containers
{"containers": [{"Command": ["top"],
# curl http://localhost:61208/api/4/containers
{"containers": [{"Command": ["/portainer"],
"Created": "2022-10-29T14:59:10.266701439Z",
"Id": "3abd51c615968482d9ccff5afc629f267f6dda113ed68b75b432615fae3b49fb",
"Image": ["portainer/portainer-ce:2.9.3"],
"Status": "running",
"Uptime": "2 weeks",
"cpu": {"total": 0.0},
"cpu_percent": 0.0,
"engine": "docker",
"io": {"cumulative_ior": 1339392, "cumulative_iow": 2080768},
"io_r": None,
"io_w": None,
"key": "name",
"memory": {"cache": None,
"limit": 7823585280,
"max_usage": None,
"rss": None,
"usage": 16338944},
"memory_usage": 16338944,
"name": "portainer",
"network": {"cumulative_rx": 5881801, "cumulative_tx": 0},
"network_rx": None,
"network_tx": None},
{"Command": ["top"],
"Created": "2023-12-09T10:45:34.339489876+01:00",
"Id": "481d6ffb7eef284d062628cf350bdd9ce0a803db8a2a505d75565ed24322b714",
"Image": "["docker.io/library/ubuntu:latest"]",
"Status": "running",
"Uptime": "yesterday",
"cpu": {"total": 2.780420133159415e-07},
"cpu_percent": 2.780420133159415e-07,
"Uptime": "6 days",
"cpu": {"total": 4.471361474716739e-07},
"cpu_percent": 4.471361474716739e-07,
"engine": "podman",
"io": {"ior": 0.0, "iow": 0.0, "time_since_update": 1},
"io_r": 0.0,
"io_w": 0.0,
"key": "name",
"memory": {"limit": 7823585280.0, "usage": 1974272.0},
"memory_usage": 1974272.0,
"memory": {"limit": 7823585280.0, "usage": 1499136.0},
"memory_usage": 1499136.0,
"name": "sad_darwin",
"network": {"rx": 0.0, "time_since_update": 1, "tx": 0.0},
"network_rx": 0.0,
@ -185,41 +218,22 @@ Get plugin stats::
"Id": "9491515251edcd5bb5dc17205d7ee573c0be96fe0b08b0a12a7e2cea874565ea",
"Image": "["k8s.gcr.io/pause:3.5"]",
"Status": "running",
"Uptime": "yesterday",
"cpu": {"total": 3.1294141365715215e-10},
"cpu_percent": 3.1294141365715215e-10,
"Uptime": "6 days",
"cpu": {"total": 3.2049907519180374e-10},
"cpu_percent": 3.2049907519180374e-10,
"engine": "podman",
"io": {"ior": 0.0, "iow": 0.0, "time_since_update": 1},
"io_r": 0.0,
"io_w": 0.0,
"key": "name",
"memory": {"limit": 7823585280.0, "usage": 692224.0},
"memory_usage": 692224.0,
"memory": {"limit": 7823585280.0, "usage": 409600.0},
"memory_usage": 409600.0,
"name": "8d0f1c783def-infra",
"network": {"rx": 0.0, "time_since_update": 1, "tx": 0.0},
"network_rx": 0.0,
"network_tx": 0.0,
"pod_id": "8d0f1c783def",
"pod_name": "8d0f1c783def-infra"},
{"Command": ["/portainer"],
"Created": "2022-10-29T14:59:10.266701439Z",
"Id": "3abd51c615968482d9ccff5afc629f267f6dda113ed68b75b432615fae3b49fb",
"Image": ["portainer/portainer-ce:2.9.3"],
"Status": "running",
"Uptime": "2 weeks",
"cpu": {"total": 0.0},
"cpu_percent": 0.0,
"engine": "docker",
"io": {},
"io_r": None,
"io_w": None,
"key": "name",
"memory": {},
"memory_usage": None,
"name": "portainer",
"network": {},
"network_rx": None,
"network_tx": None}],
"pod_name": "8d0f1c783def-infra"}],
"version": {},
"version_podman": {}}
@ -228,7 +242,7 @@ GET core
Get plugin stats::
# curl http://localhost:61208/api/3/core
# curl http://localhost:61208/api/4/core
{"log": 4, "phys": 2}
Fields descriptions:
@ -238,7 +252,7 @@ Fields descriptions:
Get a specific field::
# curl http://localhost:61208/api/3/core/phys
# curl http://localhost:61208/api/4/core/phys
{"phys": 2}
GET cpu
@ -246,24 +260,24 @@ GET cpu
Get plugin stats::
# curl http://localhost:61208/api/3/cpu
# curl http://localhost:61208/api/4/cpu
{"cpucore": 4,
"ctx_switches": 0,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 71.9,
"idle": 71.8,
"interrupts": 0,
"iowait": 0.5,
"iowait": 0.2,
"irq": 0.0,
"nice": 0.0,
"soft_interrupts": 0,
"softirq": 0.0,
"steal": 0.0,
"syscalls": 0,
"system": 3.5,
"system": 3.2,
"time_since_update": 1,
"total": 27.6,
"user": 24.1}
"total": 28.0,
"user": 24.8}
Fields descriptions:
@ -285,15 +299,15 @@ Fields descriptions:
Get a specific field::
# curl http://localhost:61208/api/3/cpu/total
{"total": 27.6}
# curl http://localhost:61208/api/4/cpu/total
{"total": 28.0}
GET diskio
----------
Get plugin stats::
# curl http://localhost:61208/api/3/diskio
# curl http://localhost:61208/api/4/diskio
[{"disk_name": "sda",
"key": "disk_name",
"read_bytes": 0,
@ -311,12 +325,12 @@ Get plugin stats::
Get a specific field::
# curl http://localhost:61208/api/3/diskio/disk_name
# curl http://localhost:61208/api/4/diskio/disk_name
{"disk_name": ["sda", "sda1", "sda2", "sda5", "dm-0", "dm-1"]}
Get a specific item when field matches the given value::
# curl http://localhost:61208/api/3/diskio/disk_name/sda
# curl http://localhost:61208/api/4/diskio/disk_name/sda
{"sda": [{"disk_name": "sda",
"key": "disk_name",
"read_bytes": 0,
@ -330,66 +344,66 @@ GET fs
Get plugin stats::
# curl http://localhost:61208/api/3/fs
# curl http://localhost:61208/api/4/fs
[{"device_name": "/dev/mapper/ubuntu--gnome--vg-root",
"free": 24790568960,
"free": 24446767104,
"fs_type": "ext4",
"key": "mnt_point",
"mnt_point": "/",
"percent": 89.3,
"percent": 89.4,
"size": 243334156288,
"used": 206156132352},
"used": 206499934208},
{"device_name": "zsfpool",
"free": 41811968,
"free": 31195136,
"fs_type": "zfs",
"key": "mnt_point",
"mnt_point": "/zsfpool",
"percent": 0.3,
"size": 41943040,
"used": 131072}]
"percent": 25.4,
"size": 41811968,
"used": 10616832}]
Get a specific field::
# curl http://localhost:61208/api/3/fs/mnt_point
# curl http://localhost:61208/api/4/fs/mnt_point
{"mnt_point": ["/", "/zsfpool", "/var/snap/firefox/common/host-hunspell"]}
Get a specific item when field matches the given value::
# curl http://localhost:61208/api/3/fs/mnt_point//
# curl http://localhost:61208/api/4/fs/mnt_point//
{"/": [{"device_name": "/dev/mapper/ubuntu--gnome--vg-root",
"free": 24790568960,
"free": 24446767104,
"fs_type": "ext4",
"key": "mnt_point",
"mnt_point": "/",
"percent": 89.3,
"percent": 89.4,
"size": 243334156288,
"used": 206156132352}]}
"used": 206499934208}]}
GET ip
------
Get plugin stats::
# curl http://localhost:61208/api/3/ip
{"address": "192.168.0.32",
"gateway": "192.168.0.254",
# curl http://localhost:61208/api/4/ip
{"address": "192.168.1.14",
"gateway": "192.168.1.1",
"mask": "255.255.255.0",
"mask_cidr": 24,
"public_address": "91.166.228.228",
"public_address": "92.151.148.66",
"public_info_human": ""}
Get a specific field::
# curl http://localhost:61208/api/3/ip/gateway
{"gateway": "192.168.0.254"}
# curl http://localhost:61208/api/4/ip/gateway
{"gateway": "192.168.1.1"}
GET load
--------
Get plugin stats::
# curl http://localhost:61208/api/3/load
{"cpucore": 4, "min1": 0.67626953125, "min15": 1.359375, "min5": 1.27734375}
# curl http://localhost:61208/api/4/load
{"cpucore": 4, "min1": 1.9189453125, "min15": 0.9111328125, "min5": 1.537109375}
Fields descriptions:
@ -400,25 +414,25 @@ Fields descriptions:
Get a specific field::
# curl http://localhost:61208/api/3/load/min1
{"min1": 0.67626953125}
# curl http://localhost:61208/api/4/load/min1
{"min1": 1.9189453125}
GET mem
-------
Get plugin stats::
# curl http://localhost:61208/api/3/mem
{"active": 2575863808,
"available": 1762955264,
"buffers": 91045888,
"cached": 1823641600,
"free": 1762955264,
"inactive": 3581095936,
"percent": 77.5,
"shared": 453021696,
# curl http://localhost:61208/api/4/mem
{"active": 2916397056,
"available": 2227191808,
"buffers": 126803968,
"cached": 2636341248,
"free": 2227191808,
"inactive": 3422937088,
"percent": 71.5,
"shared": 556515328,
"total": 7823585280,
"used": 6060630016}
"used": 5596393472}
Fields descriptions:
@ -436,7 +450,7 @@ Fields descriptions:
Get a specific field::
# curl http://localhost:61208/api/3/mem/total
# curl http://localhost:61208/api/4/mem/total
{"total": 7823585280}
GET memswap
@ -444,14 +458,14 @@ GET memswap
Get plugin stats::
# curl http://localhost:61208/api/3/memswap
{"free": 5212143616,
"percent": 35.5,
"sin": 2563657728,
"sout": 5443428352,
# curl http://localhost:61208/api/4/memswap
{"free": 4683223040,
"percent": 42.1,
"sin": 4915187712,
"sout": 8894914560,
"time_since_update": 1,
"total": 8082419712,
"used": 2870276096}
"used": 3399196672}
Fields descriptions:
@ -465,7 +479,7 @@ Fields descriptions:
Get a specific field::
# curl http://localhost:61208/api/3/memswap/total
# curl http://localhost:61208/api/4/memswap/total
{"total": 8082419712}
GET network
@ -473,11 +487,11 @@ GET network
Get plugin stats::
# curl http://localhost:61208/api/3/network
# curl http://localhost:61208/api/4/network
[{"alias": None,
"cumulative_cx": 357426016,
"cumulative_rx": 178713008,
"cumulative_tx": 178713008,
"cumulative_cx": 1314073012,
"cumulative_rx": 657036506,
"cumulative_tx": 657036506,
"cx": 0,
"interface_name": "lo",
"is_up": True,
@ -487,14 +501,14 @@ Get plugin stats::
"time_since_update": 1,
"tx": 0},
{"alias": None,
"cumulative_cx": 4300161137,
"cumulative_rx": 4046835795,
"cumulative_tx": 253325342,
"cx": 126,
"cumulative_cx": 5651740693,
"cumulative_rx": 5354455235,
"cumulative_tx": 297285458,
"cx": 224,
"interface_name": "wlp2s0",
"is_up": True,
"key": "interface_name",
"rx": 0,
"rx": 98,
"speed": 0,
"time_since_update": 1,
"tx": 126}]
@ -515,7 +529,7 @@ Fields descriptions:
Get a specific field::
# curl http://localhost:61208/api/3/network/interface_name
# curl http://localhost:61208/api/4/network/interface_name
{"interface_name": ["lo",
"wlp2s0",
"br-40875d2e2716",
@ -526,11 +540,11 @@ Get a specific field::
Get a specific item when field matches the given value::
# curl http://localhost:61208/api/3/network/interface_name/lo
# curl http://localhost:61208/api/4/network/interface_name/lo
{"lo": [{"alias": None,
"cumulative_cx": 357426016,
"cumulative_rx": 178713008,
"cumulative_tx": 178713008,
"cumulative_cx": 1314073012,
"cumulative_rx": 657036506,
"cumulative_tx": 657036506,
"cx": 0,
"interface_name": "lo",
"is_up": True,
@ -545,45 +559,45 @@ GET now
Get plugin stats::
# curl http://localhost:61208/api/3/now
"2023-12-10 20:12:30 CET"
# curl http://localhost:61208/api/4/now
"2023-12-15 17:16:58 CET"
GET percpu
----------
Get plugin stats::
# curl http://localhost:61208/api/3/percpu
# curl http://localhost:61208/api/4/percpu
[{"cpu_number": 0,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 47.0,
"idle": 75.0,
"iowait": 0.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"steal": 0.0,
"system": 1.0,
"total": 53.0,
"user": 1.0},
"system": 4.1,
"total": 25.0,
"user": 20.9},
{"cpu_number": 1,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 45.0,
"iowait": 1.0,
"idle": 89.4,
"iowait": 0.7,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"steal": 0.0,
"system": 0.0,
"total": 55.0,
"user": 4.0}]
"system": 2.6,
"total": 10.6,
"user": 7.3}]
Get a specific field::
# curl http://localhost:61208/api/3/percpu/cpu_number
# curl http://localhost:61208/api/4/percpu/cpu_number
{"cpu_number": [0, 1, 2, 3]}
GET ports
@ -591,52 +605,52 @@ GET ports
Get plugin stats::
# curl http://localhost:61208/api/3/ports
# curl http://localhost:61208/api/4/ports
[{"description": "DefaultGateway",
"host": "192.168.0.254",
"host": "192.168.1.1",
"indice": "port_0",
"port": 0,
"refresh": 30,
"rtt_warning": None,
"status": 0.084546,
"status": 0.006155,
"timeout": 3}]
Get a specific field::
# curl http://localhost:61208/api/3/ports/host
{"host": ["192.168.0.254"]}
# curl http://localhost:61208/api/4/ports/host
{"host": ["192.168.1.1"]}
Get a specific item when field matches the given value::
# curl http://localhost:61208/api/3/ports/host/192.168.0.254
{"192.168.0.254": [{"description": "DefaultGateway",
"host": "192.168.0.254",
"indice": "port_0",
"port": 0,
"refresh": 30,
"rtt_warning": None,
"status": 0.084546,
"timeout": 3}]}
# curl http://localhost:61208/api/4/ports/host/192.168.1.1
{"192.168.1.1": [{"description": "DefaultGateway",
"host": "192.168.1.1",
"indice": "port_0",
"port": 0,
"refresh": 30,
"rtt_warning": None,
"status": 0.006155,
"timeout": 3}]}
GET processcount
----------------
Get plugin stats::
# curl http://localhost:61208/api/3/processcount
{"pid_max": 0, "running": 1, "sleeping": 319, "thread": 1713, "total": 385}
# curl http://localhost:61208/api/4/processcount
{"pid_max": 0, "running": 1, "sleeping": 323, "thread": 1634, "total": 388}
Get a specific field::
# curl http://localhost:61208/api/3/processcount/total
{"total": 385}
# curl http://localhost:61208/api/4/processcount/total
{"total": 388}
GET psutilversion
-----------------
Get plugin stats::
# curl http://localhost:61208/api/3/psutilversion
# curl http://localhost:61208/api/4/psutilversion
[5, 9, 6]
GET quicklook
@ -644,77 +658,77 @@ GET quicklook
Get plugin stats::
# curl http://localhost:61208/api/3/quicklook
{"cpu": 27.6,
# curl http://localhost:61208/api/4/quicklook
{"cpu": 28.0,
"cpu_hz": 2025000000.0,
"cpu_hz_current": 1771800000.0,
"cpu_hz_current": 2048950249.9999998,
"cpu_name": "Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz",
"mem": 77.5,
"mem": 71.5,
"percpu": [{"cpu_number": 0,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 47.0,
"idle": 75.0,
"iowait": 0.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"steal": 0.0,
"system": 1.0,
"total": 53.0,
"user": 1.0},
"system": 4.1,
"total": 25.0,
"user": 20.9},
{"cpu_number": 1,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 45.0,
"iowait": 1.0,
"idle": 89.4,
"iowait": 0.7,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"steal": 0.0,
"system": 0.0,
"total": 55.0,
"user": 4.0},
"system": 2.6,
"total": 10.6,
"user": 7.3},
{"cpu_number": 2,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 27.0,
"idle": 95.2,
"iowait": 0.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"steal": 0.0,
"system": 1.0,
"total": 73.0,
"user": 20.0},
"system": 2.0,
"total": 4.8,
"user": 2.7},
{"cpu_number": 3,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 24.0,
"idle": 28.0,
"iowait": 0.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"steal": 0.0,
"system": 3.0,
"total": 76.0,
"user": 23.0}],
"swap": 35.5}
"system": 4.7,
"total": 72.0,
"user": 67.3}],
"swap": 42.1}
Get a specific field::
# curl http://localhost:61208/api/3/quicklook/cpu
{"cpu": 27.6}
# curl http://localhost:61208/api/4/quicklook/cpu
{"cpu": 28.0}
GET sensors
-----------
Get plugin stats::
# curl http://localhost:61208/api/3/sensors
# curl http://localhost:61208/api/4/sensors
[{"critical": 105,
"key": "label",
"label": "acpitz 0",
@ -732,7 +746,7 @@ Get plugin stats::
Get a specific field::
# curl http://localhost:61208/api/3/sensors/label
# curl http://localhost:61208/api/4/sensors/label
{"label": ["acpitz 0",
"acpitz 1",
"Package id 0",
@ -745,7 +759,7 @@ Get a specific field::
Get a specific item when field matches the given value::
# curl http://localhost:61208/api/3/sensors/label/acpitz 0
# curl http://localhost:61208/api/4/sensors/label/acpitz 0
{"acpitz 0": [{"critical": 105,
"key": "label",
"label": "acpitz 0",
@ -759,7 +773,7 @@ GET system
Get plugin stats::
# curl http://localhost:61208/api/3/system
# curl http://localhost:61208/api/4/system
{"hostname": "XPS13-9333",
"hr_name": "Ubuntu 22.04 64bit",
"linux_distro": "Ubuntu 22.04",
@ -769,7 +783,7 @@ Get plugin stats::
Get a specific field::
# curl http://localhost:61208/api/3/system/os_name
# curl http://localhost:61208/api/4/system/os_name
{"os_name": "Linux"}
GET uptime
@ -777,15 +791,15 @@ GET uptime
Get plugin stats::
# curl http://localhost:61208/api/3/uptime
"15 days, 11:14:41"
# curl http://localhost:61208/api/4/uptime
"20 days, 8:19:07"
GET all stats
-------------
Get all Glances stats::
# curl http://localhost:61208/api/3/all
# curl http://localhost:61208/api/4/all
Return a very big dictionary (avoid using this request, performances will be poor)...
GET top n items of a specific plugin
@ -793,7 +807,7 @@ GET top n items of a specific plugin
Get top 2 processes of the processlist plugin::
# curl http://localhost:61208/api/3/processlist/top/2
# curl http://localhost:61208/api/4/processlist/top/2
[{"cmdline": ["/snap/firefox/3206/usr/lib/firefox/firefox",
"-contentproc",
"-childID",
@ -821,19 +835,19 @@ Get top 2 processes of the processlist plugin::
"cpu_times": {"children_system": 0.0,
"children_user": 0.0,
"iowait": 0.0,
"system": 226.21,
"user": 2650.94},
"system": 261.09,
"user": 3002.21},
"gids": {"effective": 1000, "real": 1000, "saved": 1000},
"io_counters": [230234112, 0, 0, 0, 0],
"io_counters": [372081664, 0, 0, 0, 0],
"key": "pid",
"memory_info": {"data": 1036189696,
"memory_info": {"data": 1145556992,
"dirty": 0,
"lib": 0,
"rss": 505749504,
"shared": 67194880,
"rss": 533700608,
"shared": 66142208,
"text": 643072,
"vms": 3629031424},
"memory_percent": 6.464421181589011,
"vms": 3753902080},
"memory_percent": 6.8216883807010795,
"name": "WebExtensions",
"nice": 0,
"num_threads": 20,
@ -841,28 +855,33 @@ Get top 2 processes of the processlist plugin::
"status": "S",
"time_since_update": 1,
"username": "nicolargo"},
{"cmdline": ["/snap/firefox/3206/usr/lib/firefox/firefox"],
{"cmdline": ["/usr/share/code/code",
"--ms-enable-electron-run-as-node",
"/home/nicolargo/.vscode/extensions/ms-python.vscode-pylance-2023.11.10/dist/server.bundle.js",
"--cancellationReceive=file:909dfdaf9d60a0ebbc9aa560a7438878b4f45eec8b",
"--node-ipc",
"--clientProcessId=10692"],
"cpu_percent": 0.0,
"cpu_times": {"children_system": 709.9,
"children_user": 4938.6,
"cpu_times": {"children_system": 0.61,
"children_user": 4.25,
"iowait": 0.0,
"system": 1739.59,
"user": 5867.67},
"system": 336.31,
"user": 5395.51},
"gids": {"effective": 1000, "real": 1000, "saved": 1000},
"io_counters": [3403158528, 6581563392, 0, 0, 0],
"io_counters": [550125568, 2199552, 0, 0, 0],
"key": "pid",
"memory_info": {"data": 1767538688,
"memory_info": {"data": 862629888,
"dirty": 0,
"lib": 0,
"rss": 399204352,
"shared": 108036096,
"text": 643072,
"vms": 14074568704},
"memory_percent": 5.102575580284338,
"name": "firefox",
"rss": 469827584,
"shared": 24416256,
"text": 120561664,
"vms": 1207768686592},
"memory_percent": 6.005272099494517,
"name": "code",
"nice": 0,
"num_threads": 177,
"pid": 7195,
"num_threads": 13,
"pid": 11004,
"status": "S",
"time_since_update": 1,
"username": "nicolargo"}]
@ -874,42 +893,42 @@ GET stats history
History of a plugin::
# curl http://localhost:61208/api/3/cpu/history
{"system": [["2023-12-10T20:12:33.056772", 3.4],
["2023-12-10T20:12:34.107797", 3.4],
["2023-12-10T20:12:35.377582", 1.9]],
"user": [["2023-12-10T20:12:33.056764", 20.8],
["2023-12-10T20:12:34.107773", 20.8],
["2023-12-10T20:12:35.377571", 9.1]]}
# curl http://localhost:61208/api/4/cpu/history
{"system": [["2023-12-15T17:17:00.234889", 3.2],
["2023-12-15T17:17:01.256351", 2.0],
["2023-12-15T17:17:02.459609", 2.0]],
"user": [["2023-12-15T17:17:00.234874", 24.8],
["2023-12-15T17:17:01.256343", 11.3],
["2023-12-15T17:17:02.459594", 11.3]]}
Limit history to last 2 values::
# curl http://localhost:61208/api/3/cpu/history/2
{"system": [["2023-12-10T20:12:34.107797", 3.4],
["2023-12-10T20:12:35.377582", 1.9]],
"user": [["2023-12-10T20:12:34.107773", 20.8],
["2023-12-10T20:12:35.377571", 9.1]]}
# curl http://localhost:61208/api/4/cpu/history/2
{"system": [["2023-12-15T17:17:01.256351", 2.0],
["2023-12-15T17:17:02.459609", 2.0]],
"user": [["2023-12-15T17:17:01.256343", 11.3],
["2023-12-15T17:17:02.459594", 11.3]]}
History for a specific field::
# curl http://localhost:61208/api/3/cpu/system/history
{"system": [["2023-12-10T20:12:30.854088", 3.5],
["2023-12-10T20:12:33.056772", 3.4],
["2023-12-10T20:12:34.107797", 3.4],
["2023-12-10T20:12:35.377582", 1.9]]}
# curl http://localhost:61208/api/4/cpu/system/history
{"system": [["2023-12-15T17:16:58.322839", 3.2],
["2023-12-15T17:17:00.234889", 3.2],
["2023-12-15T17:17:01.256351", 2.0],
["2023-12-15T17:17:02.459609", 2.0]]}
Limit history for a specific field to last 2 values::
# curl http://localhost:61208/api/3/cpu/system/history
{"system": [["2023-12-10T20:12:34.107797", 3.4],
["2023-12-10T20:12:35.377582", 1.9]]}
# curl http://localhost:61208/api/4/cpu/system/history
{"system": [["2023-12-15T17:17:01.256351", 2.0],
["2023-12-15T17:17:02.459609", 2.0]]}
GET limits (used for thresholds)
--------------------------------
All limits/thresholds::
# curl http://localhost:61208/api/3/all/limits
# curl http://localhost:61208/api/4/all/limits
{"alert": {"alert_disable": ["False"], "history_size": 1200.0},
"amps": {"amps_disable": ["False"], "history_size": 1200.0},
"containers": {"containers_all": ["False"],
@ -1092,7 +1111,7 @@ All limits/thresholds::
Limits/thresholds for the cpu plugin::
# curl http://localhost:61208/api/3/cpu/limits
# curl http://localhost:61208/api/4/cpu/limits
{"cpu_ctx_switches_careful": 160000.0,
"cpu_ctx_switches_critical": 200000.0,
"cpu_ctx_switches_warning": 180000.0,

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" "Dec 10, 2023" "4.0.0_beta01" "Glances"
.TH "GLANCES" "1" "Dec 15, 2023" "4.0.0_beta01" "Glances"
.SH NAME
glances \- An eye on your system
.SH SYNOPSIS

View File

@ -25,6 +25,8 @@ import subprocess
from datetime import datetime
import re
import base64
import functools
import weakref
import queue
from configparser import ConfigParser, NoOptionError, NoSectionError
@ -406,3 +408,21 @@ def folder_size(path, errno=0):
except OSError as e:
ret_err = e.errno
return ret_size, ret_err
def weak_lru_cache(maxsize=128, typed=False):
"""LRU Cache decorator that keeps a weak reference to self
Source: https://stackoverflow.com/a/55990799"""
def wrapper(func):
@functools.lru_cache(maxsize, typed)
def _func(_self, *args, **kwargs):
return func(_self(), *args, **kwargs)
@functools.wraps(func)
def inner(self, *args, **kwargs):
return _func(weakref.ref(self), *args, **kwargs)
return inner
return wrapper

View File

@ -20,6 +20,8 @@ from urllib.parse import urljoin
# from typing import Annotated
from typing_extensions import Annotated
from glances import __version__
from glances.password import GlancesPassword
from glances.timer import Timer
from glances.logger import logger
@ -48,7 +50,7 @@ security = HTTPBasic()
class GlancesRestfulApi(object):
"""This class manages the Restful API server."""
API_VERSION = '3'
API_VERSION = '4'
def __init__(self, config=None, args=None):
# Init config
@ -77,8 +79,12 @@ class GlancesRestfulApi(object):
# FastAPI Init
if self.args.password:
self._app = FastAPI(dependencies=[Depends(self.authentication)])
self._password = GlancesPassword(username=args.username,
config=config)
else:
self._app = FastAPI()
self._password = None
# Change the default root path
if self.url_prefix != '/':
@ -104,8 +110,6 @@ class GlancesRestfulApi(object):
# FastAPI Enable GZIP compression
# https://fastapi.tiangolo.com/advanced/middleware/
# TODO: do not work for the moment
# curl return a binary stream, not the JSON
self._app.add_middleware(GZipMiddleware,
minimum_size=1000)
@ -131,26 +135,20 @@ class GlancesRestfulApi(object):
def app(self):
return self._app()
# TODO: the password comparaison is not working for the moment.
# if the password is wrong, authentication is working...
# Perhaps because the password is hashed in the GlancesPassword class
# and the one given by creds.password is not hashed ?
def authentication(self, creds: Annotated[HTTPBasicCredentials, Depends(security)]):
"""Check if a username/password combination is valid."""
# print(creds.username, creds.password)
# print(self.args.username, self.args.password)
if creds.username == self.args.username:
from glances.password import GlancesPassword
# check_password and get_hash are (lru) cached to optimize the requests
if self._password.check_password(self.args.password,
self._password.get_hash(creds.password)):
return creds.username
pwd = GlancesPassword(username=creds.username, config=self.config)
# print(self.args.password, pwd.get_hash(creds.username))
return pwd.check_password(self.args.password, pwd.get_hash(creds.username))
else:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect username or password",
headers={"WWW-Authenticate": "Basic"},
)
# If the username/password combination is invalid, return an HTTP 401
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect username or password",
headers={"WWW-Authenticate": "Basic"},
)
def _router(self):
"""Define a custom router for Glances path."""
@ -282,10 +280,12 @@ class GlancesRestfulApi(object):
def _index(self, request: Request):
"""Return main index.html (/) file.
Parameters are available through the request object.
Example: http://localhost:61208/?refresh=5
"""
Note: This function is only called the first time the page is loaded.
"""
refresh_time = request.query_params.get('refresh',
default=max(1, int(self.args.time)))
@ -308,8 +308,7 @@ class GlancesRestfulApi(object):
See related issue: Web server health check endpoint #1988
"""
# TODO: return a more useful status
return "Active"
return ORJSONResponse({'version': __version__})
def _api_help(self):
"""Glances API RESTful implementation.

View File

@ -13,10 +13,12 @@ from pprint import pformat
import json
import time
from glances.outputs.glances_restful_api import GlancesRestfulApi
from glances.logger import logger
from glances.globals import iteritems
API_URL = "http://localhost:61208/api/3"
API_URL = "http://localhost:61208/api/{api_version}".format(api_version=GlancesRestfulApi.API_VERSION)
APIDOC_HEADER = """\
.. _api:
@ -33,12 +35,14 @@ The Glances Restfull/API server could be ran using the following command line:
API URL
-------
The default root API URL is ``http://localhost:61208/api/3``.
The default root API URL is ``http://localhost:61208/api/{api_version}``.
The bind address and port could be changed using the ``--bind`` and ``--port`` command line options.
It is also possible to define an URL prefix using the ``url_prefix`` option from the [outputs] section
of the Glances configuration file. The url_prefix should always end with a slash (``/``).
of the Glances configuration file.
Note: The url_prefix should always end with a slash (``/``).
For example:
@ -46,10 +50,16 @@ For example:
[outputs]
url_prefix = /glances/
will change the root API URL to ``http://localhost:61208/glances/api/3`` and the Web UI URL to
will change the root API URL to ``http://localhost:61208/glances/api/{api_version}`` and the Web UI URL to
``http://localhost:61208/glances/``
"""
Web UI refresh
--------------
It is possible to change the Web UI refresh rate (default is 2 seconds) using the following option in the URL:
``http://localhost:61208/glances/?refresh=5``
""".format(api_version=GlancesRestfulApi.API_VERSION)
def indent_stat(stat, indent=' '):
@ -67,7 +77,7 @@ def print_api_status():
print('-' * len(sub_title))
print('')
print('This entry point should be used to check the API status.')
print('It will return nothing but a 200 return code if everything is OK.')
print('It will the Glances version and a 200 return code if everything is OK.')
print('')
print('Get the Rest API status::')
print('')

View File

@ -2,15 +2,15 @@ import { store } from './store.js';
import Favico from 'favico.js';
// prettier-ignore
const fetchAll = () => fetch('api/3/all', { method: 'GET' }).then((response) => response.json());
const fetchAll = () => fetch('api/4/all', { method: 'GET' }).then((response) => response.json());
// prettier-ignore
const fetchAllViews = () => fetch('api/3/all/views', { method: 'GET' }).then((response) => response.json());
const fetchAllViews = () => fetch('api/4/all/views', { method: 'GET' }).then((response) => response.json());
// prettier-ignore
const fetchAllLimits = () => fetch('api/3/all/limits', { method: 'GET' }).then((response) => response.json());
const fetchAllLimits = () => fetch('api/4/all/limits', { method: 'GET' }).then((response) => response.json());
// prettier-ignore
const fetchArgs = () => fetch('api/3/args', { method: 'GET' }).then((response) => response.json());
const fetchArgs = () => fetch('api/4/args', { method: 'GET' }).then((response) => response.json());
// prettier-ignore
const fetchConfig = () => fetch('api/3/config', { method: 'GET' }).then((response) => response.json());
const fetchConfig = () => fetch('api/4/config', { method: 'GET' }).then((response) => response.json());
class GlancesHelperService {
limits = {};

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
# SPDX-FileCopyrightText: 2022 Nicolas Hennion <nicolas@nicolargo.com>
# SPDX-FileCopyrightText: 2023 Nicolas Hennion <nicolas@nicolargo.com>
#
# SPDX-License-Identifier: LGPL-3.0-only
#
@ -16,7 +16,7 @@ import sys
import uuid
from io import open
from glances.globals import b, safe_makedirs
from glances.globals import b, safe_makedirs, weak_lru_cache
from glances.config import user_config_dir
from glances.logger import logger
@ -42,21 +42,25 @@ class GlancesPassword(object):
else:
return self.config.get_value('passwords', 'local_password_path', default=user_config_dir())
@weak_lru_cache(maxsize=32)
def get_hash(self, plain_password, salt=''):
"""Return the hashed password, salt + pbkdf2_hmac."""
return hashlib.pbkdf2_hmac('sha256', plain_password.encode(), salt.encode(), 100000, dklen=128).hex()
@weak_lru_cache(maxsize=32)
def hash_password(self, plain_password):
"""Hash password with a salt based on UUID (universally unique identifier)."""
salt = uuid.uuid4().hex
encrypted_password = self.get_hash(plain_password, salt=salt)
return salt + '$' + encrypted_password
@weak_lru_cache(maxsize=32)
def check_password(self, hashed_password, plain_password):
"""Encode the plain_password with the salt of the hashed_password.
Return the comparison with the encrypted_password.
"""
logger.info("Check password")
salt, encrypted_password = hashed_password.split('$')
re_encrypted_password = self.get_hash(plain_password, salt=salt)
return encrypted_password == re_encrypted_password

View File

@ -135,16 +135,6 @@ class PluginModel(GlancesPluginModel):
"""Return the key of the list."""
return 'pid'
def get_raw(self):
"""Overwrite the default get_raw methode in order to return dict in the values.
for example:
pmem(rss=6377472, vms=13946880, shared=4100096, text=913408, lib=0, data=2289664, dirty=0)
will be replaced by:
{'rss': 6377472, 'vms': 13946880, 'shared': 4100096, 'text': 913408, 'lib': 0, 'data': 2289664, 'dirty': 0}
"""
# TODO: When the WebUI is displayed, this function is call > 2 times per second... Why ???
return [{k: (v._asdict() if hasattr(v, '_asdict') else v) for k, v in p.items()} for p in self.stats]
def update(self):
"""Update processes stats using the input method."""
# Init new stats
@ -163,7 +153,7 @@ class PluginModel(GlancesPluginModel):
# No SNMP grab for processes
pass
# Update the stats
# Update the stats and transform all namedtuples to dict
self.stats = stats
# Get the max values (dict)
@ -230,8 +220,8 @@ class PluginModel(GlancesPluginModel):
def _get_process_curses_vms(self, p, selected, args):
"""Return process VMS curses"""
if key_exist_value_not_none_not_v('memory_info', p, '', 1):
msg = self.layout_stat['virt'].format(self.auto_unit(p['memory_info'][1], low_precision=False))
if key_exist_value_not_none_not_v('memory_info', p, '', 1) and 'vms' in p['memory_info']:
msg = self.layout_stat['virt'].format(self.auto_unit(p['memory_info']['vms'], low_precision=False))
ret = self.curse_add_line(msg, optional=True)
else:
msg = self.layout_header['virt'].format('?')
@ -240,8 +230,8 @@ class PluginModel(GlancesPluginModel):
def _get_process_curses_rss(self, p, selected, args):
"""Return process RSS curses"""
if key_exist_value_not_none_not_v('memory_info', p, '', 0):
msg = self.layout_stat['res'].format(self.auto_unit(p['memory_info'][0], low_precision=False))
if key_exist_value_not_none_not_v('memory_info', p, '', 0) and 'rss' in p['memory_info']:
msg = self.layout_stat['res'].format(self.auto_unit(p['memory_info']['rss'], low_precision=False))
ret = self.curse_add_line(msg, optional=True)
else:
msg = self.layout_header['res'].format('?')
@ -264,7 +254,7 @@ class PluginModel(GlancesPluginModel):
"""Return process time curses"""
try:
# Sum user and system time
user_system_time = p['cpu_times'][0] + p['cpu_times'][1]
user_system_time = p['cpu_times']['user'] + p['cpu_times']['system']
except (OverflowError, TypeError):
# Catch OverflowError on some Amazon EC2 server
# See https://github.com/nicolargo/glances/issues/87
@ -503,16 +493,17 @@ class PluginModel(GlancesPluginModel):
Input p is a dict with the following keys:
{'status': 'S',
'memory_info': pmem(rss=466890752, vms=3365347328, shared=68153344,
text=659456, lib=0, data=774647808, dirty=0),
'memory_info': {'rss': 466890752, 'vms': 3365347328, 'shared': 68153344,
'text': 659456, 'lib': 0, 'data': 774647808, 'dirty': 0],
'pid': 4980,
'io_counters': [165385216, 0, 165385216, 0, 1],
'num_threads': 20,
'nice': 0,
'memory_percent': 5.958135664449709,
'cpu_percent': 0.0,
'gids': pgids(real=1000, effective=1000, saved=1000),
'cpu_times': pcputimes(user=696.38, system=119.98, children_user=0.0, children_system=0.0, iowait=0.0),
'gids': {'real': 1000, 'effective': 1000, 'saved': 1000},
'cpu_times': {'user': 696.38, 'system': 119.98, 'children_user': 0.0,
'children_system': 0.0, 'iowait': 0.0),
'name': 'WebExtensions',
'key': 'pid',
'time_since_update': 2.1997854709625244,
@ -589,10 +580,11 @@ class PluginModel(GlancesPluginModel):
ret.append(self.curse_add_line(msg, decoration='INFO'))
if 'memory_info' in p and p['memory_info'] is not None:
ret.append(self.curse_add_line(' Memory info: '))
for k in p['memory_info']._asdict():
for k, v in p['memory_info'].items():
ret.append(
self.curse_add_line(
self.auto_unit(p['memory_info']._asdict()[k], low_precision=False),
self.auto_unit(v,
low_precision=False),
decoration='INFO',
splittable=True,
)
@ -601,7 +593,10 @@ class PluginModel(GlancesPluginModel):
if 'memory_swap' in p and p['memory_swap'] is not None:
ret.append(
self.curse_add_line(
self.auto_unit(p['memory_swap'], low_precision=False), decoration='INFO', splittable=True
self.auto_unit(p['memory_swap'],
low_precision=False),
decoration='INFO',
splittable=True
)
)
ret.append(self.curse_add_line(' swap ', splittable=True))
@ -700,12 +695,12 @@ class PluginModel(GlancesPluginModel):
):
# VMS
msg = self.layout_stat['virt'].format(
self.auto_unit(self.__sum_stats('memory_info', indice=1, mmm=mmm), low_precision=False)
self.auto_unit(self.__sum_stats('memory_info', sub_key='vms', mmm=mmm), low_precision=False)
)
ret.append(self.curse_add_line(msg, decoration=self.__mmm_deco(mmm), optional=True))
# RSS
msg = self.layout_stat['res'].format(
self.auto_unit(self.__sum_stats('memory_info', indice=0, mmm=mmm), low_precision=False)
self.auto_unit(self.__sum_stats('memory_info', sub_key='rss', mmm=mmm), low_precision=False)
)
ret.append(self.curse_add_line(msg, decoration=self.__mmm_deco(mmm), optional=True))
else:
@ -735,7 +730,7 @@ class PluginModel(GlancesPluginModel):
if 'io_counters' in self.stats[0] and mmm is None:
# IO read
io_rs = int(
(self.__sum_stats('io_counters', 0) - self.__sum_stats('io_counters', indice=2, mmm=mmm))
(self.__sum_stats('io_counters', 0) - self.__sum_stats('io_counters', sub_key=2, mmm=mmm))
/ self.stats[0]['time_since_update']
)
if io_rs == 0:
@ -745,7 +740,7 @@ class PluginModel(GlancesPluginModel):
ret.append(self.curse_add_line(msg, decoration=self.__mmm_deco(mmm), optional=True, additional=True))
# IO write
io_ws = int(
(self.__sum_stats('io_counters', 1) - self.__sum_stats('io_counters', indice=3, mmm=mmm))
(self.__sum_stats('io_counters', 1) - self.__sum_stats('io_counters', sub_key=3, mmm=mmm))
/ self.stats[0]['time_since_update']
)
if io_ws == 0:
@ -779,10 +774,10 @@ class PluginModel(GlancesPluginModel):
self.mmm_min = {}
self.mmm_max = {}
def __sum_stats(self, key, indice=None, mmm=None):
def __sum_stats(self, key, sub_key=None, mmm=None):
"""Return the sum of the stats value for the given key.
:param indice: If indice is set, get the p[key][indice]
:param sub_key: If sub_key is set, get the p[key][sub_key]
:param mmm: display min, max, mean or current (if mmm=None)
"""
# Compute stats summary
@ -794,13 +789,13 @@ class PluginModel(GlancesPluginModel):
if p[key] is None:
# Correct https://github.com/nicolargo/glances/issues/1105#issuecomment-363553788
continue
if indice is None:
if sub_key is None:
ret += p[key]
else:
ret += p[key][indice]
ret += p[key][sub_key]
# Manage Min/Max/Mean
mmm_key = self.__mmm_key(key, indice)
mmm_key = self.__mmm_key(key, sub_key)
if mmm == 'min':
try:
if self.mmm_min[mmm_key] > ret:
@ -824,10 +819,10 @@ class PluginModel(GlancesPluginModel):
return ret
def __mmm_key(self, key, indice):
def __mmm_key(self, key, sub_key):
ret = key
if indice is not None:
ret += str(indice)
if sub_key is not None:
ret += str(sub_key)
return ret
def __sort_stats(self, sorted_by=None):

View File

@ -353,9 +353,8 @@ class GlancesProcesses(object):
def update(self):
"""Update the processes stats."""
# Reset the stats
self.processlist = []
self.reset_processcount()
# Init new processes stats
processlist = []
# Do not process if disable tag is set
if self.disable_tag:
@ -392,7 +391,7 @@ class GlancesProcesses(object):
# Build the processes stats list (it is why we need psutil>=5.3.0)
# This is one of the main bottleneck of Glances (see flame graph)
# Filter processes
self.processlist = list(
processlist = list(
filter(
lambda p: not (BSD and p.info['name'] == 'idle')
and not (WINDOWS and p.info['name'] == 'System Idle Process')
@ -402,17 +401,17 @@ class GlancesProcesses(object):
)
)
# Only get the info key
self.processlist = [p.info for p in self.processlist]
processlist = [p.info for p in processlist]
# Sort the processes list by the current sort_key
self.processlist = sort_stats(self.processlist, sorted_by=self.sort_key, reverse=True)
processlist = sort_stats(processlist, sorted_by=self.sort_key, reverse=True)
# Update the processcount
self.update_processcount(self.processlist)
self.update_processcount(processlist)
# Loop over processes and :
# - add extended stats for selected process
# - add metadata
for position, proc in enumerate(self.processlist):
for position, proc in enumerate(processlist):
# Extended stats
################
@ -480,7 +479,11 @@ class GlancesProcesses(object):
self.processlist_cache[proc['pid']] = {cached: proc[cached] for cached in cached_attrs}
# Apply user filter
self.processlist = list(filter(lambda p: not self._filter.is_filtered(p), self.processlist))
processlist = list(filter(lambda p: not self._filter.is_filtered(p), processlist))
# Save the new processlist and transform all namedtuples to dict
self.processlist = [{k: (v._asdict() if hasattr(v, '_asdict') else v)
for k, v in p.items()} for p in processlist]
# Compute the maximum value for keys in self._max_values_list: CPU, MEM
# Useful to highlight the processes with maximum values

View File

@ -136,7 +136,7 @@ class GlancesStats(object):
# Log plugins list
logger.debug("Active plugins list: {}".format(self.getPluginsList()))
def load_additional_plugins(self, args=None, config=None):
""" Load additional plugins if defined """
def get_addl_plugins(self, plugin_path):
@ -162,7 +162,7 @@ class GlancesStats(object):
if args and 'plugin_dir' in args and args.plugin_dir:
path = args.plugin_dir
if path:
# Get list before starting the counter
_sys_path = sys.path
@ -190,7 +190,7 @@ class GlancesStats(object):
sys.path = _sys_path
# Log plugins list
logger.debug("Active additional plugins list: {}".format(self.getPluginsList()))
def load_exports(self, args=None):
"""Load all exporters in the 'exports' folder."""
start_duration = Counter()

View File

@ -17,13 +17,14 @@ import time
import numbers
import unittest
from glances.outputs.glances_restful_api import GlancesRestfulApi
from glances import __version__
from glances.globals import text_type
import requests
SERVER_PORT = 61234
API_VERSION = 3
API_VERSION = GlancesRestfulApi.API_VERSION
URL = "http://localhost:{}/api/{}".format(SERVER_PORT, API_VERSION)
pid = None