Getting field information (description, unit) from the API #2630

This commit is contained in:
nicolargo 2023-12-22 18:32:24 +01:00
parent 380888a564
commit d75a8c193d
29 changed files with 1246 additions and 345 deletions

View File

@ -3,12 +3,22 @@
API (Restfull/JSON) documentation
=================================
This documentation describes the Glances API version 4 (Restfull/JSON) interface.
For Glances version 3, please have a look on:
``https://github.com/nicolargo/glances/blob/support/glancesv3/docs/api.rst``
Run the Glances API server
--------------------------
The Glances Restfull/API server could be ran using the following command line:
.. code-block:: bash
# glances -w --disable-webui
It is also ran automatically when Glances is started in Web server mode (-w).
API URL
-------
@ -30,10 +40,11 @@ For example:
will change the root API URL to ``http://localhost:61208/glances/api/4`` and the Web UI URL to
``http://localhost:61208/glances/``
API documentation
-----------------
API documentation URL
---------------------
The API documentation is available at the following URL: ``http://localhost:61208/docs#/``.
The API documentation is embeded in the server and available at the following URL:
``http://localhost:61208/docs#/``.
WebUI refresh
-------------
@ -98,14 +109,14 @@ GET alert
Get plugin stats::
# curl http://localhost:61208/api/4/alert
[[1702733581.0,
[[1703266291.0,
-1,
"WARNING",
"MEM",
80.72395821062744,
80.72395821062744,
80.72395821062744,
80.72395821062744,
79.30944396889095,
79.30944396889095,
79.30944396889095,
79.30944396889095,
1,
[],
"",
@ -125,7 +136,7 @@ Get plugin stats::
"refresh": 3.0,
"regex": True,
"result": None,
"timer": 0.30402588844299316},
"timer": 0.34033823013305664},
{"count": 0,
"countmax": 20.0,
"countmin": None,
@ -134,7 +145,17 @@ Get plugin stats::
"refresh": 3.0,
"regex": True,
"result": None,
"timer": 0.3038666248321533}]
"timer": 0.34007930755615234}]
Fields descriptions:
* **name**: AMP name (unit is *None*)
* **result**: AMP result (a string) (unit is *None*)
* **refresh**: AMP refresh interval (unit is *second*)
* **timer**: Time until next refresh (unit is *second*)
* **count**: Number of matching processes (unit is *number*)
* **countmin**: Minimum number of matching processes (unit is *number*)
* **countmax**: Maximum number of matching processes (unit is *number*)
Get a specific field::
@ -152,7 +173,7 @@ Get a specific item when field matches the given value::
"refresh": 3.0,
"regex": True,
"result": None,
"timer": 0.30402588844299316}]}
"timer": 0.34033823013305664}]}
GET connections
---------------
@ -162,6 +183,18 @@ Get plugin stats::
# curl http://localhost:61208/api/4/connections
{"net_connections_enabled": True, "nf_conntrack_enabled": True}
Fields descriptions:
* **LISTEN**: Number of TCP connections in LISTEN state (unit is *number*)
* **ESTABLISHED**: Number of TCP connections in ESTABLISHED state (unit is *number*)
* **SYN_SENT**: Number of TCP connections in SYN_SENT state (unit is *number*)
* **SYN_RECV**: Number of TCP connections in SYN_RECV state (unit is *number*)
* **initiated**: Number of TCP connections initiated (unit is *number*)
* **terminated**: Number of TCP connections terminated (unit is *number*)
* **nf_conntrack_count**: Number of tracked connections (unit is *number*)
* **nf_conntrack_max**: Maximum number of tracked connections (unit is *number*)
* **nf_conntrack_percent**: Percentage of tracked connections (unit is *percent*)
Get a specific field::
# curl http://localhost:61208/api/4/connections/net_connections_enabled
@ -173,73 +206,97 @@ GET containers
Get plugin stats::
# 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": "3 weeks",
"cpu": {"total": 0.0},
"cpu_percent": 0.0,
"engine": "docker",
"io": {"cumulative_ior": 1904640, "cumulative_iow": 2256896},
"io_r": None,
"io_w": None,
"key": "name",
"memory": {"cache": None,
"limit": 7823585280,
"max_usage": None,
"rss": None,
"usage": 13836288},
"memory_usage": 13836288,
"name": "portainer",
"network": {"cumulative_rx": 7106388, "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": "1 weeks",
"cpu": {"total": 6.604897042562196e-07},
"cpu_percent": 6.604897042562196e-07,
[{"command": "top",
"cpu": {"total": 1.2118984034342537e-06},
"cpu_percent": 1.2118984034342537e-06,
"created": "2023-12-09T10:45:34.339489876+01:00",
"engine": "podman",
"id": "481d6ffb7eef284d062628cf350bdd9ce0a803db8a2a505d75565ed24322b714",
"image": "docker.io/library/ubuntu:latest",
"io": {"ior": 0.0, "iow": 0.0, "time_since_update": 1},
"io_rx": 0.0,
"io_wx": 0.0,
"key": "name",
"memory": {"limit": 7823585280.0, "usage": 1388544.0},
"memory_usage": 1388544.0,
"name": "sad_darwin",
"network": {"rx": 0.0, "time_since_update": 1, "tx": 0.0},
"network_rx": 0.0,
"network_tx": 0.0,
"pod_id": "8d0f1c783def",
"pod_name": "sad_darwin",
"status": "running",
"uptime": "1 weeks"},
{"command": "",
"cpu": {"total": 3.3083493909342666e-10},
"cpu_percent": 3.3083493909342666e-10,
"created": "2022-10-22T14:23:03.120912374+02:00",
"engine": "podman",
"id": "9491515251edcd5bb5dc17205d7ee573c0be96fe0b08b0a12a7e2cea874565ea",
"image": "k8s.gcr.io/pause:3.5",
"io": {"ior": 0.0, "iow": 0.0, "time_since_update": 1},
"io_rx": 0.0,
"io_wx": 0.0,
"key": "name",
"memory": {"limit": 7823585280.0, "usage": 327680.0},
"memory_usage": 327680.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",
"status": "running",
"uptime": "1 weeks"}]
Fields descriptions:
* **name**: Container name (unit is *None*)
* **id**: Container ID (unit is *None*)
* **image**: Container image (unit is *None*)
* **status**: Container status (unit is *None*)
* **created**: Container creation date (unit is *None*)
* **command**: Container command (unit is *None*)
* **cpu_percent**: Container CPU consumption (unit is *percent*)
* **memory_usage**: Container memory usage (unit is *byte*)
* **io_rx**: Container IO bytes read rate (unit is *bytepersecond*)
* **io_wx**: Container IO bytes write rate (unit is *bytepersecond*)
* **network_rx**: Container network RX bitrate (unit is *bitpersecond*)
* **network_tx**: Container network TX bitrate (unit is *bitpersecond*)
* **uptime**: Container uptime (unit is *None*)
* **engine**: Container engine (Docker and Podman are currently supported) (unit is *None*)
* **pod_name**: Pod name (only with Podman) (unit is *None*)
* **pod_id**: Pod ID (only with Podman) (unit is *None*)
Get a specific field::
# curl http://localhost:61208/api/4/containers/name
{"name": ["sad_darwin", "8d0f1c783def-infra", "portainer"]}
Get a specific item when field matches the given value::
# curl http://localhost:61208/api/4/containers/name/sad_darwin
{"sad_darwin": [{"command": "top",
"cpu": {"total": 1.2118984034342537e-06},
"cpu_percent": 1.2118984034342537e-06,
"created": "2023-12-09T10:45:34.339489876+01:00",
"engine": "podman",
"id": "481d6ffb7eef284d062628cf350bdd9ce0a803db8a2a505d75565ed24322b714",
"image": "docker.io/library/ubuntu:latest",
"io": {"ior": 0.0, "iow": 0.0, "time_since_update": 1},
"io_r": 0.0,
"io_w": 0.0,
"io_rx": 0.0,
"io_wx": 0.0,
"key": "name",
"memory": {"limit": 7823585280.0, "usage": 1441792.0},
"memory_usage": 1441792.0,
"memory": {"limit": 7823585280.0, "usage": 1388544.0},
"memory_usage": 1388544.0,
"name": "sad_darwin",
"network": {"rx": 0.0, "time_since_update": 1, "tx": 0.0},
"network_rx": 0.0,
"network_tx": 0.0,
"pod_id": "8d0f1c783def",
"pod_name": "sad_darwin"},
{"Command": [],
"Created": "2022-10-22T14:23:03.120912374+02:00",
"Id": "9491515251edcd5bb5dc17205d7ee573c0be96fe0b08b0a12a7e2cea874565ea",
"Image": "["k8s.gcr.io/pause:3.5"]",
"Status": "running",
"Uptime": "1 weeks",
"cpu": {"total": 3.231862023627245e-10},
"cpu_percent": 3.231862023627245e-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": 368640.0},
"memory_usage": 368640.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"}],
"version": {},
"version_podman": {}}
"pod_name": "sad_darwin",
"status": "running",
"uptime": "1 weeks"}]}
GET core
--------
@ -269,24 +326,24 @@ Get plugin stats::
"ctx_switches": 0,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 73.7,
"idle": 56.4,
"interrupts": 0,
"iowait": 0.2,
"iowait": 0.5,
"irq": 0.0,
"nice": 0.0,
"soft_interrupts": 0,
"softirq": 0.0,
"steal": 0.0,
"syscalls": 0,
"system": 2.0,
"system": 13.7,
"time_since_update": 1,
"total": 26.2,
"user": 24.2}
"total": 43.1,
"user": 29.4}
Fields descriptions:
* **total**: Sum of all CPU percentages (except idle) (unit is *percent*)
* **system**: percent time spent in kernel space. System CPU time is the time spent running code in the Operating System kernel (unit is *percent*)
* **system**: Percent time spent in kernel space. System CPU time is the time spent running code in the Operating System kernel (unit is *percent*)
* **user**: CPU percent time spent in user space. User CPU time is the time spent on the processor running your program's code (or code in libraries) (unit is *percent*)
* **iowait**: *(Linux)*: percent time spent by the CPU waiting for I/O operations to complete (unit is *percent*)
* **dpc**: *(Windows)*: time spent servicing deferred procedure calls (DPCs) (unit is *percent*)
@ -304,7 +361,7 @@ Fields descriptions:
Get a specific field::
# curl http://localhost:61208/api/4/cpu/total
{"total": 26.2}
{"total": 43.1}
GET diskio
----------
@ -319,7 +376,8 @@ Get plugin stats::
"time_since_update": 1,
"write_bytes": 0,
"write_count": 0},
{"disk_name": "sda1",
{"alias": "InternalDisk",
"disk_name": "sda1",
"key": "disk_name",
"read_bytes": 0,
"read_count": 0,
@ -327,6 +385,15 @@ Get plugin stats::
"write_bytes": 0,
"write_count": 0}]
Fields descriptions:
* **disk_name**: Disk name (unit is *None*)
* **read_count**: Number of reads since last request (unit is *number*)
* **write_count**: Number of writes since last request (unit is *number*)
* **read_bytes**: Number of bytes read since last request (unit is *byte*)
* **write_bytes**: Number of bytes written since last request (unit is *byte*)
* **time_since_update**: Time since last request (unit is *second*)
Get a specific field::
# curl http://localhost:61208/api/4/diskio/disk_name
@ -349,14 +416,15 @@ GET fs
Get plugin stats::
# curl http://localhost:61208/api/4/fs
[{"device_name": "/dev/mapper/ubuntu--gnome--vg-root",
"free": 26169372672,
[{"alias": "Root",
"device_name": "/dev/mapper/ubuntu--gnome--vg-root",
"free": 25942876160,
"fs_type": "ext4",
"key": "mnt_point",
"mnt_point": "/",
"percent": 88.7,
"percent": 88.8,
"size": 243334156288,
"used": 204777328640},
"used": 205003825152},
{"device_name": "zsfpool",
"free": 31195136,
"fs_type": "zfs",
@ -366,6 +434,16 @@ Get plugin stats::
"size": 41811968,
"used": 10616832}]
Fields descriptions:
* **device_name**: Device name (unit is *None*)
* **fs_type**: File system type (unit is *None*)
* **mnt_point**: Mount point (unit is *None*)
* **size**: Total size (unit is *byte*)
* **used**: Used size (unit is *byte*)
* **free**: Free size (unit is *byte*)
* **percent**: File system usage in percent (unit is *percent*)
Get a specific field::
# curl http://localhost:61208/api/4/fs/mnt_point
@ -374,14 +452,15 @@ Get a specific field::
Get a specific item when field matches the given value::
# curl http://localhost:61208/api/4/fs/mnt_point//
{"/": [{"device_name": "/dev/mapper/ubuntu--gnome--vg-root",
"free": 26169372672,
{"/": [{"alias": "Root",
"device_name": "/dev/mapper/ubuntu--gnome--vg-root",
"free": 25942876160,
"fs_type": "ext4",
"key": "mnt_point",
"mnt_point": "/",
"percent": 88.7,
"percent": 88.8,
"size": 243334156288,
"used": 204777328640}]}
"used": 205003825152}]}
GET ip
------
@ -396,6 +475,15 @@ Get plugin stats::
"public_address": "92.151.148.66",
"public_info_human": ""}
Fields descriptions:
* **address**: Private IP address (unit is *None*)
* **mask**: Private IP mask (unit is *None*)
* **mask_cidr**: Private IP mask in CIDR format (unit is *number*)
* **gateway**: Private IP gateway (unit is *None*)
* **public_address**: Public IP address (unit is *None*)
* **public_info_human**: Public IP information (unit is *None*)
Get a specific field::
# curl http://localhost:61208/api/4/ip/gateway
@ -407,7 +495,10 @@ GET load
Get plugin stats::
# curl http://localhost:61208/api/4/load
{"cpucore": 4, "min1": 1.3134765625, "min15": 1.35009765625, "min5": 1.5234375}
{"cpucore": 4,
"min1": 2.26123046875,
"min15": 2.50341796875,
"min5": 2.59912109375}
Fields descriptions:
@ -419,7 +510,7 @@ Fields descriptions:
Get a specific field::
# curl http://localhost:61208/api/4/load/min1
{"min1": 1.3134765625}
{"min1": 2.26123046875}
GET mem
-------
@ -427,16 +518,16 @@ GET mem
Get plugin stats::
# curl http://localhost:61208/api/4/mem
{"active": 3005665280,
"available": 1508077568,
"buffers": 124248064,
"cached": 1833496576,
"free": 1508077568,
"inactive": 3188097024,
"percent": 80.7,
"shared": 559996928,
{"active": 3336941568,
"available": 1618743296,
"buffers": 94175232,
"cached": 1807302656,
"free": 1618743296,
"inactive": 3029139456,
"percent": 79.3,
"shared": 499687424,
"total": 7823585280,
"used": 6315507712}
"used": 6204841984}
Fields descriptions:
@ -463,13 +554,13 @@ GET memswap
Get plugin stats::
# curl http://localhost:61208/api/4/memswap
{"free": 4914995200,
"percent": 39.2,
"sin": 6458191872,
"sout": 11348365312,
{"free": 4660985856,
"percent": 42.3,
"sin": 8542650368,
"sout": 14097289216,
"time_since_update": 1,
"total": 8082419712,
"used": 3167424512}
"used": 3421433856}
Fields descriptions:
@ -493,9 +584,9 @@ Get plugin stats::
# curl http://localhost:61208/api/4/network
[{"alias": None,
"cumulative_cx": 1492376856,
"cumulative_rx": 746188428,
"cumulative_tx": 746188428,
"cumulative_cx": 1914532754,
"cumulative_rx": 957266377,
"cumulative_tx": 957266377,
"cx": 0,
"interface_name": "lo",
"is_up": True,
@ -504,15 +595,15 @@ Get plugin stats::
"speed": 0,
"time_since_update": 1,
"tx": 0},
{"alias": None,
"cumulative_cx": 5862371250,
"cumulative_rx": 5524324325,
"cumulative_tx": 338046925,
"cx": 224,
{"alias": "WIFI",
"cumulative_cx": 6798864423,
"cumulative_rx": 6350558377,
"cumulative_tx": 448306046,
"cx": 126,
"interface_name": "wlp2s0",
"is_up": True,
"key": "interface_name",
"rx": 98,
"rx": 0,
"speed": 0,
"time_since_update": 1,
"tx": 126}]
@ -521,13 +612,13 @@ Fields descriptions:
* **interface_name**: Interface name (unit is *string*)
* **alias**: Interface alias name (optional) (unit is *string*)
* **rx**: The received/input rate (in bit per second) (unit is *bps*)
* **tx**: The sent/output rate (in bit per second) (unit is *bps*)
* **cx**: The cumulative received+sent rate (in bit per second) (unit is *bps*)
* **cumulative_rx**: The number of bytes received through the interface (cumulative) (unit is *bytes*)
* **cumulative_tx**: The number of bytes sent through the interface (cumulative) (unit is *bytes*)
* **cumulative_cx**: The cumulative number of bytes reveived and sent through the interface (cumulative) (unit is *bytes*)
* **speed**: Maximum interface speed (in bit per second). Can return 0 on some operating-system (unit is *bps*)
* **rx**: The received/input rate (unit is *bitpersecond*)
* **tx**: The sent/output rate (unit is *bitpersecond*)
* **cx**: The cumulative received+sent rate (unit is *bitpersecond*)
* **cumulative_rx**: The number of bytes received through the interface (cumulative) (unit is *byte*)
* **cumulative_tx**: The number of bytes sent through the interface (cumulative) (unit is *byte*)
* **cumulative_cx**: The cumulative number of bytes reveived and sent through the interface (cumulative) (unit is *byte*)
* **speed**: Maximum interface speed (in bit per second). Can return 0 on some operating-system (unit is *bitpersecond*)
* **is_up**: Is the interface up ? (unit is *bool*)
* **time_since_update**: Number of seconds since last update (unit is *seconds*)
@ -546,9 +637,9 @@ Get a specific item when field matches the given value::
# curl http://localhost:61208/api/4/network/interface_name/lo
{"lo": [{"alias": None,
"cumulative_cx": 1492376856,
"cumulative_rx": 746188428,
"cumulative_tx": 746188428,
"cumulative_cx": 1914532754,
"cumulative_rx": 957266377,
"cumulative_tx": 957266377,
"cx": 0,
"interface_name": "lo",
"is_up": True,
@ -564,7 +655,7 @@ GET now
Get plugin stats::
# curl http://localhost:61208/api/4/now
"2023-12-16 14:33:01 CET"
"2023-12-22 18:31:31 CET"
GET percpu
----------
@ -575,29 +666,44 @@ Get plugin stats::
[{"cpu_number": 0,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 97.1,
"idle": 36.0,
"iowait": 0.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"steal": 0.0,
"system": 1.4,
"total": 2.9,
"user": 1.4},
"system": 8.0,
"total": 64.0,
"user": 6.0},
{"cpu_number": 1,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 96.4,
"idle": 33.0,
"iowait": 0.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"softirq": 1.0,
"steal": 0.0,
"system": 1.4,
"total": 3.6,
"user": 2.2}]
"system": 14.0,
"total": 67.0,
"user": 3.0}]
Fields descriptions:
* **cpu_number**: CPU number (unit is *None*)
* **total**: Sum of CPU percentages (except idle) for current CPU number (unit is *percent*)
* **system**: Percent time spent in kernel space. System CPU time is the time spent running code in the Operating System kernel (unit is *percent*)
* **user**: CPU percent time spent in user space. User CPU time is the time spent on the processor running your program's code (or code in libraries) (unit is *percent*)
* **iowait**: *(Linux)*: percent time spent by the CPU waiting for I/O operations to complete (unit is *percent*)
* **idle**: percent of CPU used by any program. Every program or task that runs on a computer system occupies a certain amount of processing time on the CPU. If the CPU has completed all tasks it is idle (unit is *percent*)
* **irq**: *(Linux and BSD)*: percent time spent servicing/handling hardware/software interrupts. Time servicing interrupts (hardware + software) (unit is *percent*)
* **nice**: *(Unix)*: percent time occupied by user level processes with a positive nice value. The time the CPU has spent running users' processes that have been *niced* (unit is *percent*)
* **steal**: *(Linux)*: percentage of time a virtual CPU waits for a real CPU while the hypervisor is servicing another virtual processor (unit is *percent*)
* **guest**: *(Linux)*: percent of time spent running a virtual CPU for guest operating systems under the control of the Linux kernel (unit is *percent*)
* **guest_nice**: *(Linux)*: percent of time spent running a niced guest (virtual CPU) (unit is *percent*)
* **softirq**: *(Linux)*: percent of time spent handling software interrupts (unit is *percent*)
Get a specific field::
@ -616,9 +722,20 @@ Get plugin stats::
"port": 0,
"refresh": 30,
"rtt_warning": None,
"status": 0.006756,
"status": 0.006345,
"timeout": 3}]
Fields descriptions:
* **host**: Measurement is be done on this host (or IP address) (unit is *None*)
* **port**: Measurement is be done on this port (0 for ICMP) (unit is *None*)
* **description**: Human readable description for the host/port (unit is *None*)
* **refresh**: Refresh time (in seconds) for this host/port (unit is *None*)
* **timeout**: Timeout (in seconds) for the measurement (unit is *None*)
* **status**: Measurement result (in seconds) (unit is *second*)
* **rtt_warning**: Warning threshold (in seconds) for the measurement (unit is *second*)
* **indice**: Unique indice for the host/port (unit is *None*)
Get a specific field::
# curl http://localhost:61208/api/4/ports/host
@ -633,7 +750,7 @@ Get a specific item when field matches the given value::
"port": 0,
"refresh": 30,
"rtt_warning": None,
"status": 0.006756,
"status": 0.006345,
"timeout": 3}]}
GET processcount
@ -642,12 +759,20 @@ GET processcount
Get plugin stats::
# curl http://localhost:61208/api/4/processcount
{"pid_max": 0, "running": 1, "sleeping": 325, "thread": 1793, "total": 390}
{"pid_max": 0, "running": 1, "sleeping": 316, "thread": 1568, "total": 387}
Fields descriptions:
* **total**: Total number of processes (unit is *number*)
* **running**: Total number of running processes (unit is *number*)
* **sleeping**: Total number of sleeping processes (unit is *number*)
* **thread**: Total number of threads (unit is *number*)
* **pid_max**: Maximum number of processes (unit is *number*)
Get a specific field::
# curl http://localhost:61208/api/4/processcount/total
{"total": 390}
{"total": 387}
GET psutilversion
-----------------
@ -663,69 +788,78 @@ GET quicklook
Get plugin stats::
# curl http://localhost:61208/api/4/quicklook
{"cpu": 26.2,
{"cpu": 43.1,
"cpu_hz": 2025000000.0,
"cpu_hz_current": 1973989250.0,
"cpu_hz_current": 1747194750.0,
"cpu_name": "Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz",
"mem": 80.7,
"mem": 79.3,
"percpu": [{"cpu_number": 0,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 97.1,
"idle": 36.0,
"iowait": 0.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"steal": 0.0,
"system": 1.4,
"total": 2.9,
"user": 1.4},
"system": 8.0,
"total": 64.0,
"user": 6.0},
{"cpu_number": 1,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 96.4,
"idle": 33.0,
"iowait": 0.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"softirq": 1.0,
"steal": 0.0,
"system": 1.4,
"total": 3.6,
"user": 2.2},
"system": 14.0,
"total": 67.0,
"user": 3.0},
{"cpu_number": 2,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 34.0,
"iowait": 0.7,
"idle": 3.0,
"iowait": 1.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"steal": 0.0,
"system": 2.1,
"total": 66.0,
"user": 63.1},
"system": 7.0,
"total": 97.0,
"user": 42.0},
{"cpu_number": 3,
"guest": 0.0,
"guest_nice": 0.0,
"idle": 67.4,
"idle": 43.0,
"iowait": 0.0,
"irq": 0.0,
"key": "cpu_number",
"nice": 0.0,
"softirq": 0.0,
"steal": 0.0,
"system": 2.9,
"total": 32.6,
"user": 29.7}],
"swap": 39.2}
"system": 1.0,
"total": 57.0,
"user": 9.0}],
"swap": 42.3}
Fields descriptions:
* **cpu**: CPU percent usage (unit is *percent*)
* **mem**: MEM percent usage (unit is *percent*)
* **swap**: SWAP percent usage (unit is *percent*)
* **cpu_name**: CPU name (unit is *None*)
* **cpu_hz_current**: CPU current frequency (unit is *hertz*)
* **cpu_hz**: CPU max frequency (unit is *hertz*)
Get a specific field::
# curl http://localhost:61208/api/4/quicklook/cpu
{"cpu": 26.2}
{"cpu": 43.1}
GET sensors
-----------
@ -748,6 +882,15 @@ Get plugin stats::
"value": 29,
"warning": 105}]
Fields descriptions:
* **label**: Sensor label (unit is *None*)
* **unit**: Sensor unit (unit is *None*)
* **value**: Sensor value (unit is *number*)
* **warning**: Warning threshold (unit is *number*)
* **critical**: Critical threshold (unit is *number*)
* **type**: Sensor type (one of battery, temperature_core, fan_speed) (unit is *None*)
Get a specific field::
# curl http://localhost:61208/api/4/sensors/label
@ -785,6 +928,15 @@ Get plugin stats::
"os_version": "5.15.0-88-generic",
"platform": "64bit"}
Fields descriptions:
* **os_name**: Operating system name (unit is *None*)
* **hostname**: Hostname (unit is *None*)
* **platform**: Platform (32 or 64 bits) (unit is *None*)
* **linux_distro**: Linux distribution (unit is *None*)
* **os_version**: Operating system version (unit is *None*)
* **hr_name**: Human readable operating sytem name (unit is *None*)
Get a specific field::
# curl http://localhost:61208/api/4/system/os_name
@ -796,7 +948,7 @@ GET uptime
Get plugin stats::
# curl http://localhost:61208/api/4/uptime
"21 days, 5:35:08"
"27 days, 9:33:37"
GET version
-----------
@ -847,19 +999,19 @@ Get top 2 processes of the processlist plugin::
"cpu_times": {"children_system": 0.0,
"children_user": 0.0,
"iowait": 0.0,
"system": 299.32,
"user": 3357.83},
"system": 388.27,
"user": 4330.13},
"gids": {"effective": 1000, "real": 1000, "saved": 1000},
"io_counters": [405289984, 0, 0, 0, 0],
"io_counters": [516647936, 0, 0, 0, 0],
"key": "pid",
"memory_info": {"data": 1191260160,
"memory_info": {"data": 1560563712,
"dirty": 0,
"lib": 0,
"rss": 482578432,
"shared": 50585600,
"rss": 786944000,
"shared": 53026816,
"text": 643072,
"vms": 3809882112},
"memory_percent": 6.16825169955839,
"vms": 4198535168},
"memory_percent": 10.05861087769724,
"name": "WebExtensions",
"nice": 0,
"num_threads": 20,
@ -867,68 +1019,85 @@ 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.12.1/dist/server.bundle.js",
"--cancellationReceive=file:810abd06604ca203178b3fa9390087012fbf550dba",
"--node-ipc",
"--clientProcessId=391253"],
"cpu_percent": 0.0,
"cpu_times": {"children_system": 965.5,
"children_user": 6851.05,
"cpu_times": {"children_system": 0.41,
"children_user": 4.19,
"iowait": 0.0,
"system": 2456.28,
"user": 8476.01},
"system": 237.34,
"user": 4002.03},
"gids": {"effective": 1000, "real": 1000, "saved": 1000},
"io_counters": [6493832192, 9773744128, 0, 0, 0],
"io_counters": [349560832, 1896448, 0, 0, 0],
"key": "pid",
"memory_info": {"data": 1300467712,
"memory_info": {"data": 875028480,
"dirty": 0,
"lib": 0,
"rss": 474091520,
"shared": 117129216,
"text": 643072,
"vms": 13574438912},
"memory_percent": 6.0597731478936465,
"name": "firefox",
"rss": 489472000,
"shared": 22188032,
"text": 120565760,
"vms": 1207768694784},
"memory_percent": 6.256364345529317,
"name": "code",
"nice": 0,
"num_threads": 147,
"pid": 7195,
"num_threads": 13,
"pid": 391817,
"status": "S",
"time_since_update": 1,
"username": "nicolargo"}]
Note: Only work for plugin with a list of items
GET item description of a specific plugin
-----------------------------------------
# curl http://localhost:61208/api/4/diskio/read_bytes/description
"Number of bytes read since last request."
GET item unit of a specific plugin
----------------------------------
# curl http://localhost:61208/api/4/diskio/read_bytes/unit
"byte"
GET stats history
-----------------
History of a plugin::
# curl http://localhost:61208/api/4/cpu/history
{"system": [["2023-12-16T14:33:03.105389", 2.0],
["2023-12-16T14:33:04.129951", 1.8],
["2023-12-16T14:33:05.327322", 1.8]],
"user": [["2023-12-16T14:33:03.105374", 24.2],
["2023-12-16T14:33:04.129938", 10.0],
["2023-12-16T14:33:05.327306", 10.0]]}
{"system": [["2023-12-22T18:31:33.164741", 13.7],
["2023-12-22T18:31:34.185713", 2.0],
["2023-12-22T18:31:35.412977", 2.0]],
"user": [["2023-12-22T18:31:33.164727", 29.4],
["2023-12-22T18:31:34.185705", 14.0],
["2023-12-22T18:31:35.412964", 14.0]]}
Limit history to last 2 values::
# curl http://localhost:61208/api/4/cpu/history/2
{"system": [["2023-12-16T14:33:04.129951", 1.8],
["2023-12-16T14:33:05.327322", 1.8]],
"user": [["2023-12-16T14:33:04.129938", 10.0],
["2023-12-16T14:33:05.327306", 10.0]]}
{"system": [["2023-12-22T18:31:34.185713", 2.0],
["2023-12-22T18:31:35.412977", 2.0]],
"user": [["2023-12-22T18:31:34.185705", 14.0],
["2023-12-22T18:31:35.412964", 14.0]]}
History for a specific field::
# curl http://localhost:61208/api/4/cpu/system/history
{"system": [["2023-12-16T14:33:01.240422", 2.0],
["2023-12-16T14:33:03.105389", 2.0],
["2023-12-16T14:33:04.129951", 1.8],
["2023-12-16T14:33:05.327322", 1.8]]}
{"system": [["2023-12-22T18:31:31.274678", 13.7],
["2023-12-22T18:31:33.164741", 13.7],
["2023-12-22T18:31:34.185713", 2.0],
["2023-12-22T18:31:35.412977", 2.0]]}
Limit history for a specific field to last 2 values::
# curl http://localhost:61208/api/4/cpu/system/history
{"system": [["2023-12-16T14:33:04.129951", 1.8],
["2023-12-16T14:33:05.327322", 1.8]]}
{"system": [["2023-12-22T18:31:34.185713", 2.0],
["2023-12-22T18:31:35.412977", 2.0]]}
GET limits (used for thresholds)
--------------------------------
@ -966,11 +1135,13 @@ All limits/thresholds::
"cpu_user_log": ["False"],
"cpu_user_warning": 70.0,
"history_size": 1200.0},
"diskio": {"diskio_disable": ["False"],
"diskio": {"diskio_alias": ["sda1:InternalDisk", "sdb1:ExternalDisk"],
"diskio_disable": ["False"],
"diskio_hide": ["loop.*", "/dev/loop.*"],
"history_size": 1200.0},
"folders": {"folders_disable": ["False"], "history_size": 1200.0},
"fs": {"fs_careful": 50.0,
"fs": {"fs_alias": ["/:Root"],
"fs_careful": 50.0,
"fs_critical": 90.0,
"fs_disable": ["False"],
"fs_hide": ["/boot.*", "/snap.*"],
@ -1009,6 +1180,7 @@ All limits/thresholds::
"memswap_disable": ["False"],
"memswap_warning": 70.0},
"network": {"history_size": 1200.0,
"network_alias": ["wlp2s0:WIFI"],
"network_disable": ["False"],
"network_rx_careful": 70.0,
"network_rx_critical": 90.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 16, 2023" "4.0.0_beta01" "Glances"
.TH "GLANCES" "1" "Dec 22, 2023" "4.0.0_beta01" "Glances"
.SH NAME
glances \- An eye on your system
.SH SYNOPSIS

View File

@ -394,20 +394,20 @@ def folder_size(path, errno=0):
ret_size = 0
ret_err = errno
try:
f_list = os.scandir(path)
for f in os.scandir(path):
if f.is_dir(follow_symlinks=False) and (f.name != '.' or f.name != '..'):
ret = folder_size(os.path.join(path, f.name), ret_err)
ret_size += ret[0]
ret_err = ret[1]
else:
try:
ret_size += f.stat().st_size
except OSError as e:
ret_err = e.errno
except OSError as e:
return 0, e.errno
for f in f_list:
if f.is_dir(follow_symlinks=False) and (f.name != '.' or f.name != '..'):
ret = folder_size(os.path.join(path, f.name), ret_err)
ret_size += ret[0]
ret_err = ret[1]
else:
try:
ret_size += f.stat().st_size
except OSError as e:
ret_err = e.errno
return ret_size, ret_err
else:
return ret_size, ret_err
def weak_lru_cache(maxsize=128, typed=False):

View File

@ -217,6 +217,16 @@ class GlancesRestfulApi(object):
response_class=ORJSONResponse,
endpoint=self._api_item_history,
)
router.add_api_route(
'/api/%s/{plugin}/{item}/description' % self.API_VERSION,
response_class=ORJSONResponse,
endpoint=self._api_item_description,
)
router.add_api_route(
'/api/%s/{plugin}/{item}/unit' % self.API_VERSION,
response_class=ORJSONResponse,
endpoint=self._api_item_unit,
)
router.add_api_route(
'/api/%s/{plugin}/{item}/{value}' % self.API_VERSION,
response_class=ORJSONResponse,
@ -598,8 +608,58 @@ class GlancesRestfulApi(object):
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Cannot get history for plugin %s (%s)" % (plugin, str(e))
)
else:
return ORJSONResponse(ret)
return ORJSONResponse(ret)
def _api_item_description(self, plugin, item):
"""Glances API RESTful implementation.
Return the JSON representation of the couple plugin/item description
HTTP/200 if OK
HTTP/400 if plugin is not found
HTTP/404 if others error
"""
if plugin not in self.plugins_list:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Unknown plugin %s (available plugins: %s)" % (plugin, self.plugins_list),
)
try:
# Get the description
ret = self.stats.get_plugin(plugin).get_item_info(item, 'description')
except Exception as e:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Cannot get %s description for plugin %s (%s)" % (item, plugin, str(e)),
)
else:
return ORJSONResponse(ret)
def _api_item_unit(self, plugin, item):
"""Glances API RESTful implementation.
Return the JSON representation of the couple plugin/item unit
HTTP/200 if OK
HTTP/400 if plugin is not found
HTTP/404 if others error
"""
if plugin not in self.plugins_list:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Unknown plugin %s (available plugins: %s)" % (plugin, self.plugins_list),
)
try:
# Get the unit
ret = self.stats.get_plugin(plugin).get_item_info(item, 'unit')
except Exception as e:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Cannot get %s unit for plugin %s (%s)" % (item, plugin, str(e)),
)
else:
return ORJSONResponse(ret)
def _api_value(self, plugin, item, value):
"""Glances API RESTful implementation.
@ -626,8 +686,8 @@ class GlancesRestfulApi(object):
status_code=status.HTTP_404_NOT_FOUND,
detail="Cannot get %s = %s for plugin %s (%s)" % (item, value, plugin, str(e)),
)
return ORJSONResponse(ret)
else:
return ORJSONResponse(ret)
def _api_config(self):
"""Glances API RESTful implementation.
@ -641,8 +701,8 @@ class GlancesRestfulApi(object):
args_json = self.config.as_dict()
except Exception as e:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Cannot get config (%s)" % str(e))
return ORJSONResponse(args_json)
else:
return ORJSONResponse(args_json)
def _api_config_section(self, section):
"""Glances API RESTful implementation.

View File

@ -26,12 +26,22 @@ APIDOC_HEADER = """\
API (Restfull/JSON) documentation
=================================
This documentation describes the Glances API version {api_version} (Restfull/JSON) interface.
For Glances version 3, please have a look on:
``https://github.com/nicolargo/glances/blob/support/glancesv3/docs/api.rst``
Run the Glances API server
--------------------------
The Glances Restfull/API server could be ran using the following command line:
.. code-block:: bash
# glances -w --disable-webui
It is also ran automatically when Glances is started in Web server mode (-w).
API URL
-------
@ -53,10 +63,11 @@ For example:
will change the root API URL to ``http://localhost:61208/glances/api/{api_version}`` and the Web UI URL to
``http://localhost:61208/glances/``
API documentation
-----------------
API documentation URL
---------------------
The API documentation is available at the following URL: ``http://localhost:61208/docs#/``.
The API documentation is embeded in the server and available at the following URL:
``http://localhost:61208/docs#/``.
WebUI refresh
-------------
@ -130,7 +141,9 @@ def print_plugin_description(plugin, stat):
description['description'][:-1]
if description['description'].endswith('.')
else description['description'],
description['unit'],
description['unit']
if 'unit' in description
else 'None'
)
)
print('')
@ -196,6 +209,23 @@ def print_top(stats):
print('')
def print_fields_info(stats):
sub_title = 'GET item description of a specific plugin'
print(sub_title)
print('-' * len(sub_title))
print('')
print(' # curl {}/diskio/read_bytes/description'.format(API_URL))
print(indent_stat(stats.get_plugin('diskio').get_item_info('read_bytes', 'description')))
print('')
sub_title = 'GET item unit of a specific plugin'
print(sub_title)
print('-' * len(sub_title))
print('')
print(' # curl {}/diskio/read_bytes/unit'.format(API_URL))
print(indent_stat(stats.get_plugin('diskio').get_item_info('read_bytes', 'unit')))
print('')
def print_history(stats):
time.sleep(1)
stats.update()
@ -285,6 +315,9 @@ class GlancesStdoutApiDoc(object):
# Example for processlist plugin: get top 2 processes
print_top(stats)
# Fields description
print_fields_info(stats)
# History
print_history(stats)

View File

@ -60,16 +60,16 @@
{{ $filters.bytes(container.limit) }}
</div>
<div class="table-cell">
{{ $filters.bits(container.ior / container.io_time_since_update) }}
{{ $filters.bytes(container.io_rx) }}
</div>
<div class="table-cell">
{{ $filters.bits(container.iow / container.io_time_since_update) }}
{{ $filters.bytes(container.io_wx) }}
</div>
<div class="table-cell">
{{ $filters.bits(container.rx / container.net_time_since_update) }}
{{ $filters.bits(container.network_rx) }}
</div>
<div class="table-cell">
{{ $filters.bits(container.tx / container.net_time_since_update) }}
{{ $filters.bits(container.network_tx) }}
</div>
<div class="table-cell text-left">
{{ container.command }}
@ -107,25 +107,23 @@ export default {
},
containers() {
const { sorter } = this;
const containers = ((this.stats && this.stats.containers) || []).map(
const containers = (this.stats || []).map(
(containerData) => {
// prettier-ignore
return {
'id': containerData.Id,
'id': containerData.id,
'name': containerData.name,
'status': containerData.Status,
'uptime': containerData.Uptime,
'status': containerData.status,
'uptime': containerData.uptime,
'cpu_percent': containerData.cpu.total,
'memory_usage': containerData.memory.usage != undefined ? containerData.memory.usage : '?',
'limit': containerData.memory.limit != undefined ? containerData.memory.limit : '?',
'ior': containerData.io.ior != undefined ? containerData.io.ior : '?',
'iow': containerData.io.iow != undefined ? containerData.io.iow : '?',
'io_time_since_update': containerData.io.time_since_update,
'rx': containerData.network.rx != undefined ? containerData.network.rx : '?',
'tx': containerData.network.tx != undefined ? containerData.network.tx : '?',
'net_time_since_update': containerData.network.time_since_update,
'command': containerData.Command.join(' '),
'image': containerData.Image,
'io_rx': containerData.io_rx != undefined ? containerData.io_rx : '?',
'io_wx': containerData.io_wx != undefined ? containerData.io_wx : '?',
'network_rx': containerData.network_rx != undefined ? containerData.network_rx : '?',
'network_tx': containerData.network_tx != undefined ? containerData.network_tx : '?',
'command': containerData.command,
'image': containerData.image,
'engine': containerData.engine,
'pod_id': containerData.pod_id
};

View File

@ -19,7 +19,7 @@
<div class="table-cell" v-if="mean.mem == null">N/A</div>
</div>
<div class="table-row" v-if="args.meangpu || gpus.length === 1">
<div class="table-cell text-left">temperature::</div>
<div class="table-cell text-left">temperature:</div>
<div
class="table-cell"
:class="getMeanDecoration('temperature')"

File diff suppressed because one or more lines are too long

View File

@ -13,13 +13,53 @@ from glances.globals import iteritems
from glances.amps_list import AmpsList as glancesAmpsList
from glances.plugins.plugin.model import GlancesPluginModel
# Fields description
# description: human readable description
# short_name: shortname to use un UI
# unit: unit type
# rate: is it a rate ? If yes, // by time_since_update when displayed,
# min_symbol: Auto unit should be used if value > than 1 'X' (K, M, G)...
fields_description = {
'name': {
'description': 'AMP name.'
},
'result': {
'description': 'AMP result (a string).'
},
'refresh': {
'description': 'AMP refresh interval.',
'unit': 'second'
},
'timer': {
'description': 'Time until next refresh.',
'unit': 'second'
},
'count': {
'description': 'Number of matching processes.',
'unit': 'number'
},
'countmin': {
'description': 'Minimum number of matching processes.',
'unit': 'number'
},
'countmax': {
'description': 'Maximum number of matching processes.',
'unit': 'number'
},
}
class PluginModel(GlancesPluginModel):
"""Glances AMPs plugin."""
def __init__(self, args=None, config=None):
"""Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config, stats_init_value=[])
super(PluginModel, self).__init__(
args=args,
config=config,
stats_init_value=[],
fields_description=fields_description
)
self.args = args
self.config = config

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,6 +16,51 @@ from glances.globals import nativestr
import psutil
# Fields description
# description: human readable description
# short_name: shortname to use un UI
# unit: unit type
# rate: is it a rate ? If yes, // by time_since_update when displayed,
# min_symbol: Auto unit should be used if value > than 1 'X' (K, M, G)...
fields_description = {
'LISTEN': {
'description': 'Number of TCP connections in LISTEN state',
'unit': 'number',
},
'ESTABLISHED': {
'description': 'Number of TCP connections in ESTABLISHED state',
'unit': 'number',
},
'SYN_SENT': {
'description': 'Number of TCP connections in SYN_SENT state',
'unit': 'number',
},
'SYN_RECV': {
'description': 'Number of TCP connections in SYN_RECV state',
'unit': 'number',
},
'initiated': {
'description': 'Number of TCP connections initiated',
'unit': 'number',
},
'terminated': {
'description': 'Number of TCP connections terminated',
'unit': 'number',
},
'nf_conntrack_count': {
'description': 'Number of tracked connections',
'unit': 'number',
},
'nf_conntrack_max': {
'description': 'Maximum number of tracked connections',
'unit': 'number',
},
'nf_conntrack_percent': {
'description': 'Percentage of tracked connections',
'unit': 'percent',
},
}
# Define the history items list
# items_history_list = [{'name': 'rx',
# 'description': 'Download rate per second',
@ -53,6 +98,7 @@ class PluginModel(GlancesPluginModel):
config=config,
# items_history_list=items_history_list,
stats_init_value={'net_connections_enabled': True, 'nf_conntrack_enabled': True},
fields_description=fields_description
)
# We want to display the stat in the curse interface

View File

@ -19,6 +19,69 @@ from glances.plugins.plugin.model import GlancesPluginModel
from glances.processes import glances_processes
from glances.processes import sort_stats as sort_stats_processes
# Fields description
# description: human readable description
# short_name: shortname to use un UI
# unit: unit type
# rate: is it a rate ? If yes, // by time_since_update when displayed,
# min_symbol: Auto unit should be used if value > than 1 'X' (K, M, G)...
fields_description = {
'name': {
'description': 'Container name',
},
'id': {
'description': 'Container ID',
},
'image': {
'description': 'Container image',
},
'status': {
'description': 'Container status',
},
'created': {
'description': 'Container creation date',
},
'command': {
'description': 'Container command',
},
'cpu_percent': {
'description': 'Container CPU consumption',
'unit': 'percent',
},
'memory_usage': {
'description': 'Container memory usage',
'unit': 'byte',
},
'io_rx': {
'description': 'Container IO bytes read rate',
'unit': 'bytepersecond',
},
'io_wx': {
'description': 'Container IO bytes write rate',
'unit': 'bytepersecond',
},
'network_rx': {
'description': 'Container network RX bitrate',
'unit': 'bitpersecond',
},
'network_tx': {
'description': 'Container network TX bitrate',
'unit': 'bitpersecond',
},
'uptime': {
'description': 'Container uptime',
},
'engine': {
'description': 'Container engine (Docker and Podman are currently supported)',
},
'pod_name': {
'description': 'Pod name (only with Podman)',
},
'pod_id': {
'description': 'Pod ID (only with Podman)',
},
}
# Define the items history list (list of items to add to history)
# TODO: For the moment limited to the CPU. Had to change the graph exports
# method to display one graph per container.
@ -64,7 +127,11 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None):
"""Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config, items_history_list=items_history_list)
super(PluginModel, self).__init__(
args=args, config=config,
items_history_list=items_history_list,
fields_description=fields_description
)
# The plugin can be disabled using: args.disable_docker
self.args = args
@ -122,7 +189,7 @@ class PluginModel(GlancesPluginModel):
- The key is the first container name
"""
try:
ret = deepcopy(self.stats['containers'])
ret = deepcopy(self.stats)
except KeyError as e:
logger.debug("docker plugin - Docker export error {}".format(e))
ret = []
@ -159,11 +226,7 @@ class PluginModel(GlancesPluginModel):
# Update stats
stats_docker = self.update_docker() if self.docker_extension else {}
stats_podman = self.update_podman() if self.podman_client else {}
stats = {
'version': stats_docker.get('version', {}),
'version_podman': stats_podman.get('version', {}),
'containers': stats_docker.get('containers', []) + stats_podman.get('containers', []),
}
stats = stats_docker.get('containers', []) + stats_podman.get('containers', [])
elif self.input_method == 'snmp':
# Update stats using SNMP
# Not available
@ -193,24 +256,17 @@ class PluginModel(GlancesPluginModel):
"""Return the user ticks by reading the environment variable."""
return os.sysconf(os.sysconf_names['SC_CLK_TCK'])
def get_stats_action(self):
"""Return stats for the action.
Docker will return self.stats['containers']
"""
return self.stats['containers']
def update_views(self):
"""Update stats views."""
# Call the father's method
super(PluginModel, self).update_views()
if 'containers' not in self.stats:
if not self.stats:
return False
# Add specifics information
# Alert
for i in self.stats['containers']:
for i in self.stats:
# Init the views for the current container (key = container name)
self.views[i[self.get_key()]] = {'cpu': {}, 'mem': {}}
# CPU alert
@ -240,27 +296,25 @@ class PluginModel(GlancesPluginModel):
ret = []
# Only process if stats exist (and non null) and display plugin enable...
if not self.stats or 'containers' not in self.stats or len(self.stats['containers']) == 0 or self.is_disabled():
if not self.stats or len(self.stats) == 0 or self.is_disabled():
return ret
show_pod_name = False
if any(ct.get("pod_name") for ct in self.stats["containers"]):
if any(ct.get("pod_name") for ct in self.stats):
show_pod_name = True
show_engine_name = False
if len(set(ct["engine"] for ct in self.stats["containers"])) > 1:
if len(set(ct["engine"] for ct in self.stats)) > 1:
show_engine_name = True
# Build the string message
# Title
msg = '{}'.format('CONTAINERS')
ret.append(self.curse_add_line(msg, "TITLE"))
msg = ' {}'.format(len(self.stats['containers']))
msg = ' {}'.format(len(self.stats))
ret.append(self.curse_add_line(msg))
msg = ' sorted by {}'.format(sort_for_human[self.sort_key])
ret.append(self.curse_add_line(msg))
# msg = ' (served by Docker {})'.format(self.stats['version']["Version"])
# ret.append(self.curse_add_line(msg))
ret.append(self.curse_new_line())
# Header
ret.append(self.curse_new_line())
@ -268,7 +322,7 @@ class PluginModel(GlancesPluginModel):
# Max size is configurable. See feature request #1723.
name_max_width = min(
self.config.get_int_value('containers', 'max_name_size', default=20) if self.config is not None else 20,
len(max(self.stats['containers'], key=lambda x: len(x['name']))['name']),
len(max(self.stats, key=lambda x: len(x['name']))['name']),
)
if show_engine_name:
@ -301,7 +355,7 @@ class PluginModel(GlancesPluginModel):
ret.append(self.curse_add_line(msg))
# Data
for container in self.stats['containers']:
for container in self.stats:
ret.append(self.curse_new_line())
if show_engine_name:
ret.append(self.curse_add_line(' {:{width}}'.format(container["engine"], width=6)))
@ -310,12 +364,12 @@ class PluginModel(GlancesPluginModel):
# Name
ret.append(self.curse_add_line(self._msg_name(container=container, max_width=name_max_width)))
# Status
status = self.container_alert(container['Status'])
msg = '{:>10}'.format(container['Status'][0:10])
status = self.container_alert(container['status'])
msg = '{:>10}'.format(container['status'][0:10])
ret.append(self.curse_add_line(msg, status))
# Uptime
if container['Uptime']:
msg = '{:>10}'.format(container['Uptime'])
if container['uptime']:
msg = '{:>10}'.format(container['uptime'])
else:
msg = '{:>10}'.format('_')
ret.append(self.curse_add_line(msg))
@ -339,13 +393,13 @@ class PluginModel(GlancesPluginModel):
# IO R/W
unit = 'B'
try:
value = self.auto_unit(int(container['io']['ior'] // container['io']['time_since_update'])) + unit
value = self.auto_unit(int(container['io_rx'])) + unit
msg = '{:>7}'.format(value)
except KeyError:
msg = '{:>7}'.format('_')
ret.append(self.curse_add_line(msg))
try:
value = self.auto_unit(int(container['io']['iow'] // container['io']['time_since_update'])) + unit
value = self.auto_unit(int(container['io_wx'])) + unit
msg = ' {:<7}'.format(value)
except KeyError:
msg = ' {:<7}'.format('_')
@ -362,7 +416,7 @@ class PluginModel(GlancesPluginModel):
try:
value = (
self.auto_unit(
int(container['network']['rx'] // container['network']['time_since_update'] * to_bit)
int(container['network_rx'] * to_bit)
)
+ unit
)
@ -373,7 +427,7 @@ class PluginModel(GlancesPluginModel):
try:
value = (
self.auto_unit(
int(container['network']['tx'] // container['network']['time_since_update'] * to_bit)
int(container['network_tx'] * to_bit)
)
+ unit
)
@ -382,8 +436,8 @@ class PluginModel(GlancesPluginModel):
msg = ' {:<7}'.format('_')
ret.append(self.curse_add_line(msg))
# Command
if container['Command'] is not None:
msg = ' {}'.format(' '.join(container['Command']))
if container['command'] is not None:
msg = ' {}'.format(container['command'])
else:
msg = ' {}'.format('_')
ret.append(self.curse_add_line(msg, splittable=True))
@ -419,7 +473,7 @@ def sort_docker_stats(stats):
# Sort docker stats
sort_stats_processes(
stats['containers'],
stats,
sorted_by=sort_by,
sorted_by_secondary=sort_by_secondary,
# Reverse for all but name

View File

@ -295,28 +295,28 @@ class DockerContainersExtension:
# Export name
'name': nativestr(container.name),
# Container Id
'Id': container.id,
'id': container.id,
# Container Status (from attrs)
'Status': container.attrs['State']['Status'],
'Created': container.attrs['Created'],
'Command': [],
'status': container.attrs['State']['Status'],
'created': container.attrs['Created'],
'command': [],
}
# Container Image
try:
# API fails on Unraid - See issue 2233
stats['Image'] = container.image.tags
stats['image'] = ','.join(container.image.tags if container.image.tags else []),
except requests.exceptions.HTTPError:
stats['Image'] = '-'
stats['image'] = ''
if container.attrs['Config'].get('Entrypoint', None):
stats['Command'].extend(container.attrs['Config'].get('Entrypoint', []))
stats['command'].extend(container.attrs['Config'].get('Entrypoint', []))
if container.attrs['Config'].get('Cmd', None):
stats['Command'].extend(container.attrs['Config'].get('Cmd', []))
if not stats['Command']:
stats['Command'] = None
stats['command'].extend(container.attrs['Config'].get('Cmd', []))
if not stats['command']:
stats['command'] = None
if stats['Status'] in self.CONTAINER_ACTIVE_STATUS:
if stats['status'] in self.CONTAINER_ACTIVE_STATUS:
started_at = container.attrs['State']['StartedAt']
stats_fetcher = self.stats_fetchers[container.id]
activity_stats = stats_fetcher.activity_stats
@ -327,22 +327,25 @@ class DockerContainersExtension:
stats['memory_usage'] = stats["memory"].get('usage')
if stats['memory'].get('cache') is not None:
stats['memory_usage'] -= stats['memory']['cache']
stats['io_r'] = stats['io'].get('ior')
stats['io_w'] = stats['io'].get('iow')
stats['network_rx'] = stats['network'].get('rx')
stats['network_tx'] = stats['network'].get('tx')
stats['Uptime'] = pretty_date(parser.parse(started_at).astimezone(tz.tzlocal()).replace(tzinfo=None))
if 'time_since_update' in stats['io']:
stats['io_rx'] = stats['io'].get('ior') // stats['io'].get('time_since_update')
stats['io_wx'] = stats['io'].get('iow') // stats['io'].get('time_since_update')
if 'time_since_update' in stats['network']:
stats['network_rx'] = stats['network'].get('rx') // stats['network'].get('time_since_update')
stats['network_tx'] = stats['network'].get('tx') // stats['network'].get('time_since_update')
stats['uptime'] = pretty_date(parser.parse(started_at).astimezone(tz.tzlocal()).replace(tzinfo=None))
stats['command'] = ' '.join(stats['command'])
else:
stats['io'] = {}
stats['cpu'] = {}
stats['memory'] = {}
stats['network'] = {}
stats['io_r'] = None
stats['io_w'] = None
stats['io_rx'] = None
stats['io_wx'] = None
stats['cpu_percent'] = None
stats['memory_percent'] = None
stats['network_rx'] = None
stats['network_tx'] = None
stats['Uptime'] = None
stats['uptime'] = None
return stats

View File

@ -71,7 +71,8 @@ class PodmanContainerStatsFetcher:
ior = float(api_stats["BlockInput"])
iow = float(api_stats["BlockOutput"])
# Hardcode `time_since_update` to 1 as podman already sends the calculated rate
# Hardcode `time_since_update` to 1 as podman
# already sends the calculated rate per second
result_stats = {
"cpu": {"total": cpu_usage},
"memory": {"usage": mem_usage, "limit": mem_limit},
@ -290,9 +291,9 @@ class PodmanContainersExtension:
pod_stats = self.pods_stats_fetcher.activity_stats
for stats in container_stats:
if stats["Id"][:12] in pod_stats:
stats["pod_name"] = pod_stats[stats["Id"][:12]]["name"]
stats["pod_id"] = pod_stats[stats["Id"][:12]]["pod_id"]
if stats["id"][:12] in pod_stats:
stats["pod_name"] = pod_stats[stats["id"][:12]]["name"]
stats["pod_id"] = pod_stats[stats["id"][:12]]["pod_id"]
return version_stats, container_stats
@ -308,16 +309,16 @@ class PodmanContainersExtension:
# Export name
'name': nativestr(container.name),
# Container Id
'Id': container.id,
'id': container.id,
# Container Image
'Image': str(container.image.tags),
'image': ','.join(container.image.tags if container.image.tags else []),
# Container Status (from attrs)
'Status': container.attrs['State'],
'Created': container.attrs['Created'],
'Command': container.attrs.get('Command') or [],
'status': container.attrs['State'],
'created': container.attrs['Created'],
'command': container.attrs.get('Command') or [],
}
if stats['Status'] in self.CONTAINER_ACTIVE_STATUS:
if stats['status'] in self.CONTAINER_ACTIVE_STATUS:
started_at = datetime.fromtimestamp(container.attrs['StartedAt'])
stats_fetcher = self.container_stats_fetchers[container.id]
activity_stats = stats_fetcher.activity_stats
@ -328,22 +329,23 @@ class PodmanContainersExtension:
stats['memory_usage'] = stats["memory"].get('usage')
if stats['memory'].get('cache') is not None:
stats['memory_usage'] -= stats['memory']['cache']
stats['io_r'] = stats['io'].get('ior')
stats['io_w'] = stats['io'].get('iow')
stats['network_rx'] = stats['network'].get('rx')
stats['network_tx'] = stats['network'].get('tx')
stats['Uptime'] = pretty_date(started_at)
stats['io_rx'] = stats['io'].get('ior') // stats['io'].get('time_since_update')
stats['io_wx'] = stats['io'].get('iow') // stats['io'].get('time_since_update')
stats['network_rx'] = stats['network'].get('rx') // stats['network'].get('time_since_update')
stats['network_tx'] = stats['network'].get('tx') // stats['network'].get('time_since_update')
stats['uptime'] = pretty_date(started_at)
stats['command'] = ' '.join(stats['command'])
else:
stats['io'] = {}
stats['cpu'] = {}
stats['memory'] = {}
stats['network'] = {}
stats['io_r'] = None
stats['io_w'] = None
stats['io_rx'] = None
stats['io_wx'] = None
stats['cpu_percent'] = None
stats['memory_percent'] = None
stats['network_rx'] = None
stats['network_tx'] = None
stats['Uptime'] = None
stats['uptime'] = None
return stats

View File

@ -24,9 +24,12 @@ import psutil
# rate: is it a rate ? If yes, // by time_since_update when displayed,
# min_symbol: Auto unit should be used if value > than 1 'X' (K, M, G)...
fields_description = {
'total': {'description': 'Sum of all CPU percentages (except idle).', 'unit': 'percent'},
'total': {
'description': 'Sum of all CPU percentages (except idle).',
'unit': 'percent'
},
'system': {
'description': 'percent time spent in kernel space. System CPU time is the \
'description': 'Percent time spent in kernel space. System CPU time is the \
time spent running code in the Operating System kernel.',
'unit': 'percent',
},
@ -141,7 +144,9 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None):
"""Init the CPU plugin."""
super(PluginModel, self).__init__(
args=args, config=config, items_history_list=items_history_list, fields_description=fields_description
args=args, config=config,
items_history_list=items_history_list,
fields_description=fields_description
)
# We want to display the stat in the curse interface

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
#
@ -17,6 +17,37 @@ from glances.plugins.plugin.model import GlancesPluginModel
import psutil
# Fields description
# description: human readable description
# short_name: shortname to use un UI
# unit: unit type
# rate: is it a rate ? If yes, // by time_since_update when displayed,
# min_symbol: Auto unit should be used if value > than 1 'X' (K, M, G)...
fields_description = {
'disk_name': {
'description': 'Disk name.'
},
'read_count': {
'description': 'Number of reads since last request.',
'unit': 'number',
},
'write_count': {
'description': 'Number of writes since last request.',
'unit': 'number',
},
'read_bytes': {
'description': 'Number of bytes read since last request.',
'unit': 'byte',
},
'write_bytes': {
'description': 'Number of bytes written since last request.',
'unit': 'byte',
},
'time_since_update': {
'description': 'Time since last request.',
'unit': 'second',
},
}
# Define the history items list
items_history_list = [
@ -34,7 +65,10 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None):
"""Init the plugin."""
super(PluginModel, self).__init__(
args=args, config=config, items_history_list=items_history_list, stats_init_value=[]
args=args, config=config,
items_history_list=items_history_list,
stats_init_value=[],
fields_description=fields_description
)
# We want to display the stat in the curse interface
@ -69,8 +103,6 @@ class PluginModel(GlancesPluginModel):
# write_count: number of writes
# read_bytes: number of bytes read
# write_bytes: number of bytes written
# read_time: time spent reading from disk (in milliseconds)
# write_time: time spent writing to disk (in milliseconds)
try:
diskio = psutil.disk_io_counters(perdisk=True)
except Exception:

View File

@ -16,12 +16,54 @@ from glances.folder_list import FolderList as glancesFolderList
from glances.plugins.plugin.model import GlancesPluginModel
# Fields description
# description: human readable description
# short_name: shortname to use un UI
# unit: unit type
# rate: is it a rate ? If yes, // by time_since_update when displayed,
# min_symbol: Auto unit should be used if value > than 1 'X' (K, M, G)...
fields_description = {
'path': {
'description': 'Absolute path.'
},
'size': {
'description': 'Folder size in bytes.',
'unit': 'byte',
},
'refresh': {
'description': 'Refresh interval in seconds.',
'unit': 'second',
},
'errno': {
'description': 'Return code when retrieving folder size (0 is no error).',
'unit': 'number',
},
'careful': {
'description': 'Careful threshold in MB.',
'unit': 'megabyte',
},
'warning': {
'description': 'Warning threshold in MB.',
'unit': 'megabyte',
},
'critical': {
'description': 'Critical threshold in MB.',
'unit': 'megabyte',
},
}
class PluginModel(GlancesPluginModel):
"""Glances folder plugin."""
def __init__(self, args=None, config=None):
"""Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config, stats_init_value=[])
super(PluginModel, self).__init__(
args=args, config=config,
stats_init_value=[],
fields_description=fields_description
)
self.args = args
self.config = config

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
#
@ -18,6 +18,40 @@ from glances.plugins.plugin.model import GlancesPluginModel
import psutil
# Fields description
# description: human readable description
# short_name: shortname to use un UI
# unit: unit type
# rate: is it a rate ? If yes, // by time_since_update when displayed,
# min_symbol: Auto unit should be used if value > than 1 'X' (K, M, G)...
fields_description = {
'device_name': {
'description': 'Device name.'
},
'fs_type': {
'description': 'File system type.'
},
'mnt_point': {
'description': 'Mount point.'
},
'size': {
'description': 'Total size.',
'unit': 'byte',
},
'used': {
'description': 'Used size.',
'unit': 'byte',
},
'free': {
'description': 'Free size.',
'unit': 'byte',
},
'percent': {
'description': 'File system usage in percent.',
'unit': 'percent',
},
}
# SNMP OID
# The snmpd.conf needs to be edited.
# Add the following to enable it on all disk
@ -70,7 +104,10 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None):
"""Init the plugin."""
super(PluginModel, self).__init__(
args=args, config=config, items_history_list=items_history_list, stats_init_value=[]
args=args, config=config,
items_history_list=items_history_list,
stats_init_value=[],
fields_description=fields_description
)
# We want to display the stat in the curse interface

View File

@ -23,6 +23,46 @@ except Exception as e:
else:
import_error_tag = False
# {
# "key": "gpu_id",
# "gpu_id": 0,
# "name": "Fake GeForce GTX",
# "mem": 5.792331695556641,
# "proc": 4,
# "temperature": 26,
# "fan_speed": 30
# }
# Fields description
# description: human readable description
# short_name: shortname to use un UI
# unit: unit type
# rate: is it a rate ? If yes, // by time_since_update when displayed,
# min_symbol: Auto unit should be used if value > than 1 'X' (K, M, G)...
fields_description = {
'gpu_id': {
'description': 'GPU identification',
},
'name': {
'description': 'GPU name',
},
'mem': {
'description': 'Memory consumption',
'unit': 'percent',
},
'proc': {
'description': 'GPU processor consumption',
'unit': 'percent',
},
'temperature': {
'description': 'GPU temperature',
'unit': 'celsius',
},
'fan_speed': {
'description': 'GPU fan speed',
'unit': 'roundperminute',
},
}
# Define the history items list
# All items in this list will be historised if the --enable-history tag is set
items_history_list = [
@ -40,7 +80,10 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None):
"""Init the plugin."""
super(PluginModel, self).__init__(
args=args, config=config, items_history_list=items_history_list, stats_init_value=[]
args=args, config=config,
items_history_list=items_history_list,
stats_init_value=[],
fields_description=fields_description
)
# Init the Nvidia API

View File

@ -38,6 +38,34 @@ urls = [
('https://ipv4.jsonip.com', True, 'ip'),
]
# Fields description
# description: human readable description
# short_name: shortname to use un UI
# unit: unit type
# rate: is it a rate ? If yes, // by time_since_update when displayed,
# min_symbol: Auto unit should be used if value > than 1 'X' (K, M, G)...
fields_description = {
'address': {
'description': 'Private IP address',
},
'mask': {
'description': 'Private IP mask',
},
'mask_cidr': {
'description': 'Private IP mask in CIDR format',
'unit': 'number',
},
'gateway': {
'description': 'Private IP gateway',
},
'public_address': {
'description': 'Public IP address',
},
'public_info_human': {
'description': 'Public IP information',
},
}
class PluginModel(GlancesPluginModel):
"""Glances IP Plugin.
@ -50,7 +78,10 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None):
"""Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config)
super(PluginModel, self).__init__(
args=args, config=config,
fields_description=fields_description
)
# We want to display the stat in the curse interface
self.display_curse = True

View File

@ -17,6 +17,23 @@ from glances.timer import getTimeSinceLastUpdate
from glances.plugins.plugin.model import GlancesPluginModel
# Fields description
# description: human readable description
# short_name: shortname to use un UI
# unit: unit type
# rate: is it a rate ? If yes, // by time_since_update when displayed,
# min_symbol: Auto unit should be used if value > than 1 'X' (K, M, G)...
fields_description = {
'irq_line': {
'description': 'IRQ line name',
},
'irq_rate': {
'description': 'IRQ rate per second',
'unit': 'numberpersecond',
},
}
class PluginModel(GlancesPluginModel):
"""Glances IRQ plugin.
@ -25,7 +42,11 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None):
"""Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config, stats_init_value=[])
super(PluginModel, self).__init__(
args=args, config=config,
stats_init_value=[],
fields_description=fields_description
)
# We want to display the stat in the curse interface
self.display_curse = True

View File

@ -28,26 +28,50 @@ import psutil
# 'key': 'interface_name'}
# Fields description
fields_description = {
'interface_name': {'description': 'Interface name.', 'unit': 'string'},
'alias': {'description': 'Interface alias name (optional).', 'unit': 'string'},
'rx': {'description': 'The received/input rate (in bit per second).', 'unit': 'bps'},
'tx': {'description': 'The sent/output rate (in bit per second).', 'unit': 'bps'},
'cx': {'description': 'The cumulative received+sent rate (in bit per second).', 'unit': 'bps'},
'interface_name': {
'description': 'Interface name.',
'unit': 'string'
},
'alias': {
'description': 'Interface alias name (optional).',
'unit': 'string'
},
'rx': {
'description': 'The received/input rate.',
'unit': 'bitpersecond'
},
'tx': {
'description': 'The sent/output rate.',
'unit': 'bitpersecond'
},
'cx': {
'description': 'The cumulative received+sent rate.',
'unit': 'bitpersecond'
},
'cumulative_rx': {
'description': 'The number of bytes received through the interface (cumulative).',
'unit': 'bytes',
'unit': 'byte',
},
'cumulative_tx': {
'description': 'The number of bytes sent through the interface (cumulative).',
'unit': 'byte'
},
'cumulative_tx': {'description': 'The number of bytes sent through the interface (cumulative).', 'unit': 'bytes'},
'cumulative_cx': {
'description': 'The cumulative number of bytes reveived and sent through the interface (cumulative).',
'unit': 'bytes',
'unit': 'byte',
},
'speed': {
'description': 'Maximum interface speed (in bit per second). Can return 0 on some operating-system.',
'unit': 'bps',
'unit': 'bitpersecond',
},
'is_up': {
'description': 'Is the interface up ?',
'unit': 'bool'
},
'time_since_update': {
'description': 'Number of seconds since last update.',
'unit': 'seconds'
},
'is_up': {'description': 'Is the interface up ?', 'unit': 'bool'},
'time_since_update': {'description': 'Number of seconds since last update.', 'unit': 'seconds'},
}
# SNMP OID

View File

@ -12,6 +12,74 @@
from glances.cpu_percent import cpu_percent
from glances.plugins.plugin.model import GlancesPluginModel
# Fields description
# description: human readable description
# short_name: shortname to use un UI
# unit: unit type
# rate: is it a rate ? If yes, // by time_since_update when displayed,
# min_symbol: Auto unit should be used if value > than 1 'X' (K, M, G)...
fields_description = {
'cpu_number': {
'description': 'CPU number',
},
'total': {
'description': 'Sum of CPU percentages (except idle) for current CPU number.',
'unit': 'percent',
},
'system': {
'description': 'Percent time spent in kernel space. System CPU time is the \
time spent running code in the Operating System kernel.',
'unit': 'percent',
},
'user': {
'description': 'CPU percent time spent in user space. \
User CPU time is the time spent on the processor running your program\'s code (or code in libraries).',
'unit': 'percent',
},
'iowait': {
'description': '*(Linux)*: percent time spent by the CPU waiting for I/O \
operations to complete.',
'unit': 'percent',
},
'idle': {
'description': 'percent of CPU used by any program. Every program or task \
that runs on a computer system occupies a certain amount of processing \
time on the CPU. If the CPU has completed all tasks it is idle.',
'unit': 'percent',
},
'irq': {
'description': '*(Linux and BSD)*: percent time spent servicing/handling \
hardware/software interrupts. Time servicing interrupts (hardware + \
software).',
'unit': 'percent',
},
'nice': {
'description': '*(Unix)*: percent time occupied by user level processes with \
a positive nice value. The time the CPU has spent running users\' \
processes that have been *niced*.',
'unit': 'percent',
},
'steal': {
'description': '*(Linux)*: percentage of time a virtual CPU waits for a real \
CPU while the hypervisor is servicing another virtual processor.',
'unit': 'percent',
},
'guest': {
'description': '*(Linux)*: percent of time spent running a virtual CPU for \
guest operating systems under the control of the Linux kernel.',
'unit': 'percent',
},
'guest_nice': {
'description': '*(Linux)*: percent of time spent running a niced guest (virtual CPU).',
'unit': 'percent',
},
'softirq': {
'description': '*(Linux)*: percent of time spent handling software interrupts.',
'unit': 'percent',
},
}
# Define the history items list
items_history_list = [
{'name': 'user', 'description': 'User CPU usage', 'y_unit': '%'},
@ -29,7 +97,10 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None):
"""Init the plugin."""
super(PluginModel, self).__init__(
args=args, config=config, items_history_list=items_history_list, stats_init_value=[]
args=args, config=config,
items_history_list=items_history_list,
stats_init_value=[],
fields_description=fields_description
)
# We want to display the stat in the curse interface

View File

@ -439,6 +439,13 @@ class GlancesPluginModel(object):
else:
return json_dumps(rsv)
def get_item_info(self, item, key, default=None):
"""Return the item info grabbed into self.fields_description."""
if self.fields_description is None or item not in self.fields_description:
return default
else:
return self.fields_description[item].get(key, default)
def update_views_hidden(self):
"""Update the hidden views

View File

@ -31,13 +31,51 @@ except ImportError as e:
requests_tag = False
logger.warning("Missing Python Lib ({}), Ports plugin is limited to port scanning".format(e))
# Fields description
# description: human readable description
# short_name: shortname to use un UI
# unit: unit type
# rate: is it a rate ? If yes, // by time_since_update when displayed,
# min_symbol: Auto unit should be used if value > than 1 'X' (K, M, G)...
fields_description = {
'host': {
'description': 'Measurement is be done on this host (or IP address)',
},
'port': {
'description': 'Measurement is be done on this port (0 for ICMP)',
},
'description': {
'description': 'Human readable description for the host/port',
},
'refresh': {
'description': 'Refresh time (in seconds) for this host/port',
},
'timeout': {
'description': 'Timeout (in seconds) for the measurement',
},
'status': {
'description': 'Measurement result (in seconds)',
'unit': 'second',
},
'rtt_warning': {
'description': 'Warning threshold (in seconds) for the measurement',
'unit': 'second',
},
'indice': {
'description': 'Unique indice for the host/port',
},
}
class PluginModel(GlancesPluginModel):
"""Glances ports scanner plugin."""
def __init__(self, args=None, config=None):
"""Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config, stats_init_value=[])
super(PluginModel, self).__init__(
args=args, config=config,
stats_init_value=[],
fields_description=fields_description
)
self.args = args
self.config = config

View File

@ -12,6 +12,35 @@
from glances.processes import glances_processes, sort_for_human
from glances.plugins.plugin.model import GlancesPluginModel
# Fields description
# description: human readable description
# short_name: shortname to use un UI
# unit: unit type
# rate: is it a rate ? If yes, // by time_since_update when displayed,
# min_symbol: Auto unit should be used if value > than 1 'X' (K, M, G)...
fields_description = {
'total': {
'description': 'Total number of processes',
'unit': 'number',
},
'running': {
'description': 'Total number of running processes',
'unit': 'number',
},
'sleeping': {
'description': 'Total number of sleeping processes',
'unit': 'number',
},
'thread': {
'description': 'Total number of threads',
'unit': 'number',
},
'pid_max': {
'description': 'Maximum number of processes',
'unit': 'number',
},
}
# Define the history items list
items_history_list = [
{'name': 'total', 'description': 'Total number of processes', 'y_unit': ''},
@ -29,7 +58,11 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None):
"""Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config, items_history_list=items_history_list)
super(PluginModel, self).__init__(
args=args, config=config,
items_history_list=items_history_list,
fields_description=fields_description
)
# We want to display the stat in the curse interface
self.display_curse = True

View File

@ -16,6 +16,37 @@ from glances.plugins.plugin.model import GlancesPluginModel
import psutil
# Fields description
# description: human readable description
# short_name: shortname to use un UI
# unit: unit type
# rate: is it a rate ? If yes, // by time_since_update when displayed,
# min_symbol: Auto unit should be used if value > than 1 'X' (K, M, G)...
fields_description = {
'cpu': {
'description': 'CPU percent usage',
'unit': 'percent',
},
'mem': {
'description': 'MEM percent usage',
'unit': 'percent',
},
'swap': {
'description': 'SWAP percent usage',
'unit': 'percent',
},
'cpu_name': {
'description': 'CPU name',
},
'cpu_hz_current': {
'description': 'CPU current frequency',
'unit': 'hertz',
},
'cpu_hz': {
'description': 'CPU max frequency',
'unit': 'hertz',
},
}
# Define the history items list
# All items in this list will be historised if the --enable-history tag is set
@ -35,7 +66,11 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None):
"""Init the quicklook plugin."""
super(PluginModel, self).__init__(args=args, config=config, items_history_list=items_history_list)
super(PluginModel, self).__init__(
args=args, config=config,
items_history_list=items_history_list,
fields_description=fields_description
)
# We want to display the stat in the curse interface
self.display_curse = True

View File

@ -26,6 +26,35 @@ SENSOR_TEMP_UNIT = 'C'
SENSOR_FAN_TYPE = 'fan_speed'
SENSOR_FAN_UNIT = 'R'
# Fields description
# description: human readable description
# short_name: shortname to use un UI
# unit: unit type
# rate: is it a rate ? If yes, // by time_since_update when displayed,
# min_symbol: Auto unit should be used if value > than 1 'X' (K, M, G)...
fields_description = {
'label': {
'description': 'Sensor label',
},
'unit': {
'description': 'Sensor unit',
},
'value': {
'description': 'Sensor value',
'unit': 'number',
},
'warning': {
'description': 'Warning threshold',
'unit': 'number',
},
'critical': {
'description': 'Critical threshold',
'unit': 'number',
},
'type': {
'description': 'Sensor type (one of battery, temperature_core, fan_speed)',
},
}
class PluginModel(GlancesPluginModel):
"""Glances sensors plugin.
@ -37,7 +66,11 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None):
"""Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config, stats_init_value=[])
super(PluginModel, self).__init__(
args=args, config=config,
stats_init_value=[],
fields_description=fields_description
)
start_duration = Counter()

View File

@ -17,6 +17,41 @@ from io import open
from glances.globals import iteritems
from glances.plugins.plugin.model import GlancesPluginModel
# {
# "os_name": "Linux",
# "hostname": "XPS13-9333",
# "platform": "64bit",
# "linux_distro": "Ubuntu 22.04",
# "os_version": "5.15.0-88-generic",
# "hr_name": "Ubuntu 22.04 64bit"
# }
# Fields description
# description: human readable description
# short_name: shortname to use un UI
# unit: unit type
# rate: is it a rate ? If yes, // by time_since_update when displayed,
# min_symbol: Auto unit should be used if value > than 1 'X' (K, M, G)...
fields_description = {
'os_name': {
'description': 'Operating system name',
},
'hostname': {
'description': 'Hostname',
},
'platform': {
'description': 'Platform (32 or 64 bits)',
},
'linux_distro': {
'description': 'Linux distribution',
},
'os_version': {
'description': 'Operating system version',
},
'hr_name': {
'description': 'Human readable operating sytem name',
},
}
# SNMP OID
snmp_oid = {
'default': {'hostname': '1.3.6.1.2.1.1.5.0', 'system_name': '1.3.6.1.2.1.1.1.0'},
@ -82,7 +117,10 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None):
"""Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config)
super(PluginModel, self).__init__(
args=args, config=config,
fields_description=fields_description
)
# We want to display the stat in the curse interface
self.display_curse = True

View File

@ -476,7 +476,10 @@ class GlancesProcesses(object):
pass
else:
# Save values to cache
self.processlist_cache[proc['pid']] = {cached: proc[cached] for cached in cached_attrs}
try:
self.processlist_cache[proc['pid']] = {cached: proc[cached] for cached in cached_attrs}
except KeyError:
pass
# Apply user filter
processlist = list(filter(lambda p: not self._filter.is_filtered(p), processlist))