diff options
author | Bharath Vignesh J K <52282402+RazCrimson@users.noreply.github.com> | 2024-05-01 23:21:35 +0530 |
---|---|---|
committer | Bharath Vignesh J K <52282402+RazCrimson@users.noreply.github.com> | 2024-05-01 23:21:35 +0530 |
commit | 5b54ef9baf14ae200a2b93f50533b486ae2ae0e0 (patch) | |
tree | c4e9266e71604969a7cb081251494f0d9e7ffbc2 | |
parent | 6f30f135c61d164e30c4c159ea3919ed7bd33684 (diff) | |
parent | e0f7498b7e85fd215a1d55f1b126cccd44ef5809 (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.yml | 59 | ||||
-rw-r--r-- | README.rst | 40 | ||||
-rw-r--r-- | conf/glances.conf | 7 | ||||
-rwxr-xr-x | docker-compose/glances.conf | 7 | ||||
-rw-r--r-- | glances/outputs/glances_curses.py | 6 | ||||
-rw-r--r-- | glances/outputs/static/js/components/plugin-containers.vue | 6 | ||||
-rw-r--r-- | glances/plugins/help/__init__.py | 50 | ||||
-rw-r--r-- | glances/plugins/mem/__init__.py | 8 | ||||
-rw-r--r-- | glances/plugins/now/__init__.py | 4 | ||||
-rw-r--r-- | glances/plugins/percpu/__init__.py | 5 | ||||
-rw-r--r-- | glances/plugins/plugin/model.py | 10 | ||||
-rw-r--r-- | glances/plugins/processlist/__init__.py | 2 | ||||
-rw-r--r-- | glances/plugins/quicklook/__init__.py | 2 | ||||
-rw-r--r-- | glances/plugins/sensors/__init__.py | 10 | ||||
-rw-r--r-- | glances/plugins/smart/__init__.py | 2 | ||||
-rw-r--r-- | glances/plugins/system/__init__.py | 2 | ||||
-rw-r--r-- | glances/snmp.py | 7 | ||||
-rw-r--r-- | glances/standalone.py | 5 | ||||
-rw-r--r-- | optional-requirements.txt | 2 | ||||
-rw-r--r-- | requirements.txt | 1 |
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: @@ -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 |