mirror of
https://github.com/nicolargo/glances.git
synced 2025-01-03 23:26:01 +03:00
Optimize basic HTTP authentication
This commit is contained in:
parent
e27fd5f102
commit
3215bf5c63
479
docs/api.rst
479
docs/api.rst
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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('')
|
||||
|
@ -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 = {};
|
||||
|
2
glances/outputs/static/public/glances.js
vendored
2
glances/outputs/static/public/glances.js
vendored
File diff suppressed because one or more lines are too long
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user