summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBharath Vignesh J K <52282402+RazCrimson@users.noreply.github.com>2024-05-01 23:21:35 +0530
committerBharath Vignesh J K <52282402+RazCrimson@users.noreply.github.com>2024-05-01 23:21:35 +0530
commit5b54ef9baf14ae200a2b93f50533b486ae2ae0e0 (patch)
treec4e9266e71604969a7cb081251494f0d9e7ffbc2
parent6f30f135c61d164e30c4c159ea3919ed7bd33684 (diff)
parente0f7498b7e85fd215a1d55f1b126cccd44ef5809 (diff)
Merge branch 'refs/heads/develop' into 2637-docker-memory-usage-is-incorrect
# Conflicts: # glances/outputs/static/public/glances.js
-rw-r--r--.github/workflows/test.yml59
-rw-r--r--README.rst40
-rw-r--r--conf/glances.conf7
-rwxr-xr-xdocker-compose/glances.conf7
-rw-r--r--glances/outputs/glances_curses.py6
-rw-r--r--glances/outputs/static/js/components/plugin-containers.vue6
-rw-r--r--glances/plugins/help/__init__.py50
-rw-r--r--glances/plugins/mem/__init__.py8
-rw-r--r--glances/plugins/now/__init__.py4
-rw-r--r--glances/plugins/percpu/__init__.py5
-rw-r--r--glances/plugins/plugin/model.py10
-rw-r--r--glances/plugins/processlist/__init__.py2
-rw-r--r--glances/plugins/quicklook/__init__.py2
-rw-r--r--glances/plugins/sensors/__init__.py10
-rw-r--r--glances/plugins/smart/__init__.py2
-rw-r--r--glances/plugins/system/__init__.py2
-rw-r--r--glances/snmp.py7
-rw-r--r--glances/standalone.py5
-rw-r--r--optional-requirements.txt2
-rw-r--r--requirements.txt1
20 files changed, 130 insertions, 105 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 030730f8..b19bad50 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -47,33 +47,38 @@ jobs:
run: |
python ./unitest.py
- test-windows:
-
- # https://github.com/actions/runner-images?tab=readme-ov-file#available-images
- runs-on: windows-latest
- strategy:
- matrix:
- # Python version "3.12" introduce this issue:
- # https://github.com/nicolargo/glances/actions/runs/6439648370/job/17487567454
- python-version: ["3.8", "3.9", "3.10", "3.11"]
- steps:
-
- - uses: actions/checkout@v4
-
- - name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python@v4
- with:
- python-version: ${{ matrix.python-version }}
-
- - name: Install dependencies
- run: |
- python -m pip install --upgrade pip
- if (Test-Path -PathType Leaf "requirements.txt") { python -m pip install -r requirements.txt }
- python setup.py install
-
- - name: Unitary tests
- run: |
- python ./unitest.py
+ # Error appear with h11, not related to Glances
+ # Should be tested if correction is done
+ # Installed c:\hostedtoolcache\windows\python\3.9.13\x64\lib\site-packages\exceptiongroup-1.2.1-py3.9.egg
+ # error: h11 0.14.0 is installed but h11<0.13,>=0.11 is required by {'httpcore'}
+ # Error: Process completed with exit code 1.
+ # test-windows:
+
+ # # https://github.com/actions/runner-images?tab=readme-ov-file#available-images
+ # runs-on: windows-latest
+ # strategy:
+ # matrix:
+ # # Python version "3.12" introduce this issue:
+ # # https://github.com/nicolargo/glances/actions/runs/6439648370/job/17487567454
+ # python-version: ["3.8", "3.9", "3.10", "3.11"]
+ # steps:
+
+ # - uses: actions/checkout@v4
+
+ # - name: Set up Python ${{ matrix.python-version }}
+ # uses: actions/setup-python@v4
+ # with:
+ # python-version: ${{ matrix.python-version }}
+
+ # - name: Install dependencies
+ # run: |
+ # python -m pip install --upgrade pip
+ # if (Test-Path -PathType Leaf "requirements.txt") { python -m pip install -r requirements.txt }
+ # python setup.py install
+
+ # - name: Unitary tests
+ # run: |
+ # python ./unitest.py
test-macos:
diff --git a/README.rst b/README.rst
index 059fd379..97778e0c 100644
--- a/README.rst
+++ b/README.rst
@@ -87,7 +87,6 @@ Requirements
- ``defusedxml`` (in order to monkey patch xmlrpc)
- ``packaging`` (for the version comparison)
- ``ujson`` (an optimized alternative to the standard json module)
-- ``pytz`` (for the timezone support)
- ``pydantic`` (for the data validation support)
*Note for Python 2 users*
@@ -122,7 +121,7 @@ Optional dependencies:
- ``pygal`` (for the graph export module)
- ``pymdstat`` (for RAID support) [Linux-only]
- ``pymongo`` (for the MongoDB export module)
-- ``pysnmp`` (for SNMP support)
+- ``pysnmp-lextudio`` (for SNMP support)
- ``pySMART.smartx`` (for HDD Smart support) [Linux-only]
- ``pyzmq`` (for the ZeroMQ export module)
- ``requests`` (for the Ports, Cloud plugins and RESTful export module)
@@ -136,26 +135,27 @@ Installation
There are several methods to test/install Glances on your system. Choose your weapon!
-PyPI: The standard way
-----------------------
+PyPI: Pip, the standard way
+---------------------------
Glances is on ``PyPI``. By using PyPI, you will be using the latest
stable version.
-To install Glances, simply use ``pip``:
+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.
.. code-block:: console
pip install --user glances
*Note*: Python headers are required to install `psutil`_, a Glances
-dependency. For example, on Debian/Ubuntu **the simplest** is ``apt install python3-psutil`` or alternatively need to install first
+dependency. For example, on Debian/Ubuntu **the simplest** is
+``apt install python3-psutil`` or alternatively need to install first
the *python-dev* package and gcc (*python-devel* on Fedora/CentOS/RHEL).
For Windows, just install psutil from the binary installation file.
-*Note 2 (for the Wifi plugin)*: If you want to use the Wifi plugin, you need
-to install the *wireless-tools* package on your system.
-
By default, Glances is installed without the Web interface dependencies.
To install it, use the following command:
@@ -182,24 +182,18 @@ If you want to test the develop version (could be instable), enter:
pip install --user -i https://test.pypi.org/simple/ Glances
-Glances Auto Install script: the easy way
------------------------------------------
-
-To install both dependencies and the latest Glances production ready version
-(aka *master* branch), just enter the following command line:
-
-.. code-block:: console
+PyPI: PipX, the alternative way
+-------------------------------
- curl -L https://bit.ly/glances | /bin/bash
+Install PipX on your system (apt install pipx on Ubuntu).
-or
+Install Glances (with all features):
.. code-block:: console
- wget -O- https://bit.ly/glances | /bin/bash
+ pipx install 'glances[all]'
-*Note*: This is only supported on some GNU/Linux distributions and Mac OS X.
-If you want to support other distributions, please contribute to `glancesautoinstall`_.
+The glances script will be installed in the ~/.local/bin folder.
Docker: the cloudy way
----------------------
@@ -257,8 +251,8 @@ Run the container in *Web server mode*:
For a full list of options, see the Glances `Docker`_ documentation page.
-GNU/Linux
----------
+GNU/Linux package
+-----------------
`Glances` is available on many Linux distributions, so you should be
able to install it using your favorite package manager. Be aware that
diff --git a/conf/glances.conf b/conf/glances.conf
index 10f48a6d..a7ed6374 100644
--- a/conf/glances.conf
+++ b/conf/glances.conf
@@ -239,7 +239,7 @@ public_template={continent_name}/{country_name}/{city_name}
[connections]
# Display additional information about TCP connections
-# This plugin is disabled by default
+# This plugin is disabled by default because it consumes lots of CPU
disable=True
# nf_conntrack thresholds in %
nf_conntrack_percent_careful=70
@@ -333,8 +333,9 @@ port=7634
[sensors]
# Documentation: https://glances.readthedocs.io/en/latest/aoa/sensors.html
disable=False
-# By default refresh every refresh time * 2
-#refresh=6
+# Set the refresh multiplicator for the sensors
+# By default refresh every Glances refresh * 3 (increase to reduce CPU consumption)
+#refresh=3
# Hide some sensors (comma separated list of regexp)
hide=unknown.*
# Show only the following sensors (comma separated list of regexp)
diff --git a/docker-compose/glances.conf b/docker-compose/glances.conf
index 74362ea9..225700fa 100755
--- a/docker-compose/glances.conf
+++ b/docker-compose/glances.conf
@@ -239,7 +239,7 @@ public_template={continent_name}/{country_name}/{city_name}
[connections]
# Display additional information about TCP connections
-# This plugin is disabled by default
+# This plugin is disabled by default because it consumes lots of CPU
disable=True
# nf_conntrack thresholds in %
nf_conntrack_percent_careful=70
@@ -333,8 +333,9 @@ port=7634
[sensors]
# Documentation: https://glances.readthedocs.io/en/latest/aoa/sensors.html
disable=False
-# By default refresh every refresh time * 2
-#refresh=6
+# Set the refresh multiplicator for the sensors
+# By default refresh every Glances refresh * 3 (increase to reduce CPU consumption)
+#refresh=3
# Hide some sensors (comma separated list of regexp)
hide=unknown.*
# Show only the following sensors (comma separated list of regexp)
diff --git a/glances/outputs/glances_curses.py b/glances/outputs/glances_curses.py
index d95e63aa..e7e032f5 100644
--- a/glances/outputs/glances_curses.py
+++ b/glances/outputs/glances_curses.py
@@ -1130,6 +1130,10 @@ class _GlancesCurses(object):
update the terminal."""
self.term_window.erase()
+ def refresh(self):
+ """Refresh the windows"""
+ self.term_window.refresh()
+
def flush(self, stats, cs_status=None):
"""Erase and update the screen.
@@ -1139,8 +1143,10 @@ class _GlancesCurses(object):
"Connected": Client is connected to the server
"Disconnected": Client is disconnected from the server
"""
+ # See https://stackoverflow.com/a/43486979/1919431
self.erase()
self.display(stats, cs_status=cs_status)
+ self.refresh()
def update(self, stats, duration=3, cs_status=None, return_to_browser=False):
"""Update the screen.
diff --git a/glances/outputs/static/js/components/plugin-containers.vue b/glances/outputs/static/js/components/plugin-containers.vue
index db5abfd8..51366399 100644
--- a/glances/outputs/static/js/components/plugin-containers.vue
+++ b/glances/outputs/static/js/components/plugin-containers.vue
@@ -29,7 +29,7 @@
>
MEM
</div>
- <div class="table-cell">/MAX</div>
+ <div class="table-cell text-left">/MAX</div>
<div class="table-cell">IOR/s</div>
<div class="table-cell">IOW/s</div>
<div class="table-cell">RX/s</div>
@@ -56,8 +56,8 @@
<div class="table-cell">
{{ $filters.bytes(container.memory_usage) }}
</div>
- <div class="table-cell">
- {{ $filters.bytes(container.limit) }}
+ <div class="table-cell text-left">
+ /{{ $filters.bytes(container.limit) }}
</div>
<div class="table-cell">
{{ $filters.bytes(container.io_rx) }}
diff --git a/glances/plugins/help/__init__.py b/glances/plugins/help/__init__.py
index 607d682f..0fe571fa 100644
--- a/glances/plugins/help/__init__.py
+++ b/glances/plugins/help/__init__.py
@@ -106,30 +106,46 @@ class PluginModel(GlancesPluginModel):
('toggle_linux_percentage', msg_col.format('0', 'Load, Linux/percentage')),
('toggle_cpu_individual_combined', msg_col.format('1', 'CPU, individual/combined')),
('toggle_gpu_individual_combined', msg_col.format('6', 'GPU, individual/combined')),
- ('toggle_short_full',
- msg_col.format('S',
- 'Process names, short/full') if self.args.webserver else msg_col.format('/', 'Process names, short/full')),
+ (
+ 'toggle_short_full',
+ (
+ msg_col.format('S', 'Process names, short/full')
+ if self.args and self.args.webserver
+ else msg_col.format('/', 'Process names, short/full')
+ ),
+ ),
('header_miscellaneous', msg_header.format('MISCELLANEOUS:')),
- ('misc_erase_process_filter',
- '' if self.args.webserver else msg_col.format('E', 'Erase process filter')),
- ('misc_generate_history_graphs',
- '' if self.args.webserver else msg_col.format('g', 'Generate history graphs')),
+ (
+ 'misc_erase_process_filter',
+ '' if self.args and self.args.webserver else msg_col.format('E', 'Erase process filter'),
+ ),
+ (
+ 'misc_generate_history_graphs',
+ '' if self.args and self.args.webserver else msg_col.format('g', 'Generate history graphs'),
+ ),
('misc_help', msg_col.format('h', 'HELP')),
- ('misc_accumulate_processes_by_program',
- '' if self.args.webserver else msg_col.format('j', 'Display threads or programs')),
+ (
+ 'misc_accumulate_processes_by_program',
+ '' if self.args and self.args.webserver else msg_col.format('j', 'Display threads or programs'),
+ ),
('misc_increase_nice_process', msg_col.format('+', 'Increase nice process')),
('misc_decrease_nice_process', msg_col.format('-', 'Decrease nice process (need admin rights)')),
- ('misc_kill_process',
- '' if self.args.webserver else msg_col.format('k', 'Kill process')),
- ('misc_reset_processes_summary_min_max',
- '' if self.args.webserver else msg_col.format('M', 'Reset processes summary min/max')),
- ('misc_quit',
- '' if self.args.webserver else msg_col.format('q', 'QUIT (or Esc or Ctrl-C)')),
+ ('misc_kill_process', '' if self.args and self.args.webserver else msg_col.format('k', 'Kill process')),
+ (
+ 'misc_reset_processes_summary_min_max',
+ '' if self.args and self.args.webserver else msg_col.format('M', 'Reset processes summary min/max'),
+ ),
+ (
+ 'misc_quit',
+ '' if self.args and self.args.webserver else msg_col.format('q', 'QUIT (or Esc or Ctrl-C)'),
+ ),
('misc_reset_history', msg_col.format('r', 'Reset history')),
('misc_delete_warning_alerts', msg_col.format('w', 'Delete warning alerts')),
('misc_delete_warning_and_critical_alerts', msg_col.format('x', 'Delete warning & critical alerts')),
- ('misc_edit_process_filter_pattern',
- '' if self.args.webserver else ' ENTER: Edit process filter pattern'),
+ (
+ 'misc_edit_process_filter_pattern',
+ '' if self.args and self.args.webserver else ' ENTER: Edit process filter pattern',
+ ),
]
)
diff --git a/glances/plugins/mem/__init__.py b/glances/plugins/mem/__init__.py
index b44181b1..5921b131 100644
--- a/glances/plugins/mem/__init__.py
+++ b/glances/plugins/mem/__init__.py
@@ -204,12 +204,8 @@ class PluginModel(GlancesPluginModel):
self.reset()
return self.stats
- for key in iterkeys(stats):
- if stats[key] != '':
- stats[key] = float(stats[key]) * 1024
-
- # Use the 'free'/htop calculation
- stats['free'] = stats['free'] - stats['total'] + (stats['buffers'] + stats['cached'])
+ for k in stats:
+ stats[k] = int(stats[k]) * 1024
# used=total-free
stats['used'] = stats['total'] - stats['free']
diff --git a/glances/plugins/now/__init__.py b/glances/plugins/now/__init__.py
index 3f997b71..dd88b954 100644
--- a/glances/plugins/now/__init__.py
+++ b/glances/plugins/now/__init__.py
@@ -53,9 +53,9 @@ class PluginModel(GlancesPluginModel):
# Set the message position
self.align = 'bottom'
- if args.strftime_format:
+ if args and args.strftime_format:
self.strftime = args.strftime_format
- elif config is not None:
+ elif config:
if 'global' in config.as_dict():
self.strftime = config.as_dict()['global']['strftime_format']
diff --git a/glances/plugins/percpu/__init__.py b/glances/plugins/percpu/__init__.py
index d16ffb45..aa1204e4 100644
--- a/glances/plugins/percpu/__init__.py
+++ b/glances/plugins/percpu/__init__.py
@@ -108,7 +108,10 @@ class PluginModel(GlancesPluginModel):
self.display_curse = True
# Manage the maximum number of CPU to display (related to enhancement request #2734)
- self.max_cpu_display = config.get_int_value('percpu', 'max_cpu_display', 4)
+ if config:
+ self.max_cpu_display = config.get_int_value('percpu', 'max_cpu_display', 4)
+ else:
+ self.max_cpu_display = 4
def get_key(self):
"""Return the key of the list."""
diff --git a/glances/plugins/plugin/model.py b/glances/plugins/plugin/model.py
index 5a65d9a0..e711fb3f 100644
--- a/glances/plugins/plugin/model.py
+++ b/glances/plugins/plugin/model.py
@@ -350,8 +350,10 @@ class GlancesPluginModel(object):
ret = {}
if bulk:
# Bulk request
- snmp_result = snmp_client.getbulk_by_oid(0, 10, itervalues(*snmp_oid))
-
+ snmp_result = snmp_client.getbulk_by_oid(0,
+ 10,
+ *list(itervalues(snmp_oid)))
+ logger.info(snmp_result)
if len(snmp_oid) == 1:
# Bulk command for only one OID
# Note: key is the item indexed but the OID result
@@ -379,7 +381,7 @@ class GlancesPluginModel(object):
index += 1
else:
# Simple get request
- snmp_result = snmp_client.get_by_oid(itervalues(*snmp_oid))
+ snmp_result = snmp_client.get_by_oid(*list(itervalues(snmp_oid)))
# Build the internal dict with the SNMP result
for key in iterkeys(snmp_oid):
@@ -623,7 +625,7 @@ class GlancesPluginModel(object):
"""Return the plugin refresh time"""
ret = self.get_limits(item='refresh')
if ret is None:
- ret = self.args.time
+ ret = self.args.time if hasattr(self.args, 'time') else 2
return ret
def get_refresh_time(self):
diff --git a/glances/plugins/processlist/__init__.py b/glances/plugins/processlist/__init__.py
index ae4b0dcd..e29d2225 100644
--- a/glances/plugins/processlist/__init__.py
+++ b/glances/plugins/processlist/__init__.py
@@ -194,7 +194,7 @@ class PluginModel(GlancesPluginModel):
config.as_dict()['processlist']['export']))
# The default sort key could also be overwrite by command line (see #1903)
- if args.sort_processes_key is not None:
+ if args and args.sort_processes_key is not None:
glances_processes.set_sort_key(args.sort_processes_key, False)
# Note: 'glances_processes' is already init in the processes.py script
diff --git a/glances/plugins/quicklook/__init__.py b/glances/plugins/quicklook/__init__.py
index 6cf4ea25..48dd474b 100644
--- a/glances/plugins/quicklook/__init__.py
+++ b/glances/plugins/quicklook/__init__.py
@@ -92,7 +92,7 @@ class PluginModel(GlancesPluginModel):
self.display_curse = True
# Manage the maximum number of CPU to display (related to enhancement request #2734)
- self.max_cpu_display = config.get_int_value('percpu', 'max_cpu_display', 4)
+ self.max_cpu_display = config.get_int_value('percpu', 'max_cpu_display', 4) if config else 4
# Define the stats list
self.stats_list = self.get_conf_value('list', default=self.DEFAULT_STATS_LIST)
diff --git a/glances/plugins/sensors/__init__.py b/glances/plugins/sensors/__init__.py
index adeda67f..1eec639c 100644
--- a/glances/plugins/sensors/__init__.py
+++ b/glances/plugins/sensors/__init__.py
@@ -26,6 +26,11 @@ SENSOR_TEMP_UNIT = 'C'
SENSOR_FAN_TYPE = 'fan_speed'
SENSOR_FAN_UNIT = 'R'
+# Define the default refresh multiplicator
+# Default value is 3 * Glances refresh time
+# Can be overwritten by the refresh option in the sensors section of the glances.conf file
+DEFAULT_REFRESH = 3
+
# Fields description
# description: human readable description
# short_name: shortname to use un UI
@@ -96,9 +101,8 @@ class PluginModel(GlancesPluginModel):
self.display_curse = True
# Not necessary to refresh every refresh time
- # By default set to refresh * 2
- if self.get_refresh() == args.time:
- self.set_refresh(self.get_refresh() * 2)
+ if args and self.get_refresh() == args.time:
+ self.set_refresh(self.get_refresh() * DEFAULT_REFRESH)
def get_key(self):
"""Return the key of the list."""
diff --git a/glances/plugins/smart/__init__.py b/glances/plugins/smart/__init__.py
index 644efa04..f2e33d32 100644
--- a/glances/plugins/smart/__init__.py
+++ b/glances/plugins/smart/__init__.py
@@ -125,7 +125,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None, stats_init_value=[]):
"""Init the plugin."""
# check if user is admin
- if not is_admin():
+ if not is_admin() and args:
disable(args, "smart")
logger.debug("Current user is not admin, HDD SMART plugin disabled.")
diff --git a/glances/plugins/system/__init__.py b/glances/plugins/system/__init__.py
index 8e0e65fe..419d803e 100644
--- a/glances/plugins/system/__init__.py
+++ b/glances/plugins/system/__init__.py
@@ -132,7 +132,7 @@ class PluginModel(GlancesPluginModel):
self.set_refresh(60)
# Get the default message (if defined)
- self.system_info_msg = config.get_value('system', 'system_info_msg')
+ self.system_info_msg = config.get_value('system', 'system_info_msg') if config else None
@GlancesPluginModel._check_decorator
@GlancesPluginModel._log_result_decorator
diff --git a/glances/snmp.py b/glances/snmp.py
index 368efd19..fb6a6d93 100644
--- a/glances/snmp.py
+++ b/glances/snmp.py
@@ -41,12 +41,9 @@ class GlancesSNMPClient(object):
ret = {}
for name, val in varBinds:
if str(val) == '':
- ret[name.prettyPrint()] = ''
+ ret[str(name)] = ''
else:
- ret[name.prettyPrint()] = val.prettyPrint()
- # In Python 3, prettyPrint() return 'b'linux'' instead of 'linux'
- if ret[name.prettyPrint()].startswith('b\''):
- ret[name.prettyPrint()] = ret[name.prettyPrint()][2:-1]
+ ret[str(name)] = val.prettyPrint()
return ret
def __get_result__(self, errorIndication, errorStatus, errorIndex, varBinds):
diff --git a/glances/standalone.py b/glances/standalone.py
index 68700c8c..c28afe5e 100644
--- a/glances/standalone.py
+++ b/glances/standalone.py
@@ -148,15 +148,16 @@ class GlancesStandalone(object):
logger.debug('Stats updated duration: {} seconds'.format(counter.get()))
# Patch for issue1326 to avoid < 0 refresh
- adapted_refresh = self.refresh_time - counter.get()
- adapted_refresh = adapted_refresh if adapted_refresh > 0 else 0
+ adapted_refresh = (self.refresh_time - counter.get()) if (self.refresh_time - counter.get()) > 0 else 0
# Display stats
# and wait refresh_time - counter
if not self.quiet:
# The update function return True if an exit key 'q' or 'ESC'
# has been pressed.
+ counter_display = Counter()
ret = not self.screen.update(self.stats, duration=adapted_refresh)
+ logger.debug('Stats display duration: {} seconds'.format(counter_display.get() - adapted_refresh))
else:
# Nothing is displayed
# Break should be done via a signal (CTRL-C)
diff --git a/optional-requirements.txt b/optional-requirements.txt
index 6a92e6f8..37d5dd79 100644
--- a/optional-requirements.txt
+++ b/optional-requirements.txt
@@ -27,7 +27,7 @@ pygal
pymdstat
pymongo; python_version >= "3.7"
nvidia-ml-py; python_version >= "3.5"
-pysnmp
+pysnmp-lextudio; python_version >= "3.7"
pySMART.smartx
python-dateutil
pyzmq
diff --git a/requirements.txt b/requirements.txt
index af41c966..abb29186 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,5 +2,4 @@ psutil>=5.6.7
defusedxml
packaging
ujson>=5.4.0
-pytz
pydantic