mirror of https://github.com/nicolargo/glances.git
Glances 4.0.8
This commit is contained in:
commit
bf3bb6a7e8
|
|
@ -123,19 +123,12 @@ jobs:
|
||||||
|
|
||||||
- name: Retrieve Repository Docker metadata
|
- name: Retrieve Repository Docker metadata
|
||||||
id: docker_meta
|
id: docker_meta
|
||||||
uses: crazy-max/ghaction-docker-meta@v5.0.0
|
uses: docker/metadata-action@v5
|
||||||
with:
|
with:
|
||||||
images: ${{ env.DEFAULT_DOCKER_IMAGE }}
|
images: ${{ env.DEFAULT_DOCKER_IMAGE }}
|
||||||
labels: |
|
labels: |
|
||||||
org.opencontainers.image.url=https://nicolargo.github.io/glances/
|
org.opencontainers.image.url=https://nicolargo.github.io/glances/
|
||||||
|
|
||||||
- name: Cache Docker layers
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: /tmp/.buildx-cache
|
|
||||||
key: ${{ runner.os }}-buildx-${{ env.NODE_ENV }}-${{ matrix.os }}-${{ matrix.tag.tag }}
|
|
||||||
restore-keys: ${{ runner.os }}-buildx-${{ env.NODE_ENV }}-${{ matrix.os }}
|
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3
|
uses: docker/setup-qemu-action@v3
|
||||||
with:
|
with:
|
||||||
|
|
@ -166,5 +159,7 @@ jobs:
|
||||||
platforms: ${{ matrix.os != 'ubuntu' && env.DOCKER_PLATFORMS || env.DOCKER_PLATFORMS_UBUNTU }}
|
platforms: ${{ matrix.os != 'ubuntu' && env.DOCKER_PLATFORMS || env.DOCKER_PLATFORMS_UBUNTU }}
|
||||||
target: ${{ matrix.tag.target }}
|
target: ${{ matrix.tag.target }}
|
||||||
labels: ${{ steps.docker_meta.outputs.labels }}
|
labels: ${{ steps.docker_meta.outputs.labels }}
|
||||||
cache-from: type=local,src=/tmp/.buildx-cache
|
# GHA default behaviour overwrites last build cache. Causes alpine and ubuntu cache to overwrite each other.
|
||||||
cache-to: type=local,dest=/tmp/.buildx-cache,mode=max
|
# Use `scope` with the os name to prevent that
|
||||||
|
cache-from: 'type=gha,scope=${{ matrix.os }}'
|
||||||
|
cache-to: 'type=gha,mode=max,scope=${{ matrix.os }}'
|
||||||
|
|
|
||||||
56
NEWS.rst
56
NEWS.rst
|
|
@ -48,6 +48,62 @@ Version 4.0.2
|
||||||
|
|
||||||
Thanks to RazCrimson for the sensors patch !
|
Thanks to RazCrimson for the sensors patch !
|
||||||
|
|
||||||
|
===============
|
||||||
|
Version 4.0.8
|
||||||
|
===============
|
||||||
|
|
||||||
|
* Make CORS option configurable security webui #2812
|
||||||
|
* When Glances is installed via venv, default configuration file is not used documentation packaging #2803
|
||||||
|
* GET /1272f6e9e8f9d6bfd6de.png results in 404 bug webui #2781 by Emporea was closed May 25, 2024
|
||||||
|
* Screen frequently flickers when outputting to local display bug needs test #2490
|
||||||
|
* Retire ujson for being in maintenance mode dependencies enhancement #2791
|
||||||
|
|
||||||
|
===============
|
||||||
|
Version 4.0.7
|
||||||
|
===============
|
||||||
|
|
||||||
|
* cpu_hz_current not available on NetBSD #2792
|
||||||
|
* SensorType change in REST API breaks compatibility in 4.0.4 #2788
|
||||||
|
|
||||||
|
===============
|
||||||
|
Version 4.0.6
|
||||||
|
===============
|
||||||
|
|
||||||
|
* No GPU info on Web View #2796
|
||||||
|
|
||||||
|
===============
|
||||||
|
Version 4.0.5
|
||||||
|
===============
|
||||||
|
|
||||||
|
* SensorType change in REST API breaks compatibility in 4.0.4 #2788
|
||||||
|
* Please make pydantic optional dependency, not required one #2777
|
||||||
|
* Update the Grafana dashboard #2780
|
||||||
|
* 4.0.4 - On Glances startup "ERROR -- Can not init battery class #2776
|
||||||
|
* In codeSpace (with Python 3.8), an error occurs in ./unittest-restful.py #2773
|
||||||
|
|
||||||
|
Use Ruff as default Linter.
|
||||||
|
|
||||||
|
===============
|
||||||
|
Version 4.0.4
|
||||||
|
===============
|
||||||
|
|
||||||
|
Hostfix release for support sensors plugin on python 3.8
|
||||||
|
|
||||||
|
===============
|
||||||
|
Version 4.0.3
|
||||||
|
===============
|
||||||
|
|
||||||
|
Additional fixes for Sensor plugin
|
||||||
|
|
||||||
|
===============
|
||||||
|
Version 4.0.2
|
||||||
|
===============
|
||||||
|
|
||||||
|
* hotfix: plugin(sensors) - race conditions btw fan_speed & temperature… #2766
|
||||||
|
* fix: include requirements.txt and SECURITY.md for pypi dist #2761
|
||||||
|
|
||||||
|
Thanks to RazCrimson for the sensors patch !
|
||||||
|
|
||||||
===============
|
===============
|
||||||
Version 4.0.1
|
Version 4.0.1
|
||||||
===============
|
===============
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ Requirements
|
||||||
- ``psutil`` (better with latest version)
|
- ``psutil`` (better with latest version)
|
||||||
- ``defusedxml`` (in order to monkey patch xmlrpc)
|
- ``defusedxml`` (in order to monkey patch xmlrpc)
|
||||||
- ``packaging`` (for the version comparison)
|
- ``packaging`` (for the version comparison)
|
||||||
- ``ujson`` (an optimized alternative to the standard json module)
|
- ``orjson`` (an optimized alternative to the standard json module)
|
||||||
|
|
||||||
*Note for Python 2 users*
|
*Note for Python 2 users*
|
||||||
|
|
||||||
|
|
@ -115,7 +115,6 @@ Optional dependencies:
|
||||||
- ``podman`` (for the Containers Podman monitoring support)
|
- ``podman`` (for the Containers Podman monitoring support)
|
||||||
- ``potsdb`` (for the OpenTSDB export module)
|
- ``potsdb`` (for the OpenTSDB export module)
|
||||||
- ``prometheus_client`` (for the Prometheus export module)
|
- ``prometheus_client`` (for the Prometheus export module)
|
||||||
- ``py-cpuinfo`` (for the Quicklook CPU info module)
|
|
||||||
- ``pygal`` (for the graph export module)
|
- ``pygal`` (for the graph export module)
|
||||||
- ``pymdstat`` (for RAID support) [Linux-only]
|
- ``pymdstat`` (for RAID support) [Linux-only]
|
||||||
- ``pymongo`` (for the MongoDB export module)
|
- ``pymongo`` (for the MongoDB export module)
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,16 @@ history_size=1200
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
[outputs]
|
[outputs]
|
||||||
|
# Options for all UIs
|
||||||
|
#--------------------
|
||||||
# Separator in the Curses and WebUI interface (between top and others plugins)
|
# Separator in the Curses and WebUI interface (between top and others plugins)
|
||||||
separator=True
|
separator=True
|
||||||
# Set the the Curses and WebUI interface left menu plugin list (comma-separated)
|
# Set the the Curses and WebUI interface left menu plugin list (comma-separated)
|
||||||
#left_menu=network,wifi,connections,ports,diskio,fs,irq,folders,raid,smart,sensors,now
|
#left_menu=network,wifi,connections,ports,diskio,fs,irq,folders,raid,smart,sensors,now
|
||||||
# Limit the number of processes to display (in the WebUI)
|
# Limit the number of processes to display (in the WebUI)
|
||||||
max_processes_display=25
|
max_processes_display=25
|
||||||
|
# Options for WebUI
|
||||||
|
#------------------
|
||||||
# Set URL prefix for the WebUI and the API
|
# Set URL prefix for the WebUI and the API
|
||||||
# Example: url_prefix=/glances/ => http://localhost/glances/
|
# Example: url_prefix=/glances/ => http://localhost/glances/
|
||||||
# Note: The final / is mandatory
|
# Note: The final / is mandatory
|
||||||
|
|
@ -41,9 +45,22 @@ max_processes_display=25
|
||||||
# then configure this folder with the webui_root_path key
|
# then configure this folder with the webui_root_path key
|
||||||
# Default is folder where glances_restfull_api.py is hosted
|
# Default is folder where glances_restfull_api.py is hosted
|
||||||
#webui_root_path=
|
#webui_root_path=
|
||||||
|
# CORS options
|
||||||
|
# Comma separated list of origins that should be permitted to make cross-origin requests.
|
||||||
|
# Default is *
|
||||||
|
#cors_origins=*
|
||||||
|
# Indicate that cookies should be supported for cross-origin requests.
|
||||||
|
# Default is True
|
||||||
|
#cors_credentials=True
|
||||||
|
# Comma separated list of HTTP methods that should be allowed for cross-origin requests.
|
||||||
|
# Default is *
|
||||||
|
#cors_methods=*
|
||||||
|
# Comma separated list of HTTP request headers that should be supported for cross-origin requests.
|
||||||
|
# Default is *
|
||||||
|
#cors_headers=*
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# plugins
|
# Plugins
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
[quicklook]
|
[quicklook]
|
||||||
|
|
@ -199,6 +216,10 @@ tx_critical=90
|
||||||
hide=docker.*,lo
|
hide=docker.*,lo
|
||||||
# Define the list of wireless network interfaces to be show (comma-separated)
|
# Define the list of wireless network interfaces to be show (comma-separated)
|
||||||
#show=docker.*
|
#show=docker.*
|
||||||
|
# Automatically hide interface not up (default is False)
|
||||||
|
#hide_no_up=True
|
||||||
|
# Automatically hide interface with no IP address (default is False)
|
||||||
|
#hide_no_ip=True
|
||||||
# It is possible to overwrite the bitrate thresholds per interface
|
# It is possible to overwrite the bitrate thresholds per interface
|
||||||
# WLAN 0 Default limits (in bits per second aka bps) for interface bitrate
|
# WLAN 0 Default limits (in bits per second aka bps) for interface bitrate
|
||||||
#wlan0_rx_careful=4000000
|
#wlan0_rx_careful=4000000
|
||||||
|
|
@ -765,13 +786,13 @@ refresh=3
|
||||||
countmax=20
|
countmax=20
|
||||||
|
|
||||||
[amp_conntrack]
|
[amp_conntrack]
|
||||||
# Use comma separated for multiple commands (no space around the comma)
|
# Use && separator for multiple commands
|
||||||
# If the regex key is not defined, the AMP will be executed every refresh second
|
# If the regex key is not defined, the AMP will be executed every refresh second
|
||||||
# and the process count will not be displayed (countmin and countmax will be ignore)
|
# and the process count will not be displayed (countmin and countmax will be ignore)
|
||||||
enable=false
|
enable=false
|
||||||
refresh=30
|
refresh=30
|
||||||
one_line=false
|
one_line=false
|
||||||
command=sysctl net.netfilter.nf_conntrack_count;sysctl net.netfilter.nf_conntrack_max
|
command=sysctl net.netfilter.nf_conntrack_count && sysctl net.netfilter.nf_conntrack_max
|
||||||
|
|
||||||
[amp_nginx]
|
[amp_nginx]
|
||||||
# Use the NGinx AMP
|
# Use the NGinx AMP
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
|
orjson
|
||||||
reuse
|
reuse
|
||||||
setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability
|
setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability
|
||||||
sphinx
|
sphinx
|
||||||
sphinx_rtd_theme
|
sphinx_rtd_theme
|
||||||
ujson
|
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,16 @@ history_size=1200
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
[outputs]
|
[outputs]
|
||||||
|
# Options for all UIs
|
||||||
|
#--------------------
|
||||||
# Separator in the Curses and WebUI interface (between top and others plugins)
|
# Separator in the Curses and WebUI interface (between top and others plugins)
|
||||||
separator=True
|
separator=True
|
||||||
# Set the the Curses and WebUI interface left menu plugin list (comma-separated)
|
# Set the the Curses and WebUI interface left menu plugin list (comma-separated)
|
||||||
#left_menu=network,wifi,connections,ports,diskio,fs,irq,folders,raid,smart,sensors,now
|
#left_menu=network,wifi,connections,ports,diskio,fs,irq,folders,raid,smart,sensors,now
|
||||||
# Limit the number of processes to display (in the WebUI)
|
# Limit the number of processes to display (in the WebUI)
|
||||||
max_processes_display=25
|
max_processes_display=25
|
||||||
|
# Options for WebUI
|
||||||
|
#------------------
|
||||||
# Set URL prefix for the WebUI and the API
|
# Set URL prefix for the WebUI and the API
|
||||||
# Example: url_prefix=/glances/ => http://localhost/glances/
|
# Example: url_prefix=/glances/ => http://localhost/glances/
|
||||||
# Note: The final / is mandatory
|
# Note: The final / is mandatory
|
||||||
|
|
@ -41,6 +45,19 @@ max_processes_display=25
|
||||||
# then configure this folder with the webui_root_path key
|
# then configure this folder with the webui_root_path key
|
||||||
# Default is folder where glances_restfull_api.py is hosted
|
# Default is folder where glances_restfull_api.py is hosted
|
||||||
#webui_root_path=
|
#webui_root_path=
|
||||||
|
# CORS options
|
||||||
|
# Comma separated list of origins that should be permitted to make cross-origin requests.
|
||||||
|
# Default is *
|
||||||
|
#cors_origins=*
|
||||||
|
# Indicate that cookies should be supported for cross-origin requests.
|
||||||
|
# Default is True
|
||||||
|
#cors_credentials=True
|
||||||
|
# Comma separated list of HTTP methods that should be allowed for cross-origin requests.
|
||||||
|
# Default is *
|
||||||
|
#cors_methods=*
|
||||||
|
# Comma separated list of HTTP request headers that should be supported for cross-origin requests.
|
||||||
|
# Default is *
|
||||||
|
#cors_headers=*
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# plugins
|
# plugins
|
||||||
|
|
@ -199,6 +216,10 @@ tx_critical=90
|
||||||
#hide=docker.*,lo
|
#hide=docker.*,lo
|
||||||
# Define the list of wireless network interfaces to be show (comma-separated)
|
# Define the list of wireless network interfaces to be show (comma-separated)
|
||||||
#show=docker.*
|
#show=docker.*
|
||||||
|
# Automatically hide interface not up (default is False)
|
||||||
|
hide_no_up=True
|
||||||
|
# Automatically hide interface with no IP address (default is False)
|
||||||
|
hide_no_ip=True
|
||||||
# It is possible to overwrite the bitrate thresholds per interface
|
# It is possible to overwrite the bitrate thresholds per interface
|
||||||
# WLAN 0 Default limits (in bits per second aka bps) for interface bitrate
|
# WLAN 0 Default limits (in bits per second aka bps) for interface bitrate
|
||||||
#wlan0_rx_careful=4000000
|
#wlan0_rx_careful=4000000
|
||||||
|
|
@ -765,13 +786,13 @@ refresh=3
|
||||||
countmax=20
|
countmax=20
|
||||||
|
|
||||||
[amp_conntrack]
|
[amp_conntrack]
|
||||||
# Use comma separated for multiple commands (no space around the comma)
|
# Use && separator for multiple commands
|
||||||
# If the regex key is not defined, the AMP will be executed every refresh second
|
# If the regex key is not defined, the AMP will be executed every refresh second
|
||||||
# and the process count will not be displayed (countmin and countmax will be ignore)
|
# and the process count will not be displayed (countmin and countmax will be ignore)
|
||||||
enable=false
|
enable=false
|
||||||
refresh=30
|
refresh=30
|
||||||
one_line=false
|
one_line=false
|
||||||
command=sysctl net.netfilter.nf_conntrack_count;sysctl net.netfilter.nf_conntrack_max
|
command=sysctl net.netfilter.nf_conntrack_count && sysctl net.netfilter.nf_conntrack_max
|
||||||
|
|
||||||
[amp_nginx]
|
[amp_nginx]
|
||||||
# Use the NGinx AMP
|
# Use the NGinx AMP
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
# install with base requirements file
|
# install with base requirements file
|
||||||
-r requirements.txt
|
-r requirements.txt
|
||||||
|
|
||||||
docker>=6.1.1; python_version >= "3.7"
|
docker>=6.1.1
|
||||||
packaging; python_version >= "3.7"
|
podman
|
||||||
podman; python_version >= "3.6"
|
|
||||||
python-dateutil
|
python-dateutil
|
||||||
requests
|
requests
|
||||||
six
|
six
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,11 @@ For example:
|
||||||
enable=false
|
enable=false
|
||||||
refresh=30
|
refresh=30
|
||||||
one_line=false
|
one_line=false
|
||||||
command=sysctl net.netfilter.nf_conntrack_count;sysctl net.netfilter.nf_conntrack_max
|
command=sysctl net.netfilter.nf_conntrack_count && sysctl net.netfilter.nf_conntrack_max
|
||||||
|
|
||||||
For security reason, pipe is not directly allowed in a AMP command but you create a sheel
|
Note: for multiple command, please use the '&&'' separator.
|
||||||
|
|
||||||
|
For security reason, pipe is not directly allowed in a AMP command but you create a shell
|
||||||
script with your command:
|
script with your command:
|
||||||
|
|
||||||
.. code-block:: ini
|
.. code-block:: ini
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ In this case thresholds values are define in bps.
|
||||||
Additionally, you can define:
|
Additionally, you can define:
|
||||||
|
|
||||||
- a list of network interfaces to hide
|
- a list of network interfaces to hide
|
||||||
|
- automatically hide interfaces not up
|
||||||
|
- automatically hide interfaces without IP address
|
||||||
- per-interface limit values
|
- per-interface limit values
|
||||||
- aliases for interface name
|
- aliases for interface name
|
||||||
|
|
||||||
|
|
@ -41,6 +43,10 @@ virtual docker interface (docker0, docker1, ...):
|
||||||
hide=docker.*,lo
|
hide=docker.*,lo
|
||||||
# Define the list of network interfaces to show (comma-separated regexp)
|
# Define the list of network interfaces to show (comma-separated regexp)
|
||||||
#show=eth0,eth1
|
#show=eth0,eth1
|
||||||
|
# Automatically hide interface not up (default is False)
|
||||||
|
hide_no_up=True
|
||||||
|
# Automatically hide interface with no IP address (default is False)
|
||||||
|
hide_no_ip=True
|
||||||
# WLAN 0 alias
|
# WLAN 0 alias
|
||||||
wlan0_alias=Wireless IF
|
wlan0_alias=Wireless IF
|
||||||
# It is possible to overwrite the bitrate thresholds per interface
|
# It is possible to overwrite the bitrate thresholds per interface
|
||||||
|
|
|
||||||
226
docs/api.rst
226
docs/api.rst
|
|
@ -141,7 +141,7 @@ Get plugin stats::
|
||||||
"refresh": 3.0,
|
"refresh": 3.0,
|
||||||
"regex": True,
|
"regex": True,
|
||||||
"result": None,
|
"result": None,
|
||||||
"timer": 0.17942380905151367},
|
"timer": 0.24439311027526855},
|
||||||
{"count": 0,
|
{"count": 0,
|
||||||
"countmax": 20.0,
|
"countmax": 20.0,
|
||||||
"countmin": None,
|
"countmin": None,
|
||||||
|
|
@ -150,7 +150,7 @@ Get plugin stats::
|
||||||
"refresh": 3.0,
|
"refresh": 3.0,
|
||||||
"regex": True,
|
"regex": True,
|
||||||
"result": None,
|
"result": None,
|
||||||
"timer": 0.17932724952697754}]
|
"timer": 0.2443389892578125}]
|
||||||
|
|
||||||
Fields descriptions:
|
Fields descriptions:
|
||||||
|
|
||||||
|
|
@ -178,7 +178,7 @@ Get a specific item when field matches the given value::
|
||||||
"refresh": 3.0,
|
"refresh": 3.0,
|
||||||
"regex": True,
|
"regex": True,
|
||||||
"result": None,
|
"result": None,
|
||||||
"timer": 0.17942380905151367}]}
|
"timer": 0.24439311027526855}]}
|
||||||
|
|
||||||
GET cloud
|
GET cloud
|
||||||
---------
|
---------
|
||||||
|
|
@ -219,7 +219,21 @@ GET containers
|
||||||
Get plugin stats::
|
Get plugin stats::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/containers
|
# curl http://localhost:61208/api/4/containers
|
||||||
[]
|
[{"command": "/bin/sh -c /venv/bin/python3 -m glances $GLANCES_OPT",
|
||||||
|
"cpu": {"total": 0.0},
|
||||||
|
"cpu_percent": 0.0,
|
||||||
|
"created": "2024-05-25T13:52:22.535373707Z",
|
||||||
|
"engine": "docker",
|
||||||
|
"id": "bb99d31288db8904ed4cd43db8255a926830936189bc180d77c3459cbaa7f490",
|
||||||
|
"image": ["nicolargo/glances:latest"],
|
||||||
|
"io": {},
|
||||||
|
"key": "name",
|
||||||
|
"memory": {},
|
||||||
|
"memory_usage": None,
|
||||||
|
"name": "wizardly_nightingale",
|
||||||
|
"network": {},
|
||||||
|
"status": "running",
|
||||||
|
"uptime": "14 mins"}]
|
||||||
|
|
||||||
Fields descriptions:
|
Fields descriptions:
|
||||||
|
|
||||||
|
|
@ -240,6 +254,31 @@ Fields descriptions:
|
||||||
* **pod_name**: Pod name (only with Podman) (unit is *None*)
|
* **pod_name**: Pod name (only with Podman) (unit is *None*)
|
||||||
* **pod_id**: Pod ID (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": ["wizardly_nightingale"]}
|
||||||
|
|
||||||
|
Get a specific item when field matches the given value::
|
||||||
|
|
||||||
|
# curl http://localhost:61208/api/4/containers/name/wizardly_nightingale
|
||||||
|
{"wizardly_nightingale": [{"command": "/bin/sh -c /venv/bin/python3 -m glances "
|
||||||
|
"$GLANCES_OPT",
|
||||||
|
"cpu": {"total": 0.0},
|
||||||
|
"cpu_percent": 0.0,
|
||||||
|
"created": "2024-05-25T13:52:22.535373707Z",
|
||||||
|
"engine": "docker",
|
||||||
|
"id": "bb99d31288db8904ed4cd43db8255a926830936189bc180d77c3459cbaa7f490",
|
||||||
|
"image": ["nicolargo/glances:latest"],
|
||||||
|
"io": {},
|
||||||
|
"key": "name",
|
||||||
|
"memory": {},
|
||||||
|
"memory_usage": None,
|
||||||
|
"name": "wizardly_nightingale",
|
||||||
|
"network": {},
|
||||||
|
"status": "running",
|
||||||
|
"uptime": "14 mins"}]}
|
||||||
|
|
||||||
GET core
|
GET core
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
|
@ -265,18 +304,18 @@ Get plugin stats::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/cpu
|
# curl http://localhost:61208/api/4/cpu
|
||||||
{"cpucore": 16,
|
{"cpucore": 16,
|
||||||
"ctx_switches": 247960513,
|
"ctx_switches": 7772781,
|
||||||
"guest": 0.0,
|
"guest": 0.0,
|
||||||
"idle": 0.0,
|
"idle": 3.0,
|
||||||
"interrupts": 235154276,
|
"interrupts": 6643340,
|
||||||
"iowait": 0.0,
|
"iowait": 0.0,
|
||||||
"irq": 0.0,
|
"irq": 0.0,
|
||||||
"nice": 0.0,
|
"nice": 0.0,
|
||||||
"soft_interrupts": 79848589,
|
"soft_interrupts": 1761276,
|
||||||
"steal": 0.0,
|
"steal": 0.0,
|
||||||
"syscalls": 0,
|
"syscalls": 0,
|
||||||
"system": 0.0,
|
"system": 0.0,
|
||||||
"total": 0.0,
|
"total": 16.7,
|
||||||
"user": 1.0}
|
"user": 1.0}
|
||||||
|
|
||||||
Fields descriptions:
|
Fields descriptions:
|
||||||
|
|
@ -310,7 +349,7 @@ Fields descriptions:
|
||||||
Get a specific field::
|
Get a specific field::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/cpu/total
|
# curl http://localhost:61208/api/4/cpu/total
|
||||||
{"total": 0.0}
|
{"total": 16.7}
|
||||||
|
|
||||||
GET diskio
|
GET diskio
|
||||||
----------
|
----------
|
||||||
|
|
@ -320,14 +359,14 @@ Get plugin stats::
|
||||||
# curl http://localhost:61208/api/4/diskio
|
# curl http://localhost:61208/api/4/diskio
|
||||||
[{"disk_name": "nvme0n1",
|
[{"disk_name": "nvme0n1",
|
||||||
"key": "disk_name",
|
"key": "disk_name",
|
||||||
"read_bytes": 4854106624,
|
"read_bytes": 3983976960,
|
||||||
"read_count": 207109,
|
"read_count": 115648,
|
||||||
"write_bytes": 15446680576,
|
"write_bytes": 3073111040,
|
||||||
"write_count": 891078},
|
"write_count": 91409},
|
||||||
{"disk_name": "nvme0n1p1",
|
{"disk_name": "nvme0n1p1",
|
||||||
"key": "disk_name",
|
"key": "disk_name",
|
||||||
"read_bytes": 7484416,
|
"read_bytes": 7476224,
|
||||||
"read_count": 592,
|
"read_count": 576,
|
||||||
"write_bytes": 1024,
|
"write_bytes": 1024,
|
||||||
"write_count": 2}]
|
"write_count": 2}]
|
||||||
|
|
||||||
|
|
@ -363,10 +402,10 @@ Get a specific item when field matches the given value::
|
||||||
# curl http://localhost:61208/api/4/diskio/disk_name/nvme0n1
|
# curl http://localhost:61208/api/4/diskio/disk_name/nvme0n1
|
||||||
{"nvme0n1": [{"disk_name": "nvme0n1",
|
{"nvme0n1": [{"disk_name": "nvme0n1",
|
||||||
"key": "disk_name",
|
"key": "disk_name",
|
||||||
"read_bytes": 4854106624,
|
"read_bytes": 3983976960,
|
||||||
"read_count": 207109,
|
"read_count": 115648,
|
||||||
"write_bytes": 15446680576,
|
"write_bytes": 3073111040,
|
||||||
"write_count": 891078}]}
|
"write_count": 91409}]}
|
||||||
|
|
||||||
GET folders
|
GET folders
|
||||||
-----------
|
-----------
|
||||||
|
|
@ -393,13 +432,13 @@ Get plugin stats::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/fs
|
# curl http://localhost:61208/api/4/fs
|
||||||
[{"device_name": "/dev/mapper/ubuntu--vg-ubuntu--lv",
|
[{"device_name": "/dev/mapper/ubuntu--vg-ubuntu--lv",
|
||||||
"free": 904231424000,
|
"free": 902284546048,
|
||||||
"fs_type": "ext4",
|
"fs_type": "ext4",
|
||||||
"key": "mnt_point",
|
"key": "mnt_point",
|
||||||
"mnt_point": "/",
|
"mnt_point": "/",
|
||||||
"percent": 5.1,
|
"percent": 5.3,
|
||||||
"size": 1003736440832,
|
"size": 1003736440832,
|
||||||
"used": 48442511360}]
|
"used": 50389389312}]
|
||||||
|
|
||||||
Fields descriptions:
|
Fields descriptions:
|
||||||
|
|
||||||
|
|
@ -420,13 +459,13 @@ Get a specific item when field matches the given value::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/fs/mnt_point//
|
# curl http://localhost:61208/api/4/fs/mnt_point//
|
||||||
{"/": [{"device_name": "/dev/mapper/ubuntu--vg-ubuntu--lv",
|
{"/": [{"device_name": "/dev/mapper/ubuntu--vg-ubuntu--lv",
|
||||||
"free": 904231424000,
|
"free": 902284546048,
|
||||||
"fs_type": "ext4",
|
"fs_type": "ext4",
|
||||||
"key": "mnt_point",
|
"key": "mnt_point",
|
||||||
"mnt_point": "/",
|
"mnt_point": "/",
|
||||||
"percent": 5.1,
|
"percent": 5.3,
|
||||||
"size": 1003736440832,
|
"size": 1003736440832,
|
||||||
"used": 48442511360}]}
|
"used": 50389389312}]}
|
||||||
|
|
||||||
GET gpu
|
GET gpu
|
||||||
-------
|
-------
|
||||||
|
|
@ -500,9 +539,9 @@ Get plugin stats::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/load
|
# curl http://localhost:61208/api/4/load
|
||||||
{"cpucore": 16,
|
{"cpucore": 16,
|
||||||
"min1": 0.2802734375,
|
"min1": 0.560546875,
|
||||||
"min15": 0.6240234375,
|
"min15": 0.54833984375,
|
||||||
"min5": 0.61376953125}
|
"min5": 0.70166015625}
|
||||||
|
|
||||||
Fields descriptions:
|
Fields descriptions:
|
||||||
|
|
||||||
|
|
@ -514,7 +553,7 @@ Fields descriptions:
|
||||||
Get a specific field::
|
Get a specific field::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/load/min1
|
# curl http://localhost:61208/api/4/load/min1
|
||||||
{"min1": 0.2802734375}
|
{"min1": 0.560546875}
|
||||||
|
|
||||||
GET mem
|
GET mem
|
||||||
-------
|
-------
|
||||||
|
|
@ -522,16 +561,16 @@ GET mem
|
||||||
Get plugin stats::
|
Get plugin stats::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/mem
|
# curl http://localhost:61208/api/4/mem
|
||||||
{"active": 8875126784,
|
{"active": 5540470784,
|
||||||
"available": 7975804928,
|
"available": 11137699840,
|
||||||
"buffers": 463708160,
|
"buffers": 226918400,
|
||||||
"cached": 7862255616,
|
"cached": 6333566976,
|
||||||
"free": 7975804928,
|
"free": 11137699840,
|
||||||
"inactive": 4694634496,
|
"inactive": 3872489472,
|
||||||
"percent": 51.4,
|
"percent": 32.2,
|
||||||
"shared": 849006592,
|
"shared": 656637952,
|
||||||
"total": 16422486016,
|
"total": 16422486016,
|
||||||
"used": 8446681088}
|
"used": 5284786176}
|
||||||
|
|
||||||
Fields descriptions:
|
Fields descriptions:
|
||||||
|
|
||||||
|
|
@ -558,13 +597,13 @@ GET memswap
|
||||||
Get plugin stats::
|
Get plugin stats::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/memswap
|
# curl http://localhost:61208/api/4/memswap
|
||||||
{"free": 4293914624,
|
{"free": 4294963200,
|
||||||
"percent": 0.0,
|
"percent": 0.0,
|
||||||
"sin": 0,
|
"sin": 0,
|
||||||
"sout": 114688,
|
"sout": 0,
|
||||||
"time_since_update": 1,
|
"time_since_update": 1,
|
||||||
"total": 4294963200,
|
"total": 4294963200,
|
||||||
"used": 1048576}
|
"used": 0}
|
||||||
|
|
||||||
Fields descriptions:
|
Fields descriptions:
|
||||||
|
|
||||||
|
|
@ -589,15 +628,26 @@ Get plugin stats::
|
||||||
# curl http://localhost:61208/api/4/network
|
# curl http://localhost:61208/api/4/network
|
||||||
[{"alias": None,
|
[{"alias": None,
|
||||||
"bytes_all": 0,
|
"bytes_all": 0,
|
||||||
"bytes_all_gauge": 1608088786,
|
"bytes_all_gauge": 422462144,
|
||||||
"bytes_recv": 0,
|
"bytes_recv": 0,
|
||||||
"bytes_recv_gauge": 1294928139,
|
"bytes_recv_gauge": 413272561,
|
||||||
"bytes_sent": 0,
|
"bytes_sent": 0,
|
||||||
"bytes_sent_gauge": 313160647,
|
"bytes_sent_gauge": 9189583,
|
||||||
"interface_name": "wlp0s20f3",
|
"interface_name": "wlp0s20f3",
|
||||||
"key": "interface_name",
|
"key": "interface_name",
|
||||||
"speed": 0,
|
"speed": 0,
|
||||||
"time_since_update": 0.18457698822021484}]
|
"time_since_update": 0.24814295768737793},
|
||||||
|
{"alias": None,
|
||||||
|
"bytes_all": 0,
|
||||||
|
"bytes_all_gauge": 18987,
|
||||||
|
"bytes_recv": 0,
|
||||||
|
"bytes_recv_gauge": 528,
|
||||||
|
"bytes_sent": 0,
|
||||||
|
"bytes_sent_gauge": 18459,
|
||||||
|
"interface_name": "vethfc47299",
|
||||||
|
"key": "interface_name",
|
||||||
|
"speed": 10485760000,
|
||||||
|
"time_since_update": 0.24814295768737793}]
|
||||||
|
|
||||||
Fields descriptions:
|
Fields descriptions:
|
||||||
|
|
||||||
|
|
@ -619,22 +669,22 @@ Fields descriptions:
|
||||||
Get a specific field::
|
Get a specific field::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/network/interface_name
|
# curl http://localhost:61208/api/4/network/interface_name
|
||||||
{"interface_name": ["wlp0s20f3"]}
|
{"interface_name": ["wlp0s20f3", "vethfc47299"]}
|
||||||
|
|
||||||
Get a specific item when field matches the given value::
|
Get a specific item when field matches the given value::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/network/interface_name/wlp0s20f3
|
# curl http://localhost:61208/api/4/network/interface_name/wlp0s20f3
|
||||||
{"wlp0s20f3": [{"alias": None,
|
{"wlp0s20f3": [{"alias": None,
|
||||||
"bytes_all": 0,
|
"bytes_all": 0,
|
||||||
"bytes_all_gauge": 1608088786,
|
"bytes_all_gauge": 422462144,
|
||||||
"bytes_recv": 0,
|
"bytes_recv": 0,
|
||||||
"bytes_recv_gauge": 1294928139,
|
"bytes_recv_gauge": 413272561,
|
||||||
"bytes_sent": 0,
|
"bytes_sent": 0,
|
||||||
"bytes_sent_gauge": 313160647,
|
"bytes_sent_gauge": 9189583,
|
||||||
"interface_name": "wlp0s20f3",
|
"interface_name": "wlp0s20f3",
|
||||||
"key": "interface_name",
|
"key": "interface_name",
|
||||||
"speed": 0,
|
"speed": 0,
|
||||||
"time_since_update": 0.18457698822021484}]}
|
"time_since_update": 0.24814295768737793}]}
|
||||||
|
|
||||||
GET now
|
GET now
|
||||||
-------
|
-------
|
||||||
|
|
@ -642,7 +692,7 @@ GET now
|
||||||
Get plugin stats::
|
Get plugin stats::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/now
|
# curl http://localhost:61208/api/4/now
|
||||||
{"custom": "2024-05-25 16:10:02 CEST", "iso": "2024-05-25T16:10:02+02:00"}
|
{"custom": "2024-06-08 10:22:29 CEST", "iso": "2024-06-08T10:22:29+02:00"}
|
||||||
|
|
||||||
Fields descriptions:
|
Fields descriptions:
|
||||||
|
|
||||||
|
|
@ -652,7 +702,7 @@ Fields descriptions:
|
||||||
Get a specific field::
|
Get a specific field::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/now/iso
|
# curl http://localhost:61208/api/4/now/iso
|
||||||
{"iso": "2024-05-25T16:10:02+02:00"}
|
{"iso": "2024-06-08T10:22:29+02:00"}
|
||||||
|
|
||||||
GET percpu
|
GET percpu
|
||||||
----------
|
----------
|
||||||
|
|
@ -719,7 +769,7 @@ Get plugin stats::
|
||||||
"port": 0,
|
"port": 0,
|
||||||
"refresh": 30,
|
"refresh": 30,
|
||||||
"rtt_warning": None,
|
"rtt_warning": None,
|
||||||
"status": 0.005044,
|
"status": 0.005593,
|
||||||
"timeout": 3}]
|
"timeout": 3}]
|
||||||
|
|
||||||
Fields descriptions:
|
Fields descriptions:
|
||||||
|
|
@ -747,7 +797,7 @@ Get a specific item when field matches the given value::
|
||||||
"port": 0,
|
"port": 0,
|
||||||
"refresh": 30,
|
"refresh": 30,
|
||||||
"rtt_warning": None,
|
"rtt_warning": None,
|
||||||
"status": 0.005044,
|
"status": 0.005593,
|
||||||
"timeout": 3}]}
|
"timeout": 3}]}
|
||||||
|
|
||||||
GET processcount
|
GET processcount
|
||||||
|
|
@ -756,7 +806,7 @@ GET processcount
|
||||||
Get plugin stats::
|
Get plugin stats::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/processcount
|
# curl http://localhost:61208/api/4/processcount
|
||||||
{"pid_max": 0, "running": 0, "sleeping": 292, "thread": 1710, "total": 432}
|
{"pid_max": 0, "running": 0, "sleeping": 279, "thread": 1568, "total": 410}
|
||||||
|
|
||||||
Fields descriptions:
|
Fields descriptions:
|
||||||
|
|
||||||
|
|
@ -769,7 +819,7 @@ Fields descriptions:
|
||||||
Get a specific field::
|
Get a specific field::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/processcount/total
|
# curl http://localhost:61208/api/4/processcount/total
|
||||||
{"total": 432}
|
{"total": 410}
|
||||||
|
|
||||||
GET processlist
|
GET processlist
|
||||||
---------------
|
---------------
|
||||||
|
|
@ -809,14 +859,14 @@ GET quicklook
|
||||||
Get plugin stats::
|
Get plugin stats::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/quicklook
|
# curl http://localhost:61208/api/4/quicklook
|
||||||
{"cpu": 0.0,
|
{"cpu": 16.7,
|
||||||
"cpu_hz": 4475000000.0,
|
"cpu_hz": 4475000000.0,
|
||||||
"cpu_hz_current": 1610092062.5,
|
"cpu_hz_current": 1230624312.5,
|
||||||
"cpu_log_core": 16,
|
"cpu_log_core": 16,
|
||||||
"cpu_name": "13th Gen Intel(R) Core(TM) i7-13620H",
|
"cpu_name": "13th Gen Intel(R) Core(TM) i7-13620H",
|
||||||
"cpu_phys_core": 10,
|
"cpu_phys_core": 10,
|
||||||
"load": 3.9,
|
"load": 3.4,
|
||||||
"mem": 51.5,
|
"mem": 32.1,
|
||||||
"percpu": [{"cpu_number": 0,
|
"percpu": [{"cpu_number": 0,
|
||||||
"guest": 0.0,
|
"guest": 0.0,
|
||||||
"guest_nice": 0.0,
|
"guest_nice": 0.0,
|
||||||
|
|
@ -924,7 +974,7 @@ Get plugin stats::
|
||||||
{"cpu_number": 8,
|
{"cpu_number": 8,
|
||||||
"guest": 0.0,
|
"guest": 0.0,
|
||||||
"guest_nice": 0.0,
|
"guest_nice": 0.0,
|
||||||
"idle": 0.0,
|
"idle": 1.0,
|
||||||
"iowait": 0.0,
|
"iowait": 0.0,
|
||||||
"irq": 0.0,
|
"irq": 0.0,
|
||||||
"key": "cpu_number",
|
"key": "cpu_number",
|
||||||
|
|
@ -932,7 +982,7 @@ Get plugin stats::
|
||||||
"softirq": 0.0,
|
"softirq": 0.0,
|
||||||
"steal": 0.0,
|
"steal": 0.0,
|
||||||
"system": 0.0,
|
"system": 0.0,
|
||||||
"total": 100.0,
|
"total": 99.0,
|
||||||
"user": 0.0},
|
"user": 0.0},
|
||||||
{"cpu_number": 9,
|
{"cpu_number": 9,
|
||||||
"guest": 0.0,
|
"guest": 0.0,
|
||||||
|
|
@ -1063,14 +1113,14 @@ Get plugin stats::
|
||||||
"label": "Ambient",
|
"label": "Ambient",
|
||||||
"type": "temperature_core",
|
"type": "temperature_core",
|
||||||
"unit": "C",
|
"unit": "C",
|
||||||
"value": 38,
|
"value": 36,
|
||||||
"warning": 0},
|
"warning": 0},
|
||||||
{"critical": None,
|
{"critical": None,
|
||||||
"key": "label",
|
"key": "label",
|
||||||
"label": "Ambient 3",
|
"label": "Ambient 3",
|
||||||
"type": "temperature_core",
|
"type": "temperature_core",
|
||||||
"unit": "C",
|
"unit": "C",
|
||||||
"value": 35,
|
"value": 29,
|
||||||
"warning": 0}]
|
"warning": 0}]
|
||||||
|
|
||||||
Fields descriptions:
|
Fields descriptions:
|
||||||
|
|
@ -1131,7 +1181,7 @@ Get a specific item when field matches the given value::
|
||||||
"label": "Ambient",
|
"label": "Ambient",
|
||||||
"type": "temperature_core",
|
"type": "temperature_core",
|
||||||
"unit": "C",
|
"unit": "C",
|
||||||
"value": 38,
|
"value": 36,
|
||||||
"warning": 0}]}
|
"warning": 0}]}
|
||||||
|
|
||||||
GET smart
|
GET smart
|
||||||
|
|
@ -1175,7 +1225,7 @@ GET uptime
|
||||||
Get plugin stats::
|
Get plugin stats::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/uptime
|
# curl http://localhost:61208/api/4/uptime
|
||||||
"11 days, 17:02:42"
|
"0:14:44"
|
||||||
|
|
||||||
GET version
|
GET version
|
||||||
-----------
|
-----------
|
||||||
|
|
@ -1183,7 +1233,7 @@ GET version
|
||||||
Get plugin stats::
|
Get plugin stats::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/version
|
# curl http://localhost:61208/api/4/version
|
||||||
"4.0.7"
|
"4.0.8"
|
||||||
|
|
||||||
GET wifi
|
GET wifi
|
||||||
--------
|
--------
|
||||||
|
|
@ -1192,8 +1242,8 @@ Get plugin stats::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/wifi
|
# curl http://localhost:61208/api/4/wifi
|
||||||
[{"key": "ssid",
|
[{"key": "ssid",
|
||||||
"quality_level": -62.0,
|
"quality_level": -66.0,
|
||||||
"quality_link": 48.0,
|
"quality_link": 44.0,
|
||||||
"ssid": "wlp0s20f3"}]
|
"ssid": "wlp0s20f3"}]
|
||||||
|
|
||||||
Get a specific field::
|
Get a specific field::
|
||||||
|
|
@ -1205,8 +1255,8 @@ Get a specific item when field matches the given value::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/wifi/ssid/wlp0s20f3
|
# curl http://localhost:61208/api/4/wifi/ssid/wlp0s20f3
|
||||||
{"wlp0s20f3": [{"key": "ssid",
|
{"wlp0s20f3": [{"key": "ssid",
|
||||||
"quality_level": -62.0,
|
"quality_level": -66.0,
|
||||||
"quality_link": 48.0,
|
"quality_link": 44.0,
|
||||||
"ssid": "wlp0s20f3"}]}
|
"ssid": "wlp0s20f3"}]}
|
||||||
|
|
||||||
GET all stats
|
GET all stats
|
||||||
|
|
@ -1251,34 +1301,34 @@ GET stats history
|
||||||
History of a plugin::
|
History of a plugin::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/cpu/history
|
# curl http://localhost:61208/api/4/cpu/history
|
||||||
{"system": [["2024-05-25T16:10:03.933630", 0.0],
|
{"system": [["2024-06-08T10:22:30.631056", 0.0],
|
||||||
["2024-05-25T16:10:04.963537", 0.0],
|
["2024-06-08T10:22:31.667772", 1.0],
|
||||||
["2024-05-25T16:10:06.018120", 0.0]],
|
["2024-06-08T10:22:32.723737", 1.0]],
|
||||||
"user": [["2024-05-25T16:10:03.933619", 1.0],
|
"user": [["2024-06-08T10:22:30.631046", 1.0],
|
||||||
["2024-05-25T16:10:04.963532", 1.0],
|
["2024-06-08T10:22:31.667765", 1.0],
|
||||||
["2024-05-25T16:10:06.018110", 1.0]]}
|
["2024-06-08T10:22:32.723728", 1.0]]}
|
||||||
|
|
||||||
Limit history to last 2 values::
|
Limit history to last 2 values::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/cpu/history/2
|
# curl http://localhost:61208/api/4/cpu/history/2
|
||||||
{"system": [["2024-05-25T16:10:04.963537", 0.0],
|
{"system": [["2024-06-08T10:22:31.667772", 1.0],
|
||||||
["2024-05-25T16:10:06.018120", 0.0]],
|
["2024-06-08T10:22:32.723737", 1.0]],
|
||||||
"user": [["2024-05-25T16:10:04.963532", 1.0],
|
"user": [["2024-06-08T10:22:31.667765", 1.0],
|
||||||
["2024-05-25T16:10:06.018110", 1.0]]}
|
["2024-06-08T10:22:32.723728", 1.0]]}
|
||||||
|
|
||||||
History for a specific field::
|
History for a specific field::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/cpu/system/history
|
# curl http://localhost:61208/api/4/cpu/system/history
|
||||||
{"system": [["2024-05-25T16:10:02.825532", 0.0],
|
{"system": [["2024-06-08T10:22:29.515717", 0.0],
|
||||||
["2024-05-25T16:10:03.933630", 0.0],
|
["2024-06-08T10:22:30.631056", 0.0],
|
||||||
["2024-05-25T16:10:04.963537", 0.0],
|
["2024-06-08T10:22:31.667772", 1.0],
|
||||||
["2024-05-25T16:10:06.018120", 0.0]]}
|
["2024-06-08T10:22:32.723737", 1.0]]}
|
||||||
|
|
||||||
Limit history for a specific field to last 2 values::
|
Limit history for a specific field to last 2 values::
|
||||||
|
|
||||||
# curl http://localhost:61208/api/4/cpu/system/history
|
# curl http://localhost:61208/api/4/cpu/system/history
|
||||||
{"system": [["2024-05-25T16:10:04.963537", 0.0],
|
{"system": [["2024-06-08T10:22:31.667772", 1.0],
|
||||||
["2024-05-25T16:10:06.018120", 0.0]]}
|
["2024-06-08T10:22:32.723737", 1.0]]}
|
||||||
|
|
||||||
GET limits (used for thresholds)
|
GET limits (used for thresholds)
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ You can place your ``glances.conf`` file in the following locations:
|
||||||
``*BSD`` ~/.config/glances/, /usr/local/etc/glances/, /usr/share/docs/glances/
|
``*BSD`` ~/.config/glances/, /usr/local/etc/glances/, /usr/share/docs/glances/
|
||||||
``macOS`` ~/.config/glances/, ~/Library/Application Support/glances/, /usr/local/etc/glances/, /usr/share/docs/glances/
|
``macOS`` ~/.config/glances/, ~/Library/Application Support/glances/, /usr/local/etc/glances/, /usr/share/docs/glances/
|
||||||
``Windows`` %APPDATA%\\glances\\glances.conf
|
``Windows`` %APPDATA%\\glances\\glances.conf
|
||||||
|
``All`` + <venv_root_folder>/share/doc/glances/
|
||||||
==================== =============================================================
|
==================== =============================================================
|
||||||
|
|
||||||
- On Windows XP, ``%APPDATA%`` is: ``C:\Documents and Settings\<USERNAME>\Application Data``.
|
- On Windows XP, ``%APPDATA%`` is: ``C:\Documents and Settings\<USERNAME>\Application Data``.
|
||||||
|
|
@ -59,17 +60,41 @@ than a second one concerning the user interface:
|
||||||
.. code-block:: ini
|
.. code-block:: ini
|
||||||
|
|
||||||
[outputs]
|
[outputs]
|
||||||
|
# Options for all UIs
|
||||||
|
#--------------------
|
||||||
# Separator in the Curses and WebUI interface (between top and others plugins)
|
# Separator in the Curses and WebUI interface (between top and others plugins)
|
||||||
separator=True
|
separator=True
|
||||||
# Set the the Curses and WebUI interface left menu plugin list (comma-separated)
|
# Set the the Curses and WebUI interface left menu plugin list (comma-separated)
|
||||||
#left_menu=network,wifi,connections,ports,diskio,fs,irq,folders,raid,smart,sensors,now
|
#left_menu=network,wifi,connections,ports,diskio,fs,irq,folders,raid,smart,sensors,now
|
||||||
# Limit the number of processes to display (for the WebUI)
|
# Limit the number of processes to display (in the WebUI)
|
||||||
max_processes_display=25
|
max_processes_display=25
|
||||||
# Set the URL prefix (for the WebUI and the API)
|
# Options for WebUI
|
||||||
|
#------------------
|
||||||
|
# Set URL prefix for the WebUI and the API
|
||||||
# Example: url_prefix=/glances/ => http://localhost/glances/
|
# Example: url_prefix=/glances/ => http://localhost/glances/
|
||||||
# The final / is mandatory
|
# Note: The final / is mandatory
|
||||||
# Default is no prefix (/)
|
# Default is no prefix (/)
|
||||||
#url_prefix=/glances/
|
#url_prefix=/glances/
|
||||||
|
# Set root path for WebUI statics files
|
||||||
|
# Why ? On Debian system, WebUI statics files are not provided.
|
||||||
|
# You can download it in a specific folder
|
||||||
|
# thanks to https://github.com/nicolargo/glances/issues/2021
|
||||||
|
# then configure this folder with the webui_root_path key
|
||||||
|
# Default is folder where glances_restfull_api.py is hosted
|
||||||
|
#webui_root_path=
|
||||||
|
# CORS options
|
||||||
|
# Comma separated list of origins that should be permitted to make cross-origin requests.
|
||||||
|
# Default is *
|
||||||
|
#cors_origins=*
|
||||||
|
# Indicate that cookies should be supported for cross-origin requests.
|
||||||
|
# Default is True
|
||||||
|
#cors_credentials=True
|
||||||
|
# Comma separated list of HTTP methods that should be allowed for cross-origin requests.
|
||||||
|
# Default is *
|
||||||
|
#cors_methods=*
|
||||||
|
# Comma separated list of HTTP request headers that should be supported for cross-origin requests.
|
||||||
|
# Default is *
|
||||||
|
#cors_headers=*
|
||||||
|
|
||||||
Each plugin, export module, and application monitoring process (AMP) can
|
Each plugin, export module, and application monitoring process (AMP) can
|
||||||
have a section. Below is an example for the CPU plugin:
|
have a section. Below is an example for the CPU plugin:
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||||
..
|
..
|
||||||
.TH "GLANCES" "1" "May 25, 2024" "4.0.7" "Glances"
|
.TH "GLANCES" "1" "Jun 08, 2024" "4.0.8" "Glances"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
glances \- An eye on your system
|
glances \- An eye on your system
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
|
@ -585,6 +585,15 @@ T} T{
|
||||||
%APPDATA%\eglances\eglances.conf
|
%APPDATA%\eglances\eglances.conf
|
||||||
T}
|
T}
|
||||||
_
|
_
|
||||||
|
T{
|
||||||
|
\fBAll\fP
|
||||||
|
T} T{
|
||||||
|
.INDENT 0.0
|
||||||
|
.IP \(bu 2
|
||||||
|
<venv_root_folder>/share/doc/glances/
|
||||||
|
.UNINDENT
|
||||||
|
T}
|
||||||
|
_
|
||||||
.TE
|
.TE
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.IP \(bu 2
|
.IP \(bu 2
|
||||||
|
|
@ -632,17 +641,41 @@ than a second one concerning the user interface:
|
||||||
.nf
|
.nf
|
||||||
.ft C
|
.ft C
|
||||||
[outputs]
|
[outputs]
|
||||||
|
# Options for all UIs
|
||||||
|
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
|
||||||
# Separator in the Curses and WebUI interface (between top and others plugins)
|
# Separator in the Curses and WebUI interface (between top and others plugins)
|
||||||
separator=True
|
separator=True
|
||||||
# Set the the Curses and WebUI interface left menu plugin list (comma\-separated)
|
# Set the the Curses and WebUI interface left menu plugin list (comma\-separated)
|
||||||
#left_menu=network,wifi,connections,ports,diskio,fs,irq,folders,raid,smart,sensors,now
|
#left_menu=network,wifi,connections,ports,diskio,fs,irq,folders,raid,smart,sensors,now
|
||||||
# Limit the number of processes to display (for the WebUI)
|
# Limit the number of processes to display (in the WebUI)
|
||||||
max_processes_display=25
|
max_processes_display=25
|
||||||
# Set the URL prefix (for the WebUI and the API)
|
# Options for WebUI
|
||||||
|
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
|
||||||
|
# Set URL prefix for the WebUI and the API
|
||||||
# Example: url_prefix=/glances/ => http://localhost/glances/
|
# Example: url_prefix=/glances/ => http://localhost/glances/
|
||||||
# The final / is mandatory
|
# Note: The final / is mandatory
|
||||||
# Default is no prefix (/)
|
# Default is no prefix (/)
|
||||||
#url_prefix=/glances/
|
#url_prefix=/glances/
|
||||||
|
# Set root path for WebUI statics files
|
||||||
|
# Why ? On Debian system, WebUI statics files are not provided.
|
||||||
|
# You can download it in a specific folder
|
||||||
|
# thanks to https://github.com/nicolargo/glances/issues/2021
|
||||||
|
# then configure this folder with the webui_root_path key
|
||||||
|
# Default is folder where glances_restfull_api.py is hosted
|
||||||
|
#webui_root_path=
|
||||||
|
# CORS options
|
||||||
|
# Comma separated list of origins that should be permitted to make cross\-origin requests.
|
||||||
|
# Default is *
|
||||||
|
#cors_origins=*
|
||||||
|
# Indicate that cookies should be supported for cross\-origin requests.
|
||||||
|
# Default is True
|
||||||
|
#cors_credentials=True
|
||||||
|
# Comma separated list of HTTP methods that should be allowed for cross\-origin requests.
|
||||||
|
# Default is *
|
||||||
|
#cors_methods=*
|
||||||
|
# Comma separated list of HTTP request headers that should be supported for cross\-origin requests.
|
||||||
|
# Default is *
|
||||||
|
#cors_headers=*
|
||||||
.ft P
|
.ft P
|
||||||
.fi
|
.fi
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import tracemalloc
|
||||||
# Global name
|
# Global name
|
||||||
# Version should start and end with a numerical char
|
# Version should start and end with a numerical char
|
||||||
# See https://packaging.python.org/specifications/core-metadata/#version
|
# See https://packaging.python.org/specifications/core-metadata/#version
|
||||||
__version__ = '4.0.7'
|
__version__ = '4.0.8'
|
||||||
__apiversion__ = '4'
|
__apiversion__ = '4'
|
||||||
__author__ = 'Nicolas Hennion <nicolas@nicolargo.com>'
|
__author__ = 'Nicolas Hennion <nicolas@nicolargo.com>'
|
||||||
__license__ = 'LGPLv3'
|
__license__ = 'LGPLv3'
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,9 @@ one_line=false
|
||||||
command=foo status
|
command=foo status
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from subprocess import STDOUT, CalledProcessError, check_output
|
|
||||||
|
|
||||||
from glances.amps.amp import GlancesAmp
|
from glances.amps.amp import GlancesAmp
|
||||||
from glances.globals import to_ascii, u
|
|
||||||
from glances.logger import logger
|
from glances.logger import logger
|
||||||
|
from glances.secure import secure_popen
|
||||||
|
|
||||||
|
|
||||||
class Amp(GlancesAmp):
|
class Amp(GlancesAmp):
|
||||||
|
|
@ -68,10 +66,7 @@ class Amp(GlancesAmp):
|
||||||
# Run command(s)
|
# Run command(s)
|
||||||
# Comma separated commands can be executed
|
# Comma separated commands can be executed
|
||||||
try:
|
try:
|
||||||
msg = ''
|
self.set_result(secure_popen(res).rstrip())
|
||||||
for cmd in res.split(';'):
|
except Exception as e:
|
||||||
msg += u(check_output(cmd.split(), stderr=STDOUT))
|
|
||||||
self.set_result(to_ascii(msg.rstrip()))
|
|
||||||
except CalledProcessError as e:
|
|
||||||
self.set_result(e.output)
|
self.set_result(e.output)
|
||||||
return self.result()
|
return self.result()
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,10 @@ one_line=true
|
||||||
service_cmd=/usr/bin/service --status-all
|
service_cmd=/usr/bin/service --status-all
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from subprocess import STDOUT, check_output
|
|
||||||
|
|
||||||
from glances.amps.amp import GlancesAmp
|
from glances.amps.amp import GlancesAmp
|
||||||
from glances.globals import iteritems
|
from glances.globals import iteritems
|
||||||
from glances.logger import logger
|
from glances.logger import logger
|
||||||
|
from glances.secure import secure_popen
|
||||||
|
|
||||||
|
|
||||||
class Amp(GlancesAmp):
|
class Amp(GlancesAmp):
|
||||||
|
|
@ -58,8 +57,9 @@ class Amp(GlancesAmp):
|
||||||
# Get the systemctl status
|
# Get the systemctl status
|
||||||
logger.debug('{}: Update stats using service {}'.format(self.NAME, self.get('service_cmd')))
|
logger.debug('{}: Update stats using service {}'.format(self.NAME, self.get('service_cmd')))
|
||||||
try:
|
try:
|
||||||
res = check_output(self.get('service_cmd').split(), stderr=STDOUT).decode('utf-8')
|
# res = check_output(self.get('service_cmd').split(), stderr=STDOUT).decode('utf-8')
|
||||||
except OSError as e:
|
res = secure_popen(self.get('service_cmd'))
|
||||||
|
except Exception as e:
|
||||||
logger.debug(f'{self.NAME}: Error while executing service ({e})')
|
logger.debug(f'{self.NAME}: Error while executing service ({e})')
|
||||||
else:
|
else:
|
||||||
status = {'running': 0, 'stopped': 0, 'upstart': 0}
|
status = {'running': 0, 'stopped': 0, 'upstart': 0}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import ujson
|
import orjson
|
||||||
|
|
||||||
from glances import __version__
|
from glances import __version__
|
||||||
from glances.globals import Fault, ProtocolError, ServerProxy, Transport
|
from glances.globals import Fault, ProtocolError, ServerProxy, Transport
|
||||||
|
|
@ -118,7 +118,7 @@ class GlancesClient:
|
||||||
if __version__.split('.')[0] == client_version.split('.')[0]:
|
if __version__.split('.')[0] == client_version.split('.')[0]:
|
||||||
# Init stats
|
# Init stats
|
||||||
self.stats = GlancesStatsClient(config=self.config, args=self.args)
|
self.stats = GlancesStatsClient(config=self.config, args=self.args)
|
||||||
self.stats.set_plugins(ujson.loads(self.client.getAllPlugins()))
|
self.stats.set_plugins(orjson.loads(self.client.getAllPlugins()))
|
||||||
logger.debug(f"Client version: {__version__} / Server version: {client_version}")
|
logger.debug(f"Client version: {__version__} / Server version: {client_version}")
|
||||||
else:
|
else:
|
||||||
self.log_and_exit(
|
self.log_and_exit(
|
||||||
|
|
@ -195,7 +195,7 @@ class GlancesClient:
|
||||||
"""
|
"""
|
||||||
# Update the stats
|
# Update the stats
|
||||||
try:
|
try:
|
||||||
server_stats = ujson.loads(self.client.getAll())
|
server_stats = orjson.loads(self.client.getAll())
|
||||||
except OSError:
|
except OSError:
|
||||||
# Client cannot get server stats
|
# Client cannot get server stats
|
||||||
return "Disconnected"
|
return "Disconnected"
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
import ujson
|
import orjson
|
||||||
|
|
||||||
from glances.autodiscover import GlancesAutoDiscoverServer
|
from glances.autodiscover import GlancesAutoDiscoverServer
|
||||||
from glances.client import GlancesClient, GlancesClientTransport
|
from glances.client import GlancesClient, GlancesClientTransport
|
||||||
|
|
@ -95,12 +95,12 @@ class GlancesClientBrowser:
|
||||||
# Mandatory stats
|
# Mandatory stats
|
||||||
try:
|
try:
|
||||||
# CPU%
|
# CPU%
|
||||||
cpu_percent = 100 - ujson.loads(s.getCpu())['idle']
|
cpu_percent = 100 - orjson.loads(s.getPlugin('cpu'))['idle']
|
||||||
server['cpu_percent'] = f'{cpu_percent:.1f}'
|
server['cpu_percent'] = f'{cpu_percent:.1f}'
|
||||||
# MEM%
|
# MEM%
|
||||||
server['mem_percent'] = ujson.loads(s.getMem())['percent']
|
server['mem_percent'] = orjson.loads(s.getPlugin('mem'))['percent']
|
||||||
# OS (Human Readable name)
|
# OS (Human Readable name)
|
||||||
server['hr_name'] = ujson.loads(s.getSystem())['hr_name']
|
server['hr_name'] = orjson.loads(s.getPlugin('system'))['hr_name']
|
||||||
except (OSError, Fault, KeyError) as e:
|
except (OSError, Fault, KeyError) as e:
|
||||||
logger.debug(f"Error while grabbing stats form server ({e})")
|
logger.debug(f"Error while grabbing stats form server ({e})")
|
||||||
server['status'] = 'OFFLINE'
|
server['status'] = 'OFFLINE'
|
||||||
|
|
@ -120,7 +120,7 @@ class GlancesClientBrowser:
|
||||||
# Optional stats (load is not available on Windows OS)
|
# Optional stats (load is not available on Windows OS)
|
||||||
try:
|
try:
|
||||||
# LOAD
|
# LOAD
|
||||||
load_min5 = ujson.loads(s.getLoad())['min5']
|
load_min5 = orjson.loads(s.getPlugin('load'))['min5']
|
||||||
server['load_min5'] = f'{load_min5:.2f}'
|
server['load_min5'] = f'{load_min5:.2f}'
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"Error while grabbing stats form server ({e})")
|
logger.warning(f"Error while grabbing stats form server ({e})")
|
||||||
|
|
|
||||||
|
|
@ -81,16 +81,29 @@ def default_config_dir():
|
||||||
- Linux, SunOS, *BSD, macOS: /usr/share/doc (as defined in the setup.py files)
|
- Linux, SunOS, *BSD, macOS: /usr/share/doc (as defined in the setup.py files)
|
||||||
- Windows: %APPDATA%\glances
|
- Windows: %APPDATA%\glances
|
||||||
"""
|
"""
|
||||||
if LINUX or SUNOS or BSD or MACOS:
|
path = []
|
||||||
path = '/usr/share/doc'
|
# Add venv path (solve issue #2803)
|
||||||
else:
|
if in_virtualenv():
|
||||||
path = os.environ.get('APPDATA')
|
path.append(os.path.join(sys.prefix, 'share', 'doc', 'glances'))
|
||||||
if path is None:
|
|
||||||
path = ''
|
|
||||||
else:
|
|
||||||
path = os.path.join(path, 'glances')
|
|
||||||
|
|
||||||
return [path]
|
# Add others system path
|
||||||
|
if LINUX or SUNOS or BSD or MACOS:
|
||||||
|
path.append('/usr/share/doc')
|
||||||
|
else:
|
||||||
|
path.append(os.environ.get('APPDATA'))
|
||||||
|
|
||||||
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
def in_virtualenv():
|
||||||
|
# Source: https://stackoverflow.com/questions/1871549/how-to-determine-if-python-is-running-inside-a-virtualenv/1883251#1883251
|
||||||
|
return sys.prefix != get_base_prefix_compat()
|
||||||
|
|
||||||
|
|
||||||
|
def get_base_prefix_compat():
|
||||||
|
"""Get base/real prefix, or sys.prefix if there is none."""
|
||||||
|
# Source: https://stackoverflow.com/questions/1871549/how-to-determine-if-python-is-running-inside-a-virtualenv/1883251#1883251
|
||||||
|
return getattr(sys, "base_prefix", None) or getattr(sys, "real_prefix", None) or sys.prefix
|
||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
|
|
@ -104,6 +117,7 @@ class Config:
|
||||||
self.config_dir = config_dir
|
self.config_dir = config_dir
|
||||||
self.config_filename = 'glances.conf'
|
self.config_filename = 'glances.conf'
|
||||||
self._loaded_config_file = None
|
self._loaded_config_file = None
|
||||||
|
self._config_file_paths = self.config_file_paths()
|
||||||
|
|
||||||
# Re pattern for optimize research of `foo`
|
# Re pattern for optimize research of `foo`
|
||||||
self.re_pattern = re.compile(r'(\`.+?\`)')
|
self.re_pattern = re.compile(r'(\`.+?\`)')
|
||||||
|
|
@ -151,7 +165,7 @@ class Config:
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
"""Read the config file, if it exists. Using defaults otherwise."""
|
"""Read the config file, if it exists. Using defaults otherwise."""
|
||||||
for config_file in self.config_file_paths():
|
for config_file in self._config_file_paths:
|
||||||
logger.debug(f'Search glances.conf file in {config_file}')
|
logger.debug(f'Search glances.conf file in {config_file}')
|
||||||
if os.path.exists(config_file):
|
if os.path.exists(config_file):
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ class CpuPercent:
|
||||||
self.percpu_percent = []
|
self.percpu_percent = []
|
||||||
|
|
||||||
# Get CPU name
|
# Get CPU name
|
||||||
self.__get_cpu_name()
|
self.cpu_info['cpu_name'] = self.__get_cpu_name()
|
||||||
|
|
||||||
# cached_timer_cpu is the minimum time interval between stats updates
|
# cached_timer_cpu is the minimum time interval between stats updates
|
||||||
# since last update is passed (will retrieve old cached info instead)
|
# since last update is passed (will retrieve old cached info instead)
|
||||||
|
|
@ -71,12 +71,18 @@ class CpuPercent:
|
||||||
|
|
||||||
def __get_cpu_name(self):
|
def __get_cpu_name(self):
|
||||||
# Get the CPU name once from the /proc/cpuinfo file
|
# Get the CPU name once from the /proc/cpuinfo file
|
||||||
# TODO: Multisystem...
|
# Read the first line with the "model name"
|
||||||
|
ret = None
|
||||||
try:
|
try:
|
||||||
self.cpu_info['cpu_name'] = open('/proc/cpuinfo').readlines()[4].split(':')[1].strip()
|
cpuinfo_file = open('/proc/cpuinfo').readlines()
|
||||||
except (FileNotFoundError, PermissionError, IndexError, KeyError, AttributeError):
|
except (FileNotFoundError, PermissionError):
|
||||||
self.cpu_info['cpu_name'] = 'CPU'
|
pass
|
||||||
return self.cpu_info['cpu_name']
|
else:
|
||||||
|
for line in cpuinfo_file:
|
||||||
|
if line.startswith('model name'):
|
||||||
|
ret = line.split(':')[1].strip()
|
||||||
|
break
|
||||||
|
return ret if ret else 'CPU'
|
||||||
|
|
||||||
def __get_cpu(self):
|
def __get_cpu(self):
|
||||||
"""Update and/or return the CPU using the psutil library."""
|
"""Update and/or return the CPU using the psutil library."""
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ from urllib.request import Request, urlopen
|
||||||
from xmlrpc.client import Fault, ProtocolError, Server, ServerProxy, Transport
|
from xmlrpc.client import Fault, ProtocolError, Server, ServerProxy, Transport
|
||||||
from xmlrpc.server import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer
|
from xmlrpc.server import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer
|
||||||
|
|
||||||
import ujson
|
import orjson
|
||||||
|
|
||||||
# Correct issue #1025 by monkey path the xmlrpc lib
|
# Correct issue #1025 by monkey path the xmlrpc lib
|
||||||
from defusedxml.xmlrpc import monkey_patch
|
from defusedxml.xmlrpc import monkey_patch
|
||||||
|
|
@ -309,9 +309,9 @@ def json_dumps(data):
|
||||||
Manage the issue #815 for Windows OS with UnicodeDecodeError catching.
|
Manage the issue #815 for Windows OS with UnicodeDecodeError catching.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return ujson.dumps(data)
|
return orjson.dumps(data)
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
return ujson.dumps(data, ensure_ascii=False)
|
return orjson.dumps(data, ensure_ascii=False)
|
||||||
|
|
||||||
|
|
||||||
def dictlist(data, item):
|
def dictlist(data, item):
|
||||||
|
|
|
||||||
|
|
@ -249,15 +249,19 @@ class GlancesCursesBrowser(_GlancesCurses):
|
||||||
screen_x = self.screen.getmaxyx()[1]
|
screen_x = self.screen.getmaxyx()[1]
|
||||||
screen_y = self.screen.getmaxyx()[0]
|
screen_y = self.screen.getmaxyx()[0]
|
||||||
stats_max = screen_y - 3
|
stats_max = screen_y - 3
|
||||||
stats_len = len(stats)
|
|
||||||
|
|
||||||
self._page_max_lines = stats_max
|
self._page_max_lines = stats_max
|
||||||
self._page_max = int(math.ceil(stats_len / stats_max))
|
self._page_max = int(math.ceil(len(stats) / stats_max))
|
||||||
# Init position
|
|
||||||
x = 0
|
|
||||||
y = 0
|
|
||||||
|
|
||||||
# Display top header
|
# Display header
|
||||||
|
x, y = self.__display_header(stats, 0, 0, screen_x, screen_y)
|
||||||
|
|
||||||
|
# Display Glances server list
|
||||||
|
# ================================
|
||||||
|
return self.__display_server_list(stats, x, y, screen_x, screen_y)
|
||||||
|
|
||||||
|
def __display_header(self, stats, x, y, screen_x, screen_y):
|
||||||
|
stats_len = len(stats)
|
||||||
|
stats_max = screen_y - 3
|
||||||
if stats_len == 0:
|
if stats_len == 0:
|
||||||
if self.first_scan and not self.args.disable_autodiscover:
|
if self.first_scan and not self.args.disable_autodiscover:
|
||||||
msg = 'Glances is scanning your network. Please wait...'
|
msg = 'Glances is scanning your network. Please wait...'
|
||||||
|
|
@ -282,11 +286,14 @@ class GlancesCursesBrowser(_GlancesCurses):
|
||||||
msg = f'{page_lines} servers displayed.({self._current_page + 1}/{self._page_max}) {status_count}'
|
msg = f'{page_lines} servers displayed.({self._current_page + 1}/{self._page_max}) {status_count}'
|
||||||
self.term_window.addnstr(y + 1, x, msg, screen_x - x)
|
self.term_window.addnstr(y + 1, x, msg, screen_x - x)
|
||||||
|
|
||||||
if stats_len == 0:
|
return x, y
|
||||||
|
|
||||||
|
def __display_server_list(self, stats, x, y, screen_x, screen_y):
|
||||||
|
if len(stats) == 0:
|
||||||
|
# No server to display
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Display the Glances server list
|
stats_max = screen_y - 3
|
||||||
# ================================
|
|
||||||
|
|
||||||
# Table of table
|
# Table of table
|
||||||
# Item description: [stats_id, column name, column size]
|
# Item description: [stats_id, column name, column size]
|
||||||
|
|
|
||||||
|
|
@ -130,11 +130,11 @@ class GlancesRestfulApi:
|
||||||
# https://fastapi.tiangolo.com/tutorial/cors/
|
# https://fastapi.tiangolo.com/tutorial/cors/
|
||||||
self._app.add_middleware(
|
self._app.add_middleware(
|
||||||
CORSMiddleware,
|
CORSMiddleware,
|
||||||
# allow_origins=["*"],
|
# Related to https://github.com/nicolargo/glances/issues/2812
|
||||||
allow_origins=[self.bind_url],
|
allow_origins=config.get_list_value('outputs', 'cors_origins', default=["*"]),
|
||||||
allow_credentials=True,
|
allow_credentials=config.get_bool_value('outputs', 'cors_credentials', default=True),
|
||||||
allow_methods=["*"],
|
allow_methods=config.get_list_value('outputs', 'cors_methods', default=["*"]),
|
||||||
allow_headers=["*"],
|
allow_headers=config.get_list_value('outputs', 'cors_headers', default=["*"]),
|
||||||
)
|
)
|
||||||
|
|
||||||
# FastAPI Enable GZIP compression
|
# FastAPI Enable GZIP compression
|
||||||
|
|
|
||||||
|
|
@ -218,23 +218,23 @@ body {
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loading page */
|
// /* Loading page */
|
||||||
|
|
||||||
#loading-page .glances-logo {
|
// #loading-page .glances-logo {
|
||||||
background: url('../images/glances.png') no-repeat center center;
|
// background: url('../images/glances.png') no-repeat center center;
|
||||||
background-size: contain;
|
// background-size: contain;
|
||||||
}
|
// }
|
||||||
|
|
||||||
@media (max-width: 750px) {
|
// @media (max-width: 750px) {
|
||||||
#loading-page .glances-logo {
|
// #loading-page .glances-logo {
|
||||||
height: 400px;
|
// height: 400px;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
@media (min-width: 750px) {
|
// @media (min-width: 750px) {
|
||||||
#loading-page .glances-logo {
|
// #loading-page .glances-logo {
|
||||||
height: 500px;
|
// height: 500px;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-if="!dataLoaded" class="container-fluid" id="loading-page">
|
<div v-if="!dataLoaded" class="container-fluid" id="loading-page">
|
||||||
<div class="glances-logo"></div>
|
<div class="loader">Glances is loading...</div>
|
||||||
<div class="loader">Loading...</div>
|
|
||||||
</div>
|
</div>
|
||||||
<glances-help v-else-if="args.help_tag"></glances-help>
|
<glances-help v-else-if="args.help_tag"></glances-help>
|
||||||
<main v-else>
|
<main v-else>
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 49 KiB |
File diff suppressed because one or more lines are too long
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
from ujson import loads
|
from orjson import loads
|
||||||
|
|
||||||
from glances.globals import queue, urlopen_auth
|
from glances.globals import queue, urlopen_auth
|
||||||
from glances.logger import logger
|
from glances.logger import logger
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,11 @@ class PluginModel(GlancesPluginModel):
|
||||||
self.hide_zero = False
|
self.hide_zero = False
|
||||||
self.hide_zero_fields = ['bytes_recv', 'bytes_sent']
|
self.hide_zero_fields = ['bytes_recv', 'bytes_sent']
|
||||||
|
|
||||||
|
# Add support for automatically hiding network interfaces that are down
|
||||||
|
# or that don't have any IP addresses #2799
|
||||||
|
self.hide_no_up = config.get_bool_value(self.plugin_name, 'hide_no_up', default=False)
|
||||||
|
self.hide_no_ip = config.get_bool_value(self.plugin_name, 'hide_no_ip', default=False)
|
||||||
|
|
||||||
# Force a first update because we need two updates to have the first stat
|
# Force a first update because we need two updates to have the first stat
|
||||||
self.update()
|
self.update()
|
||||||
self.refresh_timer.set(0)
|
self.refresh_timer.set(0)
|
||||||
|
|
@ -140,10 +145,21 @@ class PluginModel(GlancesPluginModel):
|
||||||
net_status = {}
|
net_status = {}
|
||||||
try:
|
try:
|
||||||
net_status = psutil.net_if_stats()
|
net_status = psutil.net_if_stats()
|
||||||
|
net_addrs = psutil.net_if_addrs()
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
# see psutil #797/glances #1106
|
# see psutil #797/glances #1106
|
||||||
logger.debug(f'Can not get network interface status ({e})')
|
logger.debug(f'Can not get network interface status ({e})')
|
||||||
|
|
||||||
|
# Filter interfaces (related to #2799)
|
||||||
|
if self.hide_no_up:
|
||||||
|
net_status = {k: v for k, v in net_status.items() if v.isup}
|
||||||
|
if self.hide_no_ip:
|
||||||
|
net_status = {
|
||||||
|
k: v
|
||||||
|
for k, v in net_status.items()
|
||||||
|
if k in net_addrs and any(a.family != psutil.AF_LINK for a in net_addrs[k])
|
||||||
|
}
|
||||||
|
|
||||||
for interface_name, interface_stat in net_io_counters.items():
|
for interface_name, interface_stat in net_io_counters.items():
|
||||||
# Do not take hidden interface into account
|
# Do not take hidden interface into account
|
||||||
# or KeyError: 'eth0' when interface is not connected #1348
|
# or KeyError: 'eth0' when interface is not connected #1348
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ class GlancesPluginModel:
|
||||||
# Init the limits (configuration keys) dictionary
|
# Init the limits (configuration keys) dictionary
|
||||||
self._limits = {}
|
self._limits = {}
|
||||||
if config is not None:
|
if config is not None:
|
||||||
logger.debug(f'Load section {self.plugin_name} in {config.config_file_paths()}')
|
logger.debug(f'Load section {self.plugin_name} in Glances configuration file')
|
||||||
self.load_limits(config=config)
|
self.load_limits(config=config)
|
||||||
|
|
||||||
# Init the alias (dictionnary)
|
# Init the alias (dictionnary)
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ def secure_popen(cmd):
|
||||||
"""
|
"""
|
||||||
ret = ''
|
ret = ''
|
||||||
|
|
||||||
# Split by multiple commands '&&'
|
# Split by multiple commands (only '&&' separator is supported)
|
||||||
for c in cmd.split('&&'):
|
for c in cmd.split('&&'):
|
||||||
ret += __secure_popen(c)
|
ret += __secure_popen(c)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,14 @@
|
||||||
|
|
||||||
"""Manage the Glances server."""
|
"""Manage the Glances server."""
|
||||||
|
|
||||||
|
import json
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
from base64 import b64decode
|
from base64 import b64decode
|
||||||
|
|
||||||
from glances import __version__
|
from glances import __version__
|
||||||
from glances.autodiscover import GlancesAutoDiscoverClient
|
from glances.autodiscover import GlancesAutoDiscoverClient
|
||||||
from glances.globals import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer, json_dumps
|
from glances.globals import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer
|
||||||
from glances.logger import logger
|
from glances.logger import logger
|
||||||
from glances.stats_server import GlancesStatsServer
|
from glances.stats_server import GlancesStatsServer
|
||||||
from glances.timer import Timer
|
from glances.timer import Timer
|
||||||
|
|
@ -140,39 +141,28 @@ class GlancesInstance:
|
||||||
def getAll(self):
|
def getAll(self):
|
||||||
# Update and return all the stats
|
# Update and return all the stats
|
||||||
self.__update__()
|
self.__update__()
|
||||||
return json_dumps(self.stats.getAll())
|
return json.dumps(self.stats.getAll())
|
||||||
|
|
||||||
def getAllPlugins(self):
|
def getAllPlugins(self):
|
||||||
# Return the plugins list
|
# Return the plugins list
|
||||||
return json_dumps(self.stats.getPluginsList())
|
return json.dumps(self.stats.getPluginsList())
|
||||||
|
|
||||||
def getAllLimits(self):
|
def getAllLimits(self):
|
||||||
# Return all the plugins limits
|
# Return all the plugins limits
|
||||||
return json_dumps(self.stats.getAllLimitsAsDict())
|
return json.dumps(self.stats.getAllLimitsAsDict())
|
||||||
|
|
||||||
def getAllViews(self):
|
def getAllViews(self):
|
||||||
# Return all the plugins views
|
# Return all the plugins views
|
||||||
return json_dumps(self.stats.getAllViewsAsDict())
|
return json.dumps(self.stats.getAllViewsAsDict())
|
||||||
|
|
||||||
def __getattr__(self, item):
|
def getPlugin(self, plugin):
|
||||||
"""Overwrite the getattr method in case of attribute is not found.
|
# Update and return the plugin stat
|
||||||
|
self.__update__()
|
||||||
|
return json.dumps(self.stats.get_plugin(plugin).get_raw())
|
||||||
|
|
||||||
The goal is to dynamically generate the API get'Stats'() methods.
|
def getPluginView(self, plugin):
|
||||||
"""
|
# Update and return the plugin view
|
||||||
header = 'get'
|
return json.dumps(self.stats.get_plugin(plugin).get_views())
|
||||||
# Check if the attribute starts with 'get'
|
|
||||||
if item.startswith(header):
|
|
||||||
try:
|
|
||||||
# Update the stat
|
|
||||||
self.__update__()
|
|
||||||
# Return the attribute
|
|
||||||
return getattr(self.stats, item)
|
|
||||||
except Exception:
|
|
||||||
# The method is not found for the plugin
|
|
||||||
raise AttributeError(item)
|
|
||||||
else:
|
|
||||||
# Default behavior
|
|
||||||
raise AttributeError(item)
|
|
||||||
|
|
||||||
|
|
||||||
class GlancesServer:
|
class GlancesServer:
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ class GlancesStats:
|
||||||
# Get the plugin instance
|
# Get the plugin instance
|
||||||
plugin = self._plugins[plugname]
|
plugin = self._plugins[plugname]
|
||||||
if hasattr(plugin, 'get_json_views'):
|
if hasattr(plugin, 'get_json_views'):
|
||||||
# The method get_views exist, return it
|
# The method get_json_views exist, return it
|
||||||
return getattr(plugin, 'get_json_views')
|
return getattr(plugin, 'get_json_views')
|
||||||
# The method get_views is not found for the plugin
|
# The method get_views is not found for the plugin
|
||||||
raise AttributeError(item)
|
raise AttributeError(item)
|
||||||
|
|
@ -61,9 +61,9 @@ class GlancesStats:
|
||||||
plugname = item[len('get') :].lower()
|
plugname = item[len('get') :].lower()
|
||||||
# Get the plugin instance
|
# Get the plugin instance
|
||||||
plugin = self._plugins[plugname]
|
plugin = self._plugins[plugname]
|
||||||
if hasattr(plugin, 'get_stats'):
|
if hasattr(plugin, 'get_json'):
|
||||||
# The method get_stats exist, return it
|
# The method get_json exist, return it
|
||||||
return getattr(plugin, 'get_stats')
|
return getattr(plugin, 'get_json')
|
||||||
# The method get_stats is not found for the plugin
|
# The method get_stats is not found for the plugin
|
||||||
raise AttributeError(item)
|
raise AttributeError(item)
|
||||||
# Default behavior
|
# Default behavior
|
||||||
|
|
@ -358,11 +358,17 @@ class GlancesStats:
|
||||||
return self._plugins
|
return self._plugins
|
||||||
|
|
||||||
def get_plugin(self, plugin_name):
|
def get_plugin(self, plugin_name):
|
||||||
"""Return the plugin name."""
|
"""Return the plugin stats."""
|
||||||
if plugin_name in self._plugins:
|
if plugin_name in self._plugins:
|
||||||
return self._plugins[plugin_name]
|
return self._plugins[plugin_name]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def get_plugin_view(self, plugin_name):
|
||||||
|
"""Return the plugin views."""
|
||||||
|
if plugin_name in self._plugins:
|
||||||
|
return self._plugins[plugin_name].get_views()
|
||||||
|
return None
|
||||||
|
|
||||||
def end(self):
|
def end(self):
|
||||||
"""End of the Glances stats."""
|
"""End of the Glances stats."""
|
||||||
# Close export modules
|
# Close export modules
|
||||||
|
|
|
||||||
|
|
@ -7,35 +7,32 @@ cassandra-driver
|
||||||
chevron
|
chevron
|
||||||
docker>=6.1.1
|
docker>=6.1.1
|
||||||
elasticsearch
|
elasticsearch
|
||||||
fastapi; python_version >= "3.8"
|
fastapi
|
||||||
graphitesender
|
graphitesender
|
||||||
hddtemp
|
hddtemp
|
||||||
influxdb>=1.0.0 # For InfluxDB < 1.8
|
influxdb>=1.0.0 # For InfluxDB < 1.8
|
||||||
influxdb-client; python_version >= "3.7" # For InfluxDB >= 1.8
|
influxdb-client # For InfluxDB >= 1.8
|
||||||
jinja2
|
jinja2
|
||||||
kafka-python
|
kafka-python
|
||||||
netifaces
|
netifaces
|
||||||
nvidia-ml-py; python_version >= "3.5"
|
nvidia-ml-py
|
||||||
packaging; python_version >= "3.7"
|
|
||||||
paho-mqtt
|
paho-mqtt
|
||||||
pika
|
pika
|
||||||
podman; python_version >= "3.6"
|
podman
|
||||||
potsdb
|
potsdb
|
||||||
prometheus_client
|
prometheus_client
|
||||||
pycouchdb
|
pycouchdb
|
||||||
pydantic
|
pydantic
|
||||||
pygal
|
pygal
|
||||||
pymdstat
|
pymdstat
|
||||||
pymongo; python_version >= "3.7"
|
pymongo
|
||||||
pySMART.smartx
|
pySMART.smartx
|
||||||
pysnmp-lextudio; python_version >= "3.7"
|
pysnmp-lextudio
|
||||||
python-dateutil
|
python-dateutil
|
||||||
pyzmq
|
pyzmq
|
||||||
requests
|
requests
|
||||||
scandir; python_version < "3.5"
|
|
||||||
six
|
six
|
||||||
sparklines
|
sparklines
|
||||||
statsd
|
statsd
|
||||||
uvicorn; python_version >= "3.8"
|
uvicorn
|
||||||
wifi
|
|
||||||
zeroconf==0.131.0 # Waiting correction for ARMv7: https://github.com/python-zeroconf/python-zeroconf/issues/1372
|
zeroconf==0.131.0 # Waiting correction for ARMv7: https://github.com/python-zeroconf/python-zeroconf/issues/1372
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,3 @@
|
||||||
[tool.black]
|
|
||||||
line-length = 120
|
|
||||||
skip-string-normalization = true
|
|
||||||
exclude = '\./glances/outputs/static/*'
|
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
line-length = 120
|
line-length = 120
|
||||||
target-version = "py38"
|
target-version = "py38"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
defusedxml
|
defusedxml
|
||||||
|
orjson
|
||||||
packaging
|
packaging
|
||||||
psutil>=5.6.7
|
psutil>=5.6.7
|
||||||
ujson>=5.4.0
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
name: glances
|
name: glances
|
||||||
version: '4.0.7'
|
version: '4.0.8'
|
||||||
|
|
||||||
summary: Glances an Eye on your system. A top/htop alternative.
|
summary: Glances an Eye on your system. A top/htop alternative.
|
||||||
description: |
|
description: |
|
||||||
|
|
@ -9,7 +9,7 @@ description: |
|
||||||
depending on the user interface size.
|
depending on the user interface size.
|
||||||
|
|
||||||
base: core22
|
base: core22
|
||||||
grade: stable
|
grade: stable # devel
|
||||||
confinement: strict
|
confinement: strict
|
||||||
|
|
||||||
apps:
|
apps:
|
||||||
|
|
@ -49,7 +49,7 @@ parts:
|
||||||
glances:
|
glances:
|
||||||
plugin: python
|
plugin: python
|
||||||
source: https://github.com/nicolargo/glances.git
|
source: https://github.com/nicolargo/glances.git
|
||||||
source-branch: master
|
source-branch: master # develop
|
||||||
python-requirements:
|
python-requirements:
|
||||||
- requirements.txt
|
- requirements.txt
|
||||||
- webui-requirements.txt
|
- webui-requirements.txt
|
||||||
|
|
|
||||||
2
tox.ini
2
tox.ini
|
|
@ -18,7 +18,7 @@ deps =
|
||||||
psutil
|
psutil
|
||||||
defusedxml
|
defusedxml
|
||||||
packaging
|
packaging
|
||||||
ujson
|
orjson
|
||||||
fastapi
|
fastapi
|
||||||
uvicorn
|
uvicorn
|
||||||
jinja2
|
jinja2
|
||||||
|
|
|
||||||
|
|
@ -17,14 +17,24 @@ import time
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from glances import __version__
|
from glances import __version__
|
||||||
from glances.globals import ServerProxy
|
from glances.client import GlancesClient
|
||||||
|
|
||||||
|
SERVER_HOST = 'localhost'
|
||||||
SERVER_PORT = 61234
|
SERVER_PORT = 61234
|
||||||
URL = f"http://localhost:{SERVER_PORT}"
|
|
||||||
pid = None
|
pid = None
|
||||||
|
|
||||||
|
|
||||||
# Init the XML-RPC client
|
# Init the XML-RPC client
|
||||||
client = ServerProxy(URL)
|
class args:
|
||||||
|
client = SERVER_HOST
|
||||||
|
port = SERVER_PORT
|
||||||
|
username = ""
|
||||||
|
password = ""
|
||||||
|
time = 3
|
||||||
|
quiet = False
|
||||||
|
|
||||||
|
|
||||||
|
client = GlancesClient(args=args).client
|
||||||
|
|
||||||
# Unitest class
|
# Unitest class
|
||||||
# ==============
|
# ==============
|
||||||
|
|
@ -71,14 +81,16 @@ class TestGlances(unittest.TestCase):
|
||||||
print('INFO: [TEST_002] Get plugins list')
|
print('INFO: [TEST_002] Get plugins list')
|
||||||
print(f"XML-RPC request: {method}")
|
print(f"XML-RPC request: {method}")
|
||||||
req = json.loads(client.getAllPlugins())
|
req = json.loads(client.getAllPlugins())
|
||||||
|
print(req)
|
||||||
|
|
||||||
self.assertIsInstance(req, list)
|
self.assertIsInstance(req, list)
|
||||||
|
self.assertIn('cpu', req)
|
||||||
|
|
||||||
def test_003_system(self):
|
def test_003_system(self):
|
||||||
"""System."""
|
"""System."""
|
||||||
method = "getSystem()"
|
method = "getSystem()"
|
||||||
print(f'INFO: [TEST_003] Method: {method}')
|
print(f'INFO: [TEST_003] Method: {method}')
|
||||||
req = json.loads(client.getSystem())
|
req = json.loads(client.getPlugin('system'))
|
||||||
|
|
||||||
self.assertIsInstance(req, dict)
|
self.assertIsInstance(req, dict)
|
||||||
|
|
||||||
|
|
@ -87,16 +99,16 @@ class TestGlances(unittest.TestCase):
|
||||||
method = "getCpu(), getPerCpu(), getLoad() and getCore()"
|
method = "getCpu(), getPerCpu(), getLoad() and getCore()"
|
||||||
print(f'INFO: [TEST_004] Method: {method}')
|
print(f'INFO: [TEST_004] Method: {method}')
|
||||||
|
|
||||||
req = json.loads(client.getCpu())
|
req = json.loads(client.getPlugin('cpu'))
|
||||||
self.assertIsInstance(req, dict)
|
self.assertIsInstance(req, dict)
|
||||||
|
|
||||||
req = json.loads(client.getPerCpu())
|
req = json.loads(client.getPlugin('percpu'))
|
||||||
self.assertIsInstance(req, list)
|
self.assertIsInstance(req, list)
|
||||||
|
|
||||||
req = json.loads(client.getLoad())
|
req = json.loads(client.getPlugin('load'))
|
||||||
self.assertIsInstance(req, dict)
|
self.assertIsInstance(req, dict)
|
||||||
|
|
||||||
req = json.loads(client.getCore())
|
req = json.loads(client.getPlugin('core'))
|
||||||
self.assertIsInstance(req, dict)
|
self.assertIsInstance(req, dict)
|
||||||
|
|
||||||
def test_005_mem(self):
|
def test_005_mem(self):
|
||||||
|
|
@ -104,10 +116,10 @@ class TestGlances(unittest.TestCase):
|
||||||
method = "getMem() and getMemSwap()"
|
method = "getMem() and getMemSwap()"
|
||||||
print(f'INFO: [TEST_005] Method: {method}')
|
print(f'INFO: [TEST_005] Method: {method}')
|
||||||
|
|
||||||
req = json.loads(client.getMem())
|
req = json.loads(client.getPlugin('mem'))
|
||||||
self.assertIsInstance(req, dict)
|
self.assertIsInstance(req, dict)
|
||||||
|
|
||||||
req = json.loads(client.getMemSwap())
|
req = json.loads(client.getPlugin('memswap'))
|
||||||
self.assertIsInstance(req, dict)
|
self.assertIsInstance(req, dict)
|
||||||
|
|
||||||
def test_006_net(self):
|
def test_006_net(self):
|
||||||
|
|
@ -115,7 +127,7 @@ class TestGlances(unittest.TestCase):
|
||||||
method = "getNetwork()"
|
method = "getNetwork()"
|
||||||
print(f'INFO: [TEST_006] Method: {method}')
|
print(f'INFO: [TEST_006] Method: {method}')
|
||||||
|
|
||||||
req = json.loads(client.getNetwork())
|
req = json.loads(client.getPlugin('network'))
|
||||||
self.assertIsInstance(req, list)
|
self.assertIsInstance(req, list)
|
||||||
|
|
||||||
def test_007_disk(self):
|
def test_007_disk(self):
|
||||||
|
|
@ -123,13 +135,13 @@ class TestGlances(unittest.TestCase):
|
||||||
method = "getFs(), getFolders() and getDiskIO()"
|
method = "getFs(), getFolders() and getDiskIO()"
|
||||||
print(f'INFO: [TEST_007] Method: {method}')
|
print(f'INFO: [TEST_007] Method: {method}')
|
||||||
|
|
||||||
req = json.loads(client.getFs())
|
req = json.loads(client.getPlugin('fs'))
|
||||||
self.assertIsInstance(req, list)
|
self.assertIsInstance(req, list)
|
||||||
|
|
||||||
req = json.loads(client.getFolders())
|
req = json.loads(client.getPlugin('folders'))
|
||||||
self.assertIsInstance(req, list)
|
self.assertIsInstance(req, list)
|
||||||
|
|
||||||
req = json.loads(client.getDiskIO())
|
req = json.loads(client.getPlugin('diskio'))
|
||||||
self.assertIsInstance(req, list)
|
self.assertIsInstance(req, list)
|
||||||
|
|
||||||
def test_008_sensors(self):
|
def test_008_sensors(self):
|
||||||
|
|
@ -137,7 +149,7 @@ class TestGlances(unittest.TestCase):
|
||||||
method = "getSensors()"
|
method = "getSensors()"
|
||||||
print(f'INFO: [TEST_008] Method: {method}')
|
print(f'INFO: [TEST_008] Method: {method}')
|
||||||
|
|
||||||
req = json.loads(client.getSensors())
|
req = json.loads(client.getPlugin('sensors'))
|
||||||
self.assertIsInstance(req, list)
|
self.assertIsInstance(req, list)
|
||||||
|
|
||||||
def test_009_process(self):
|
def test_009_process(self):
|
||||||
|
|
@ -145,10 +157,10 @@ class TestGlances(unittest.TestCase):
|
||||||
method = "getProcessCount() and getProcessList()"
|
method = "getProcessCount() and getProcessList()"
|
||||||
print(f'INFO: [TEST_009] Method: {method}')
|
print(f'INFO: [TEST_009] Method: {method}')
|
||||||
|
|
||||||
req = json.loads(client.getProcessCount())
|
req = json.loads(client.getPlugin('processcount'))
|
||||||
self.assertIsInstance(req, dict)
|
self.assertIsInstance(req, dict)
|
||||||
|
|
||||||
req = json.loads(client.getProcessList())
|
req = json.loads(client.getPlugin('processlist'))
|
||||||
self.assertIsInstance(req, list)
|
self.assertIsInstance(req, list)
|
||||||
|
|
||||||
def test_010_all_limits(self):
|
def test_010_all_limits(self):
|
||||||
|
|
@ -173,7 +185,7 @@ class TestGlances(unittest.TestCase):
|
||||||
"""IRQS"""
|
"""IRQS"""
|
||||||
method = "getIrqs()"
|
method = "getIrqs()"
|
||||||
print(f'INFO: [TEST_012] Method: {method}')
|
print(f'INFO: [TEST_012] Method: {method}')
|
||||||
req = json.loads(client.getIrq())
|
req = json.loads(client.getPlugin('irq'))
|
||||||
self.assertIsInstance(req, list)
|
self.assertIsInstance(req, list)
|
||||||
|
|
||||||
def test_013_plugin_views(self):
|
def test_013_plugin_views(self):
|
||||||
|
|
@ -181,12 +193,13 @@ class TestGlances(unittest.TestCase):
|
||||||
method = "getViewsCpu()"
|
method = "getViewsCpu()"
|
||||||
print(f'INFO: [TEST_013] Method: {method}')
|
print(f'INFO: [TEST_013] Method: {method}')
|
||||||
|
|
||||||
req = json.loads(client.getViewsCpu())
|
req = json.loads(client.getPluginView('cpu'))
|
||||||
self.assertIsInstance(req, dict)
|
self.assertIsInstance(req, dict)
|
||||||
|
|
||||||
def test_999_stop_server(self):
|
def test_999_stop_server(self):
|
||||||
"""Stop the Glances Web Server."""
|
"""Stop the Glances Web Server."""
|
||||||
print('INFO: [TEST_999] Stop the Glances Server')
|
print('INFO: [TEST_999] Stop the Glances Server')
|
||||||
|
print(client.system.listMethods())
|
||||||
|
|
||||||
print("Stop the Glances Server")
|
print("Stop the Glances Server")
|
||||||
pid.terminate()
|
pid.terminate()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue