diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index efd24232..5465ba2f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -99,7 +99,8 @@ jobs: runs-on: macos-14 strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + # Only test the latest stable version + python-version: ["3.12"] steps: diff --git a/CODE-OF-CONDUCT.md b/CODE-OF-CONDUCT.md index 73df9aab..5c6c55ba 100644 --- a/CODE-OF-CONDUCT.md +++ b/CODE-OF-CONDUCT.md @@ -6,7 +6,7 @@ In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, -education, socio-economic status, nationality, personal appearance, race, +education, socioeconomic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards diff --git a/Makefile b/Makefile index b7e1e817..b92bf202 100644 --- a/Makefile +++ b/Makefile @@ -93,7 +93,7 @@ lint: ## Lint the code. ./venv-dev/bin/python -m ruff check . --fix codespell: ## Run codespell to fix common misspellings in text files - ./venv-dev/bin/codespell -S .git,./docs/_build,./Glances.egg-info,./venv*,./glances/outputs,*.svg -L hart,bu,te,statics + ./venv-dev/bin/codespell -S .git,./docs/_build,./Glances.egg-info,./venv*,./glances/outputs,*.svg -L hart,bu,te,statics -w semgrep: ## Run semgrep to find bugs and enforce code standards ./venv-dev/bin/semgrep scan --config=auto @@ -185,7 +185,7 @@ flatpak: venv-dev-upgrade ## Generate FlatPack JSON file rm -rf ./flatpak-builder-tools @echo "Now follow: https://github.com/flathub/flathub/wiki/App-Submission" -# Snap package is automaticaly build on the Snapcraft.io platform +# Snap package is automatically build on the Snapcraft.io platform # https://snapcraft.io/glances # But you can try an offline build with the following command snapcraft: diff --git a/NEWS.rst b/NEWS.rst index 64d5a12f..945263bc 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -2,6 +2,14 @@ Glances ChangeLog ============================================================================== +=============== +Version 4.1.2 +=============== + +Bug corrected: + +* AttributeError: 'CpuPercent' object has no attribute 'cpu_percent' #2859 + =============== Version 4.1.1 =============== @@ -23,8 +31,8 @@ Enhancements: Bug corrected: * API: Network module is disabled but appears in endpoint "all" #2815 -* API is not compatible with requests containing spcial/encoding char #2820 -* 'j' hot key crashs Glances #2831 +* API is not compatible with requests containing special/encoding char #2820 +* 'j' hot key crashes Glances #2831 * Raspberry PI - CPU info is not correct #2616 * Graph export is broken if there is no graph section in Glances configuration file #2839 * Glances API status check returns Error 405 - Method Not Allowed #2841 @@ -33,17 +41,17 @@ Bug corrected: * Exception when Glances is ran with limited plugin list #2822 * Disable separator option do not work #2823 -Continious integration and documentation: +Continuous integration and documentation: * test test_107_fs_plugin_method fails on aarch64-linux #2819 -Thanks to all contibutors and bug reporters ! +Thanks to all contributors and bug reporters ! Special thanks to: * Bharath Vignesh J K * RazCrimson -* Vadim Smal +* Vadim Small =============== Version 4.0.8 @@ -218,7 +226,7 @@ Many thinks to the contributors: * Christoph Zimmermann * RazCrimson * Robin Candau -* Github GPG acces +* Github GPG access * Continuous Integration * Georgiy Timchenko * turbocrime @@ -392,7 +400,7 @@ Documentation and CI: * Update Makefile with comments * Update Python minimal requirement for py3nvlm * Update security policy (user can open private issue directly in Github) -* Add a simple run script. Entry point for IDE debuger +* Add a simple run script. Entry point for IDE debugger Cyber security update: @@ -421,7 +429,7 @@ And also a big thanks to @RazCrimson (https://github.com/RazCrimson) for the sup Version 3.3.0.4 =============== -Refactor the Docker images factory, from now, only Alpine image wll be provided. +Refactor the Docker images factory, from now, only Alpine image will be provided. The following Docker images (nicolargo/glances) are availables: @@ -469,9 +477,9 @@ Bug corrected: * Correct issue with the regexp filter (use fullmatch instead of match) * Errors when running Glances as web service #1702 * Apply alias to Duplicate sensor name #1686 -* Make the hide function in sensors section compliant with lower/upercase #1590 +* Make the hide function in sensors section compliant with lower/uppercase #1590 * Web UI truncates the days part of CPU time counter of the process list #2108 -* Correct alignement issue with the diskio plugin (Console UI) +* Correct alignment issue with the diskio plugin (Console UI) Documentation and CI: @@ -738,7 +746,7 @@ Bugs corrected: * Docker containers information missing with Docker 20.10.x #1878 * Get system sensors temperatures thresholds #1864 -Contibutors for this version: +Contributors for this version: * Nicolargo * Markus Pöschl @@ -1345,7 +1353,7 @@ Enhancements and new features: * Add ZeroMQ exporter (issue #939) * Add CouchDB exporter (issue #928) * Add hotspot Wifi information (issue #937) -* Add default interface speed and automatic rate thresolds (issue #718) +* Add default interface speed and automatic rate thresholds (issue #718) * Highlight max stats in the processes list (issue #878) * Docker alerts and actions (issue #875) * Glances API returns the processes PPID (issue #926) diff --git a/README.rst b/README.rst index c5f064ba..7fbc4319 100644 --- a/README.rst +++ b/README.rst @@ -2,7 +2,7 @@ Glances - An eye on your system =============================== -| |pypi| |test| |contibutors| |quality| +| |pypi| |test| |contributors| |quality| | |starts| |docker| |pypistat| | |sponsors| |twitter| @@ -25,9 +25,9 @@ Glances - An eye on your system :target: https://github.com/nicolargo/glances/actions :alt: Linux tests (GitHub Actions) -.. |contibutors| image:: https://img.shields.io/github/contributors/nicolargo/glances +.. |contributors| image:: https://img.shields.io/github/contributors/nicolargo/glances :target: https://github.com/nicolargo/glances/issues?q=is%3Aissue+is%3Aopen+label%3A%22needs+contributor%22 - :alt: Contibutors + :alt: Contributors .. |quality| image:: https://scrutinizer-ci.com/g/nicolargo/glances/badges/quality-score.png?b=develop :target: https://scrutinizer-ci.com/g/nicolargo/glances/?branch=develop @@ -141,7 +141,7 @@ stable version. To install Glances, simply use the ``pip`` command line. Warning: on modern Linux operating systems, you may have an externally-managed-environment -error message when you try to use ``pip``. In this case, go to the the PipX section bellow. +error message when you try to use ``pip``. In this case, go to the the PipX section below. .. code-block:: console diff --git a/conf/glances.conf b/conf/glances.conf index 7bba30aa..faa94f9f 100644 --- a/conf/glances.conf +++ b/conf/glances.conf @@ -375,7 +375,7 @@ temperature_hdd_critical=60 battery_careful=80 battery_warning=90 battery_critical=95 -# Fan speed threashold in RPM +# Fan speed threshold in RPM #fan_speed_careful=100 # Sensors alias #alias=core 0:CPU Core 0,core 1:CPU Core 1 diff --git a/docker-compose/docker-compose-with-traefik.yml b/docker-compose/docker-compose-with-traefik.yml index 1f98d07b..06caf682 100644 --- a/docker-compose/docker-compose-with-traefik.yml +++ b/docker-compose/docker-compose-with-traefik.yml @@ -27,7 +27,7 @@ services: environment: - TZ=${TZ} - "GLANCES_OPT=-C /glances/conf/glances.conf -w" - # Uncomment for GPU compatibilty (Nvidia) inside the container + # Uncomment for GPU compatibility (Nvidia) inside the container # deploy: # resources: # reservations: diff --git a/docker-compose/docker-compose.yml b/docker-compose/docker-compose.yml index 84e4bcf7..f446dad6 100644 --- a/docker-compose/docker-compose.yml +++ b/docker-compose/docker-compose.yml @@ -15,7 +15,7 @@ services: environment: - TZ=${TZ} - "GLANCES_OPT=-C /glances/conf/glances.conf -w" - # Uncomment for GPU compatibilty (Nvidia) inside the container + # Uncomment for GPU compatibility (Nvidia) inside the container # deploy: # resources: # reservations: diff --git a/docker-compose/glances.conf b/docker-compose/glances.conf index 11bcb951..0194b250 100755 --- a/docker-compose/glances.conf +++ b/docker-compose/glances.conf @@ -375,7 +375,7 @@ temperature_hdd_critical=60 battery_careful=80 battery_warning=90 battery_critical=95 -# Fan speed threashold in RPM +# Fan speed threshold in RPM #fan_speed_careful=100 # Sensors alias #alias=core 0:CPU Core 0,core 1:CPU Core 1 diff --git a/docs/aoa/cloud.rst b/docs/aoa/cloud.rst index d6214925..a65a2414 100644 --- a/docs/aoa/cloud.rst +++ b/docs/aoa/cloud.rst @@ -3,7 +3,7 @@ CLOUD ===== -This plugin diplays information about the cloud provider if your host is running on OpenStack. +This plugin displays information about the cloud provider if your host is running on OpenStack. The plugin use the standard OpenStack `metadata`_ service to retrieve the information. diff --git a/docs/aoa/cpu.rst b/docs/aoa/cpu.rst index 1124663c..c9e3ea83 100644 --- a/docs/aoa/cpu.rst +++ b/docs/aoa/cpu.rst @@ -53,7 +53,7 @@ To switch to per-CPU stats, just hit the ``1`` key: .. image:: ../_static/per-cpu.png In this case, Glances will show on line per logical CPU on the system. -If you have multiple core, it is possible to define the maximun number +If you have multiple core, it is possible to define the maximum number of CPU to display. The top 'max_cpu_display' will be display and an extra line with the mean of all others CPU will be added. diff --git a/docs/aoa/header.rst b/docs/aoa/header.rst index 62a3515b..23f07ab4 100644 --- a/docs/aoa/header.rst +++ b/docs/aoa/header.rst @@ -57,7 +57,7 @@ Example: **NOTE:** Setting low values for `public_refresh_interval` will result in frequent HTTP requests to the onlive service defined in public_api. Recommended range: 120-600 seconds. -Glances uses online services in order to get the IP addresses and the additional informations. +Glances uses online services in order to get the IP addresses and the additional information. Your IP address could be blocked if too many requests are done. diff --git a/docs/aoa/load.rst b/docs/aoa/load.rst index 57b1fc00..32924182 100644 --- a/docs/aoa/load.rst +++ b/docs/aoa/load.rst @@ -39,7 +39,7 @@ Trend Status ======== ============================================================== ``-`` Mean 15 lasts values equal mean 15 previous values ``↓`` Mean 15 lasts values is lower mean 15 previous values -``↑`` Mean 15 lasts values is higher mean 15 previous valuess +``↑`` Mean 15 lasts values is higher mean 15 previous values ======== ============================================================== Legend: diff --git a/docs/aoa/memory.rst b/docs/aoa/memory.rst index fa62764a..2e41584d 100644 --- a/docs/aoa/memory.rst +++ b/docs/aoa/memory.rst @@ -49,7 +49,7 @@ Trend Status ======== ============================================================== ``-`` Mean 15 lasts values equal mean 15 previous values ``↓`` Mean 15 lasts values is lower mean 15 previous values -``↑`` Mean 15 lasts values is higher mean 15 previous valuess +``↑`` Mean 15 lasts values is higher mean 15 previous values ======== ============================================================== Alerts are only set for used memory and used swap. diff --git a/docs/api.rst b/docs/api.rst index e5ca31d7..50649ee5 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -141,7 +141,7 @@ Get plugin stats:: "refresh": 3.0, "regex": True, "result": None, - "timer": 0.4461839199066162}, + "timer": 0.46051621437072754}, {"count": 0, "countmax": 20.0, "countmin": None, @@ -150,7 +150,7 @@ Get plugin stats:: "refresh": 3.0, "regex": True, "result": None, - "timer": 0.4460873603820801}] + "timer": 0.4604213237762451}] Fields descriptions: @@ -178,7 +178,7 @@ Get a specific item when field matches the given value:: "refresh": 3.0, "regex": True, "result": None, - "timer": 0.4461839199066162}]} + "timer": 0.46051621437072754}]} GET cloud --------- @@ -265,19 +265,19 @@ Get plugin stats:: # curl http://localhost:61208/api/4/cpu {"cpucore": 16, - "ctx_switches": 470143766, + "ctx_switches": 546195071, "guest": 0.0, - "idle": 89.0, - "interrupts": 400614986, - "iowait": 0.0, + "idle": 92.4, + "interrupts": 467876767, + "iowait": 0.1, "irq": 0.0, "nice": 0.0, - "soft_interrupts": 148453028, + "soft_interrupts": 173761929, "steal": 0.0, "syscalls": 0, - "system": 3.7, - "total": 6.6, - "user": 7.2} + "system": 2.9, + "total": 7.4, + "user": 4.6} Fields descriptions: @@ -310,7 +310,7 @@ Fields descriptions: Get a specific field:: # curl http://localhost:61208/api/4/cpu/total - {"total": 6.6} + {"total": 7.4} GET diskio ---------- @@ -320,14 +320,14 @@ Get plugin stats:: # curl http://localhost:61208/api/4/diskio [{"disk_name": "nvme0n1", "key": "disk_name", - "read_bytes": 7696793088, - "read_count": 291321, - "write_bytes": 27269166080, - "write_count": 1362029}, + "read_bytes": 10517048832, + "read_count": 404202, + "write_bytes": 35011642368, + "write_count": 1738213}, {"disk_name": "nvme0n1p1", "key": "disk_name", - "read_bytes": 7558144, - "read_count": 605, + "read_bytes": 8385536, + "read_count": 905, "write_bytes": 1024, "write_count": 2}] @@ -363,10 +363,10 @@ Get a specific item when field matches the given value:: # curl http://localhost:61208/api/4/diskio/disk_name/nvme0n1 {"nvme0n1": [{"disk_name": "nvme0n1", "key": "disk_name", - "read_bytes": 7696793088, - "read_count": 291321, - "write_bytes": 27269166080, - "write_count": 1362029}]} + "read_bytes": 10517048832, + "read_count": 404202, + "write_bytes": 35011642368, + "write_count": 1738213}]} GET folders ----------- @@ -393,13 +393,13 @@ Get plugin stats:: # curl http://localhost:61208/api/4/fs [{"device_name": "/dev/mapper/ubuntu--vg-ubuntu--lv", - "free": 896569999360, + "free": 897308430336, "fs_type": "ext4", "key": "mnt_point", "mnt_point": "/", - "percent": 5.9, + "percent": 5.8, "size": 1003736440832, - "used": 56103936000}] + "used": 55365505024}] Fields descriptions: @@ -420,13 +420,13 @@ Get a specific item when field matches the given value:: # curl http://localhost:61208/api/4/fs/mnt_point// {"/": [{"device_name": "/dev/mapper/ubuntu--vg-ubuntu--lv", - "free": 896569999360, + "free": 897308430336, "fs_type": "ext4", "key": "mnt_point", "mnt_point": "/", - "percent": 5.9, + "percent": 5.8, "size": 1003736440832, - "used": 56103936000}]} + "used": 55365505024}]} GET gpu ------- @@ -499,10 +499,7 @@ GET load Get plugin stats:: # curl http://localhost:61208/api/4/load - {"cpucore": 16, - "min1": 0.61279296875, - "min15": 0.96044921875, - "min5": 0.88916015625} + {"cpucore": 16, "min1": 1.2109375, "min15": 1.0966796875, "min5": 1.15185546875} Fields descriptions: @@ -514,7 +511,7 @@ Fields descriptions: Get a specific field:: # curl http://localhost:61208/api/4/load/min1 - {"min1": 0.61279296875} + {"min1": 1.2109375} GET mem ------- @@ -522,16 +519,16 @@ GET mem Get plugin stats:: # curl http://localhost:61208/api/4/mem - {"active": 8189308928, - "available": 4513206272, - "buffers": 120315904, - "cached": 4011606016, - "free": 4513206272, - "inactive": 4910346240, - "percent": 72.5, - "shared": 870084608, + {"active": 5502283776, + "available": 10467418112, + "buffers": 280461312, + "cached": 6802784256, + "free": 10467418112, + "inactive": 4388352000, + "percent": 36.3, + "shared": 844951552, "total": 16422486016, - "used": 11909279744} + "used": 5955067904} Fields descriptions: @@ -558,13 +555,13 @@ GET memswap Get plugin stats:: # curl http://localhost:61208/api/4/memswap - {"free": 3059740672, - "percent": 28.8, - "sin": 38764544, - "sout": 1242734592, + {"free": 3880251392, + "percent": 9.7, + "sin": 218775552, + "sout": 1518604288, "time_since_update": 1, "total": 4294963200, - "used": 1235222528} + "used": 414711808} Fields descriptions: @@ -589,15 +586,15 @@ Get plugin stats:: # curl http://localhost:61208/api/4/network [{"alias": None, "bytes_all": 0, - "bytes_all_gauge": 5740182673, + "bytes_all_gauge": 6662226672, "bytes_recv": 0, - "bytes_recv_gauge": 5442631219, + "bytes_recv_gauge": 6304144613, "bytes_sent": 0, - "bytes_sent_gauge": 297551454, + "bytes_sent_gauge": 358082059, "interface_name": "wlp0s20f3", "key": "interface_name", "speed": 0, - "time_since_update": 0.4495677947998047}] + "time_since_update": 0.46425318717956543}] Fields descriptions: @@ -626,15 +623,15 @@ Get a specific item when field matches the given value:: # curl http://localhost:61208/api/4/network/interface_name/wlp0s20f3 {"wlp0s20f3": [{"alias": None, "bytes_all": 0, - "bytes_all_gauge": 5740182673, + "bytes_all_gauge": 6662226672, "bytes_recv": 0, - "bytes_recv_gauge": 5442631219, + "bytes_recv_gauge": 6304144613, "bytes_sent": 0, - "bytes_sent_gauge": 297551454, + "bytes_sent_gauge": 358082059, "interface_name": "wlp0s20f3", "key": "interface_name", "speed": 0, - "time_since_update": 0.4495677947998047}]} + "time_since_update": 0.46425318717956543}]} GET now ------- @@ -642,7 +639,7 @@ GET now Get plugin stats:: # curl http://localhost:61208/api/4/now - {"custom": "2024-06-29 16:31:55 CEST", "iso": "2024-06-29T16:31:55+02:00"} + {"custom": "2024-07-03 19:42:32 CEST", "iso": "2024-07-03T19:42:32+02:00"} Fields descriptions: @@ -652,7 +649,7 @@ Fields descriptions: Get a specific field:: # curl http://localhost:61208/api/4/now/iso - {"iso": "2024-06-29T16:31:55+02:00"} + {"iso": "2024-07-03T19:42:32+02:00"} GET percpu ---------- @@ -663,7 +660,7 @@ Get plugin stats:: [{"cpu_number": 0, "guest": 0.0, "guest_nice": 0.0, - "idle": 37.0, + "idle": 42.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", @@ -671,12 +668,12 @@ Get plugin stats:: "softirq": 0.0, "steal": 0.0, "system": 0.0, - "total": 63.0, + "total": 58.0, "user": 0.0}, {"cpu_number": 1, "guest": 0.0, "guest_nice": 0.0, - "idle": 37.0, + "idle": 42.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", @@ -684,8 +681,8 @@ Get plugin stats:: "softirq": 0.0, "steal": 0.0, "system": 0.0, - "total": 63.0, - "user": 1.0}] + "total": 58.0, + "user": 0.0}] Fields descriptions: @@ -719,7 +716,7 @@ Get plugin stats:: "port": 0, "refresh": 30, "rtt_warning": None, - "status": None, + "status": 0.003735, "timeout": 3}] Fields descriptions: @@ -747,7 +744,7 @@ Get a specific item when field matches the given value:: "port": 0, "refresh": 30, "rtt_warning": None, - "status": None, + "status": 0.003735, "timeout": 3}]} GET processcount @@ -756,7 +753,7 @@ GET processcount Get plugin stats:: # curl http://localhost:61208/api/4/processcount - {"pid_max": 0, "running": 1, "sleeping": 283, "thread": 1641, "total": 423} + {"pid_max": 0, "running": 1, "sleeping": 281, "thread": 1602, "total": 420} Fields descriptions: @@ -769,7 +766,7 @@ Fields descriptions: Get a specific field:: # curl http://localhost:61208/api/4/processcount/total - {"total": 423} + {"total": 420} GET processlist --------------- @@ -777,97 +774,57 @@ GET processlist Get plugin stats:: # curl http://localhost:61208/api/4/processlist - [{"cmdline": ["/snap/firefox/4336/usr/lib/firefox/firefox", - "-contentproc", - "-childID", - "2", - "-isForBrowser", - "-prefsLen", - "28296", - "-prefMapSize", - "244444", - "-jsInitLen", - "231800", - "-parentBuildID", - "20240527194810", - "-greomni", - "/snap/firefox/4336/usr/lib/firefox/omni.ja", - "-appomni", - "/snap/firefox/4336/usr/lib/firefox/browser/omni.ja", - "-appDir", - "/snap/firefox/4336/usr/lib/firefox/browser", - "{01aadc3d-85fc-4851-9ca1-a43a1e81c3fa}", - "4591", - "true", - "tab"], + [{"cmdline": ["/snap/firefox/4336/usr/lib/firefox/firefox"], "cpu_percent": 0.0, - "cpu_times": {"children_system": 0.0, - "children_user": 0.0, + "cpu_times": {"children_system": 190.29, + "children_user": 1859.41, "iowait": 0.0, - "system": 134.89, - "user": 3176.31}, + "system": 497.15, + "user": 1644.75}, "gids": {"effective": 1000, "real": 1000, "saved": 1000}, - "io_counters": [9353216, 0, 0, 0, 0], + "io_counters": [448777216, 2910990336, 0, 0, 0], "key": "pid", - "memory_info": {"data": 3979939840, + "memory_info": {"data": 927793152, "dirty": 0, "lib": 0, - "rss": 3911520256, - "shared": 128909312, + "rss": 531296256, + "shared": 243904512, "text": 987136, - "vms": 6556266496}, - "memory_percent": 23.818076338680438, - "name": "Isolated Web Co", + "vms": 21316730880}, + "memory_percent": 3.2351755725800095, + "name": "firefox", "nice": 0, - "num_threads": 29, - "pid": 4848, + "num_threads": 145, + "pid": 793506, "status": "S", "time_since_update": 1, "username": "nicolargo"}, - {"cmdline": ["/snap/firefox/4336/usr/lib/firefox/firefox", - "-contentproc", - "-childID", - "3", - "-isForBrowser", - "-prefsLen", - "28296", - "-prefMapSize", - "244444", - "-jsInitLen", - "231800", - "-parentBuildID", - "20240527194810", - "-greomni", - "/snap/firefox/4336/usr/lib/firefox/omni.ja", - "-appomni", - "/snap/firefox/4336/usr/lib/firefox/browser/omni.ja", - "-appDir", - "/snap/firefox/4336/usr/lib/firefox/browser", - "{0ae685c6-7105-4724-886c-98d4a4a9a4f8}", - "4591", - "true", - "tab"], + {"cmdline": ["/snap/code/159/usr/share/code/code", + "/home/nicolargo/.vscode/extensions/ms-python.vscode-pylance-2024.6.1/dist/server.bundle.js", + "--cancellationReceive=file:08276fdd86da3ba7774331df76f940b557481b9ffb", + "--node-ipc", + "--clientProcessId=885312"], "cpu_percent": 0.0, - "cpu_times": {"children_system": 0.0, - "children_user": 0.0, + "cpu_times": {"children_system": 0.12, + "children_user": 0.55, "iowait": 0.0, - "system": 56.51, - "user": 529.53}, + "system": 3.42, + "user": 32.45}, "gids": {"effective": 1000, "real": 1000, "saved": 1000}, - "io_counters": [2974720, 0, 0, 0, 0], + "io_counters": [1064960, 225280, 0, 0, 0], "key": "pid", - "memory_info": {"data": 2120372224, + "memory_info": {"data": 612491264, "dirty": 0, "lib": 0, - "rss": 2025164800, - "shared": 119304192, - "text": 987136, - "vms": 4683640832}, - "memory_percent": 12.331657935509488, - "name": "Isolated Web Co", + "rss": 483213312, + "shared": 64225280, + "text": 128315392, + "vms": 1210419245056}, + "memory_percent": 2.9423883298132685, + "name": "code", "nice": 0, - "num_threads": 28, - "pid": 4852, + "num_threads": 14, + "pid": 885867, "status": "S", "time_since_update": 1, "username": "nicolargo"}] @@ -902,18 +859,18 @@ GET quicklook Get plugin stats:: # curl http://localhost:61208/api/4/quicklook - {"cpu": 6.6, + {"cpu": 7.4, "cpu_hz": 4475000000.0, - "cpu_hz_current": 519943687.5, + "cpu_hz_current": 808461187.5, "cpu_log_core": 16, "cpu_name": "13th Gen Intel(R) Core(TM) i7-13620H", "cpu_phys_core": 10, - "load": 6.0, - "mem": 72.5, + "load": 6.9, + "mem": 36.3, "percpu": [{"cpu_number": 0, "guest": 0.0, "guest_nice": 0.0, - "idle": 37.0, + "idle": 42.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", @@ -921,12 +878,12 @@ Get plugin stats:: "softirq": 0.0, "steal": 0.0, "system": 0.0, - "total": 63.0, + "total": 58.0, "user": 0.0}, {"cpu_number": 1, "guest": 0.0, "guest_nice": 0.0, - "idle": 37.0, + "idle": 42.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", @@ -934,12 +891,12 @@ Get plugin stats:: "softirq": 0.0, "steal": 0.0, "system": 0.0, - "total": 63.0, - "user": 1.0}, + "total": 58.0, + "user": 0.0}, {"cpu_number": 2, "guest": 0.0, "guest_nice": 0.0, - "idle": 36.0, + "idle": 42.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", @@ -947,12 +904,12 @@ Get plugin stats:: "softirq": 0.0, "steal": 0.0, "system": 0.0, - "total": 64.0, + "total": 58.0, "user": 0.0}, {"cpu_number": 3, "guest": 0.0, "guest_nice": 0.0, - "idle": 37.0, + "idle": 44.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", @@ -960,25 +917,25 @@ Get plugin stats:: "softirq": 0.0, "steal": 0.0, "system": 0.0, - "total": 63.0, + "total": 56.0, "user": 0.0}, {"cpu_number": 4, "guest": 0.0, "guest_nice": 0.0, - "idle": 7.0, + "idle": 11.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", "nice": 0.0, "softirq": 0.0, "steal": 0.0, - "system": 2.0, - "total": 93.0, - "user": 26.0}, + "system": 3.0, + "total": 89.0, + "user": 30.0}, {"cpu_number": 5, "guest": 0.0, "guest_nice": 0.0, - "idle": 37.0, + "idle": 43.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", @@ -986,35 +943,9 @@ Get plugin stats:: "softirq": 0.0, "steal": 0.0, "system": 0.0, - "total": 63.0, + "total": 57.0, "user": 0.0}, {"cpu_number": 6, - "guest": 0.0, - "guest_nice": 0.0, - "idle": 30.0, - "iowait": 0.0, - "irq": 0.0, - "key": "cpu_number", - "nice": 0.0, - "softirq": 0.0, - "steal": 0.0, - "system": 1.0, - "total": 70.0, - "user": 6.0}, - {"cpu_number": 7, - "guest": 0.0, - "guest_nice": 0.0, - "idle": 37.0, - "iowait": 0.0, - "irq": 0.0, - "key": "cpu_number", - "nice": 0.0, - "softirq": 0.0, - "steal": 0.0, - "system": 0.0, - "total": 63.0, - "user": 0.0}, - {"cpu_number": 8, "guest": 0.0, "guest_nice": 0.0, "idle": 35.0, @@ -1024,13 +955,13 @@ Get plugin stats:: "nice": 0.0, "softirq": 0.0, "steal": 0.0, - "system": 0.0, + "system": 1.0, "total": 65.0, - "user": 1.0}, - {"cpu_number": 9, + "user": 7.0}, + {"cpu_number": 7, "guest": 0.0, "guest_nice": 0.0, - "idle": 37.0, + "idle": 42.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", @@ -1038,25 +969,51 @@ Get plugin stats:: "softirq": 0.0, "steal": 0.0, "system": 0.0, - "total": 63.0, + "total": 58.0, + "user": 1.0}, + {"cpu_number": 8, + "guest": 0.0, + "guest_nice": 0.0, + "idle": 41.0, + "iowait": 0.0, + "irq": 0.0, + "key": "cpu_number", + "nice": 0.0, + "softirq": 0.0, + "steal": 0.0, + "system": 0.0, + "total": 59.0, + "user": 3.0}, + {"cpu_number": 9, + "guest": 0.0, + "guest_nice": 0.0, + "idle": 43.0, + "iowait": 0.0, + "irq": 0.0, + "key": "cpu_number", + "nice": 0.0, + "softirq": 0.0, + "steal": 0.0, + "system": 0.0, + "total": 57.0, "user": 0.0}, {"cpu_number": 10, "guest": 0.0, "guest_nice": 0.0, - "idle": 36.0, - "iowait": 0.0, + "idle": 40.0, + "iowait": 1.0, "irq": 0.0, "key": "cpu_number", "nice": 0.0, "softirq": 0.0, "steal": 0.0, "system": 0.0, - "total": 64.0, - "user": 0.0}, + "total": 60.0, + "user": 2.0}, {"cpu_number": 11, "guest": 0.0, "guest_nice": 0.0, - "idle": 37.0, + "idle": 43.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", @@ -1064,25 +1021,12 @@ Get plugin stats:: "softirq": 0.0, "steal": 0.0, "system": 0.0, - "total": 63.0, + "total": 57.0, "user": 0.0}, {"cpu_number": 12, "guest": 0.0, "guest_nice": 0.0, - "idle": 37.0, - "iowait": 0.0, - "irq": 0.0, - "key": "cpu_number", - "nice": 0.0, - "softirq": 0.0, - "steal": 0.0, - "system": 0.0, - "total": 63.0, - "user": 0.0}, - {"cpu_number": 13, - "guest": 0.0, - "guest_nice": 0.0, - "idle": 36.0, + "idle": 42.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", @@ -1090,25 +1034,38 @@ Get plugin stats:: "softirq": 0.0, "steal": 0.0, "system": 1.0, - "total": 64.0, + "total": 58.0, + "user": 0.0}, + {"cpu_number": 13, + "guest": 0.0, + "guest_nice": 0.0, + "idle": 42.0, + "iowait": 0.0, + "irq": 0.0, + "key": "cpu_number", + "nice": 0.0, + "softirq": 0.0, + "steal": 0.0, + "system": 0.0, + "total": 58.0, "user": 0.0}, {"cpu_number": 14, "guest": 0.0, "guest_nice": 0.0, - "idle": 37.0, + "idle": 43.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", "nice": 0.0, "softirq": 0.0, "steal": 0.0, - "system": 0.0, - "total": 63.0, - "user": 1.0}, + "system": 1.0, + "total": 57.0, + "user": 0.0}, {"cpu_number": 15, "guest": 0.0, "guest_nice": 0.0, - "idle": 37.0, + "idle": 43.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", @@ -1116,9 +1073,9 @@ Get plugin stats:: "softirq": 0.0, "steal": 0.0, "system": 0.0, - "total": 63.0, - "user": 0.0}], - "swap": 28.8} + "total": 57.0, + "user": 1.0}], + "swap": 9.7} Fields descriptions: @@ -1156,14 +1113,14 @@ Get plugin stats:: "label": "Ambient", "type": "temperature_core", "unit": "C", - "value": 37, + "value": 35, "warning": 0}, {"critical": None, "key": "label", "label": "Ambient 3", "type": "temperature_core", "unit": "C", - "value": 33, + "value": 30, "warning": 0}] Fields descriptions: @@ -1224,7 +1181,7 @@ Get a specific item when field matches the given value:: "label": "Ambient", "type": "temperature_core", "unit": "C", - "value": 37, + "value": 35, "warning": 0}]} GET smart @@ -1255,7 +1212,7 @@ Fields descriptions: * **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*) +* **hr_name**: Human readable operating system name (unit is *None*) Get a specific field:: @@ -1268,7 +1225,7 @@ GET uptime Get plugin stats:: # curl http://localhost:61208/api/4/uptime - "19 days, 23:34:41" + "24 days, 2:45:13" GET version ----------- @@ -1276,7 +1233,7 @@ GET version Get plugin stats:: # curl http://localhost:61208/api/4/version - "4.1.1" + "4.1.2" GET wifi -------- @@ -1285,8 +1242,8 @@ Get plugin stats:: # curl http://localhost:61208/api/4/wifi [{"key": "ssid", - "quality_level": -75.0, - "quality_link": 35.0, + "quality_level": -60.0, + "quality_link": 50.0, "ssid": "wlp0s20f3"}] Get a specific field:: @@ -1298,8 +1255,8 @@ Get a specific item when field matches the given value:: # curl http://localhost:61208/api/4/wifi/ssid/wlp0s20f3 {"wlp0s20f3": [{"key": "ssid", - "quality_level": -75.0, - "quality_link": 35.0, + "quality_level": -60.0, + "quality_link": 50.0, "ssid": "wlp0s20f3"}]} GET all stats @@ -1344,34 +1301,34 @@ GET stats history History of a plugin:: # curl http://localhost:61208/api/4/cpu/history - {"system": [["2024-06-29T16:31:56.152620", 3.7], - ["2024-06-29T16:31:57.226915", 0.7], - ["2024-06-29T16:31:58.238907", 0.7]], - "user": [["2024-06-29T16:31:56.152614", 7.2], - ["2024-06-29T16:31:57.226912", 1.3], - ["2024-06-29T16:31:58.238902", 1.3]]} + {"system": [["2024-07-03T19:42:33.499180", 2.9], + ["2024-07-03T19:42:34.575670", 0.6], + ["2024-07-03T19:42:35.587081", 0.6]], + "user": [["2024-07-03T19:42:33.499174", 4.6], + ["2024-07-03T19:42:34.575667", 0.8], + ["2024-07-03T19:42:35.587076", 0.8]]} Limit history to last 2 values:: # curl http://localhost:61208/api/4/cpu/history/2 - {"system": [["2024-06-29T16:31:57.226915", 0.7], - ["2024-06-29T16:31:58.238907", 0.7]], - "user": [["2024-06-29T16:31:57.226912", 1.3], - ["2024-06-29T16:31:58.238902", 1.3]]} + {"system": [["2024-07-03T19:42:34.575670", 0.6], + ["2024-07-03T19:42:35.587081", 0.6]], + "user": [["2024-07-03T19:42:34.575667", 0.8], + ["2024-07-03T19:42:35.587076", 0.8]]} History for a specific field:: # curl http://localhost:61208/api/4/cpu/system/history - {"system": [["2024-06-29T16:31:54.997819", 3.7], - ["2024-06-29T16:31:56.152620", 3.7], - ["2024-06-29T16:31:57.226915", 0.7], - ["2024-06-29T16:31:58.238907", 0.7]]} + {"system": [["2024-07-03T19:42:32.349506", 2.9], + ["2024-07-03T19:42:33.499180", 2.9], + ["2024-07-03T19:42:34.575670", 0.6], + ["2024-07-03T19:42:35.587081", 0.6]]} Limit history for a specific field to last 2 values:: # curl http://localhost:61208/api/4/cpu/system/history - {"system": [["2024-06-29T16:31:57.226915", 0.7], - ["2024-06-29T16:31:58.238907", 0.7]]} + {"system": [["2024-07-03T19:42:34.575670", 0.6], + ["2024-07-03T19:42:35.587081", 0.6]]} GET limits (used for thresholds) -------------------------------- diff --git a/docs/man/glances.1 b/docs/man/glances.1 index d35c0512..f6f7c3b1 100644 --- a/docs/man/glances.1 +++ b/docs/man/glances.1 @@ -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" "Jun 29, 2024" "4.1.1" "Glances" +.TH "GLANCES" "1" "Jul 03, 2024" "4.1.2" "Glances" .SH NAME glances \- An eye on your system .SH SYNOPSIS diff --git a/glances/__init__.py b/glances/__init__.py index 750f32a9..40bb6410 100644 --- a/glances/__init__.py +++ b/glances/__init__.py @@ -19,7 +19,7 @@ import tracemalloc # Global name # Version should start and end with a numerical char # See https://packaging.python.org/specifications/core-metadata/#version -__version__ = '4.1.1' +__version__ = '4.1.2' __apiversion__ = '4' __author__ = 'Nicolas Hennion ' __license__ = 'LGPLv3' @@ -55,7 +55,7 @@ if psutil_version_info < psutil_min_version: def __signal_handler(signal, frame): - logger.debug(f"Signal {signal} catched") + logger.debug(f"Signal {signal} caught") end() diff --git a/glances/exports/glances_influxdb/__init__.py b/glances/exports/glances_influxdb/__init__.py index b0ae1ee8..cff8012c 100644 --- a/glances/exports/glances_influxdb/__init__.py +++ b/glances/exports/glances_influxdb/__init__.py @@ -156,7 +156,7 @@ class Export(GlancesExport): try: self.client.write_points(self._normalize(name, columns, points), time_precision="s") except Exception as e: - # Log level set to debug instead of error (see: issue #1561) - logger.debug(f"Cannot export {name} stats to InfluxDB ({e})") + # Log level set to warning instead of error (see: issue #1561) + logger.warning(f"Cannot export {name} stats to InfluxDB ({e})") else: logger.debug(f"Export {name} stats to InfluxDB") diff --git a/glances/exports/glances_influxdb2/__init__.py b/glances/exports/glances_influxdb2/__init__.py index 75e7698c..62d90a54 100644 --- a/glances/exports/glances_influxdb2/__init__.py +++ b/glances/exports/glances_influxdb2/__init__.py @@ -164,7 +164,7 @@ class Export(GlancesExport): try: self.client.write(self.bucket, self.org, self._normalize(name, columns, points), time_precision="s") except Exception as e: - # Log level set to debug instead of error (see: issue #1561) - logger.debug(f"Cannot export {name} stats to InfluxDB ({e})") + # Log level set to warning instead of error (see: issue #1561) + logger.warning(f"Cannot export {name} stats to InfluxDB ({e})") else: logger.debug(f"Export {name} stats to InfluxDB") diff --git a/glances/globals.py b/glances/globals.py index 96d8f781..0060e3d1 100644 --- a/glances/globals.py +++ b/glances/globals.py @@ -89,7 +89,7 @@ def printandflush(string): def to_ascii(s): """Convert the bytes string to a ASCII string - Usefull to remove accent (diacritics)""" + Useful to remove accent (diacritics)""" if isinstance(s, binary_type): return s.decode() return s.encode('ascii', 'ignore').decode() @@ -153,7 +153,7 @@ def subsample(data, sampling): Data should be a list of numerical itervalues - Return a subsampled list of sampling lenght + Return a subsampled list of sampling length """ if len(data) <= sampling: return data @@ -216,13 +216,13 @@ def key_exist_value_not_none(k, d): return k in d and d[k] is not None -def key_exist_value_not_none_not_v(k, d, value='', lengh=None): +def key_exist_value_not_none_not_v(k, d, value='', length=None): # Return True if: # - key k exists # - d[k] is not None # - d[k] != value - # - if lengh is not None and len(d[k]) >= lengh - return k in d and d[k] is not None and d[k] != value and (lengh is None or len(d[k]) >= lengh) + # - if length is not None and len(d[k]) >= length + return k in d and d[k] is not None and d[k] != value and (length is None or len(d[k]) >= length) def disable(class_name, var): @@ -425,12 +425,12 @@ def weak_lru_cache(maxsize=128, typed=False): def namedtuple_to_dict(data): - """Convert a namedtuple to a dict, using the _asdict() method embeded in PsUtil stats.""" + """Convert a namedtuple to a dict, using the _asdict() method embedded in PsUtil stats.""" return {k: (v._asdict() if hasattr(v, '_asdict') else v) for k, v in data.items()} def list_of_namedtuple_to_list_of_dict(data): - """Convert a list of namedtuples to a dict, using the _asdict() method embeded in PsUtil stats.""" + """Convert a list of namedtuples to a dict, using the _asdict() method embedded in PsUtil stats.""" return [namedtuple_to_dict(d) for d in data] diff --git a/glances/outputs/glances_curses.py b/glances/outputs/glances_curses.py index 1db8d752..6aed9a81 100644 --- a/glances/outputs/glances_curses.py +++ b/glances/outputs/glances_curses.py @@ -1211,7 +1211,7 @@ def build_colors_list(args): curses.init_pair(5, curses.COLOR_MAGENTA, -1) else: curses.init_pair(2, -1, curses.COLOR_RED) - curses.init_pair(3, -1, curses.COLOR_GREEN) + curses.init_pair(3, 0, curses.COLOR_GREEN) curses.init_pair(5, -1, curses.COLOR_MAGENTA) curses.init_pair(4, curses.COLOR_BLUE, -1) curses.init_pair(6, curses.COLOR_RED, -1) diff --git a/glances/plugins/README.rst b/glances/plugins/README.rst index 32da654e..8f8ef56c 100644 --- a/glances/plugins/README.rst +++ b/glances/plugins/README.rst @@ -11,7 +11,7 @@ It should implement a Class named PluginModel (inherited from GlancesPluginModel This class should be based on the MVC model. - model: where the stats are updated (update method) - view: where the stats are prepare to be displayed (update_views) -- controler: where the stats are displayed (msg_curse method) +- controller: where the stats are displayed (msg_curse method) A plugin should define the following global variables: diff --git a/glances/plugins/containers/__init__.py b/glances/plugins/containers/__init__.py index 08004e52..d906dd37 100644 --- a/glances/plugins/containers/__init__.py +++ b/glances/plugins/containers/__init__.py @@ -8,12 +8,14 @@ """Containers plugin.""" -import os from copy import deepcopy +from typing import Any, Dict, List, Optional, Tuple +from glances.globals import iteritems, itervalues from glances.logger import logger -from glances.plugins.containers.engines.docker import DockerContainersExtension, import_docker_error_tag -from glances.plugins.containers.engines.podman import PodmanContainersExtension, import_podman_error_tag +from glances.plugins.containers.engines import ContainersExtension +from glances.plugins.containers.engines.docker import DockerExtension, import_docker_error_tag +from glances.plugins.containers.engines.podman import PodmanExtension, import_podman_error_tag from glances.plugins.plugin.model import GlancesPluginModel from glances.processes import glances_processes from glances.processes import sort_stats as sort_stats_processes @@ -139,14 +141,15 @@ class PluginModel(GlancesPluginModel): # We want to display the stat in the curse interface self.display_curse = True + self.watchers: Dict[str, ContainersExtension] = {} + # Init the Docker API - self.docker_extension = DockerContainersExtension() if not import_docker_error_tag else None + if not import_docker_error_tag: + self.watchers['docker'] = DockerExtension() # Init the Podman API - if import_podman_error_tag: - self.podman_extension = None - else: - self.podman_extension = PodmanContainersExtension(podman_sock=self._podman_sock()) + if not import_podman_error_tag: + self.watchers['podman'] = PodmanExtension(podman_sock=self._podman_sock()) # Sort key self.sort_key = None @@ -155,7 +158,7 @@ class PluginModel(GlancesPluginModel): self.update() self.refresh_timer.set(0) - def _podman_sock(self): + def _podman_sock(self) -> str: """Return the podman sock. Could be desfined in the [docker] section thanks to the podman_sock option. Default value: unix:///run/user/1000/podman/podman.sock @@ -165,20 +168,19 @@ class PluginModel(GlancesPluginModel): return "unix:///run/user/1000/podman/podman.sock" return conf_podman_sock[0] - def exit(self): + def exit(self) -> None: """Overwrite the exit method to close threads.""" - if self.docker_extension: - self.docker_extension.stop() - if self.podman_extension: - self.podman_extension.stop() + for watcher in itervalues(self.watchers): + watcher.stop() + # Call the father class super().exit() - def get_key(self): + def get_key(self) -> str: """Return the key of the list.""" return 'name' - def get_export(self): + def get_export(self) -> List[Dict]: """Overwrite the default export method. - Only exports containers @@ -197,7 +199,7 @@ class PluginModel(GlancesPluginModel): return ret - def _all_tag(self): + def _all_tag(self) -> bool: """Return the all tag of the Glances/Docker configuration file. # By default, Glances only display running containers @@ -211,52 +213,35 @@ class PluginModel(GlancesPluginModel): @GlancesPluginModel._check_decorator @GlancesPluginModel._log_result_decorator - def update(self): + def update(self) -> List[Dict]: """Update Docker and podman stats using the input method.""" # Connection should be ok - if self.docker_extension is None and self.podman_extension is None: + if not self.watchers: return self.get_init_value() - if self.input_method == 'local': - # Update stats - stats_docker = self.update_docker() if self.docker_extension else {} - stats_podman = self.update_podman() if self.podman_extension else {} - stats = stats_docker.get('containers', []) + stats_podman.get('containers', []) - elif self.input_method == 'snmp': - # Update stats using SNMP - # Not available - pass + if self.input_method != 'local': + return self.get_init_value() + + # Update stats + stats = [] + for engine, watcher in iteritems(self.watchers): + version, containers = watcher.update(all_tag=self._all_tag()) + for container in containers: + container["engine"] = 'docker' + stats.extend(containers) # Sort and update the stats # @TODO: Have a look because sort did not work for the moment (need memory stats ?) self.sort_key, self.stats = sort_docker_stats(stats) - return self.stats - def update_docker(self): - """Update Docker stats using the input method.""" - version, containers = self.docker_extension.update(all_tag=self._all_tag()) - for container in containers: - container["engine"] = 'docker' - return {"version": version, "containers": containers} - - def update_podman(self): - """Update Podman stats.""" - version, containers = self.podman_extension.update(all_tag=self._all_tag()) - for container in containers: - container["engine"] = 'podman' - return {"version": version, "containers": containers} - - def get_user_ticks(self): - """Return the user ticks by reading the environment variable.""" - return os.sysconf(os.sysconf_names['SC_CLK_TCK']) - - def memory_usage_no_cache(self, mem): + @staticmethod + def memory_usage_no_cache(mem: Dict[str, float]) -> float: """Return the 'real' memory usage by removing inactive_file to usage""" # Ref: https://github.com/docker/docker-py/issues/3210 return mem['usage'] - (mem['inactive_file'] if 'inactive_file' in mem else 0) - def update_views(self): + def update_views(self) -> bool: """Update stats views.""" # Call the father's method super().update_views() @@ -305,7 +290,7 @@ class PluginModel(GlancesPluginModel): return True - def msg_curse(self, args=None, max_width=None): + def msg_curse(self, args=None, max_width: Optional[int] = None) -> List[str]: """Return the dict to display in the curse interface.""" # Init the return message ret = [] @@ -369,7 +354,9 @@ class PluginModel(GlancesPluginModel): if self.views['show_pod_name']: ret.append(self.curse_add_line(' {:{width}}'.format(container.get("pod_id", "-"), width=12))) # Name - ret.append(self.curse_add_line(self._msg_name(container=container, max_width=name_max_width))) + ret.append( + self.curse_add_line(' {:{width}}'.format(container['name'][:name_max_width], width=name_max_width)) + ) # Status status = self.container_alert(container['status']) msg = '{:>10}'.format(container['status'][0:10]) @@ -441,12 +428,8 @@ class PluginModel(GlancesPluginModel): return ret - def _msg_name(self, container, max_width): - """Build the container name.""" - name = container['name'][:max_width] - return ' {:{width}}'.format(name, width=max_width) - - def container_alert(self, status): + @staticmethod + def container_alert(status: str) -> str: """Analyse the container status.""" if status == 'running': return 'OK' @@ -457,7 +440,7 @@ class PluginModel(GlancesPluginModel): return 'CAREFUL' -def sort_docker_stats(stats): +def sort_docker_stats(stats: List[Dict[str, Any]]) -> Tuple[str, List[Dict[str, Any]]]: # Sort Docker stats using the same function than processes sort_by = glances_processes.sort_key sort_by_secondary = 'memory_usage' diff --git a/glances/plugins/containers/engines/__init__.py b/glances/plugins/containers/engines/__init__.py index e69de29b..d72e1328 100644 --- a/glances/plugins/containers/engines/__init__.py +++ b/glances/plugins/containers/engines/__init__.py @@ -0,0 +1,9 @@ +from typing import Any, Dict, Protocol, Tuple + + +class ContainersExtension(Protocol): + def stop(self) -> None: + raise NotImplementedError + + def update(self, all_tag) -> Tuple[Dict, list[Dict[str, Any]]]: + raise NotImplementedError diff --git a/glances/plugins/containers/engines/docker.py b/glances/plugins/containers/engines/docker.py index 81e94174..3f2cb5c6 100644 --- a/glances/plugins/containers/engines/docker.py +++ b/glances/plugins/containers/engines/docker.py @@ -207,7 +207,7 @@ class DockerStatsFetcher: return stats -class DockerContainersExtension: +class DockerExtension: """Glances' Containers Plugin's Docker Extension unit""" CONTAINER_ACTIVE_STATUS = ['running', 'paused'] diff --git a/glances/plugins/containers/engines/podman.py b/glances/plugins/containers/engines/podman.py index c913a58d..edbc952d 100644 --- a/glances/plugins/containers/engines/podman.py +++ b/glances/plugins/containers/engines/podman.py @@ -243,7 +243,7 @@ class PodmanPodStatsFetcher: return {"ior": ior, "iow": iow, "time_since_update": 1} -class PodmanContainersExtension: +class PodmanExtension: """Glances' Containers Plugin's Docker Extension unit""" CONTAINER_ACTIVE_STATUS = ['running', 'paused'] diff --git a/glances/plugins/plugin/model.py b/glances/plugins/plugin/model.py index daf4d8e6..53423c1f 100644 --- a/glances/plugins/plugin/model.py +++ b/glances/plugins/plugin/model.py @@ -98,7 +98,7 @@ class GlancesPluginModel: logger.debug(f'Load section {self.plugin_name} in Glances configuration file') self.load_limits(config=config) - # Init the alias (dictionnary) + # Init the alias (dictionary) self.alias = self.read_alias() # Init the actions diff --git a/glances/plugins/processlist/__init__.py b/glances/plugins/processlist/__init__.py index 17a4af65..bedd8285 100644 --- a/glances/plugins/processlist/__init__.py +++ b/glances/plugins/processlist/__init__.py @@ -543,7 +543,7 @@ class PluginModel(GlancesPluginModel): # Process list # Loop over processes (sorted by the sort key previously compute) # This is a Glances bottleneck (see flame graph), - # TODO: get_process_curses_data should be optimzed + # TODO: get_process_curses_data should be optimized for position, process in enumerate(processes_list_sorted): ret.extend(self.get_process_curses_data(process, position == args.cursor_position, args)) diff --git a/glances/plugins/system/__init__.py b/glances/plugins/system/__init__.py index ad0d7040..82933cc0 100644 --- a/glances/plugins/system/__init__.py +++ b/glances/plugins/system/__init__.py @@ -48,7 +48,7 @@ fields_description = { 'description': 'Operating system version', }, 'hr_name': { - 'description': 'Human readable operating sytem name', + 'description': 'Human readable operating system name', }, } diff --git a/glances/plugins/wifi/__init__.py b/glances/plugins/wifi/__init__.py index 0781c978..4b8a5215 100644 --- a/glances/plugins/wifi/__init__.py +++ b/glances/plugins/wifi/__init__.py @@ -8,7 +8,7 @@ """Wifi plugin. -Stats are retreived from the /proc/net/wireless file (Linux only): +Stats are retrieved from the /proc/net/wireless file (Linux only): # cat /proc/net/wireless Inter-| sta-| Quality | Discarded packets | Missed | WE diff --git a/glances/processes.py b/glances/processes.py index 9487b9ef..66f9e452 100644 --- a/glances/processes.py +++ b/glances/processes.py @@ -293,7 +293,7 @@ class GlancesProcesses: # - connections (TCP and UDP) # - CPU min/max/mean - # Set the extended stats list (OS dependant) + # Set the extended stats list (OS dependent) extended_stats = ['cpu_affinity', 'ionice', 'num_ctx_switches'] if LINUX: # num_fds only available on Unix system (see issue #1351) @@ -418,7 +418,7 @@ class GlancesProcesses: ##################### sorted_attrs = ['cpu_percent', 'cpu_times', 'memory_percent', 'name', 'status', 'num_threads'] displayed_attr = ['memory_info', 'nice', 'pid'] - # The following attributes are cached and only retreive every self.cache_timeout seconds + # The following attributes are cached and only retrieve every self.cache_timeout seconds # Warning: 'name' can not be cached because it is used for filtering cached_attrs = ['cmdline', 'username'] @@ -454,7 +454,7 @@ class GlancesProcesses: ) # Only get the info key # PsUtil 6+ no longer check PID reused #2755 so use is_running in the loop - # Note: not sure it is realy needed but CPU consumption look teh same with or without it + # Note: not sure it is realy needed but CPU consumption look the same with or without it processlist = [p.info for p in processlist if p.is_running()] # Sort the processes list by the current sort_key processlist = sort_stats(processlist, sorted_by=self.sort_key, reverse=True) diff --git a/glances/stats.py b/glances/stats.py index e033723f..8863dd45 100644 --- a/glances/stats.py +++ b/glances/stats.py @@ -136,7 +136,7 @@ class GlancesStats: """Load additional plugins if defined""" def get_addl_plugins(self, plugin_path): - """Get list of additonal plugins""" + """Get list of additional plugins""" _plugin_list = [] for plugin in os.listdir(plugin_path): path = os.path.join(plugin_path, plugin) @@ -167,7 +167,7 @@ class GlancesStats: sys.path.insert(0, path) for plugin in get_addl_plugins(self, path): if plugin in sys.modules: - logger.warn(f"Pugin {plugin} already in sys.modules, skipping (workaround: rename plugin)") + logger.warn(f"Plugin {plugin} already in sys.modules, skipping (workaround: rename plugin)") else: start_duration.reset() try: diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index afb28960..28aa2fc4 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,5 +1,5 @@ name: glances -version: '4.1.1+build01' +version: '4.1.2+build01' # Put the current stable version+buildXX summary: Glances an Eye on your system. A top/htop alternative. description: |