mirror of https://github.com/nicolargo/glances.git
Drop support for psutil < 5.3.0
Issue #1055 has been fixed in psutil 5.3.0 (see giampaolo/psutil#1074).
This commit is contained in:
parent
2cdc9b0b3d
commit
83d47a8bc9
1
NEWS
1
NEWS
|
|
@ -42,6 +42,7 @@ Bugs corrected:
|
|||
Backward-incompatible changes:
|
||||
|
||||
* Support for Python 3.3 has been dropped (EOL 2017-09-29)
|
||||
* Support for psutil < 5.3.0 has been dropped
|
||||
* Minimum supported Docker API version is now 1.21 (Docker plugins)
|
||||
* Support for InfluxDB < 0.9 is deprecated (InfluxDB exporter)
|
||||
* Remove graph export from Glances
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ Requirements
|
|||
============
|
||||
|
||||
- ``python 2.7,>=3.4``
|
||||
- ``psutil>=2.0.0`` (better with latest version)
|
||||
- ``psutil>=5.3.0`` (better with latest version)
|
||||
|
||||
Optional dependencies:
|
||||
|
||||
|
|
|
|||
|
|
@ -55,11 +55,11 @@ if sys.version_info < (2, 7) or (3, 0) <= sys.version_info < (3, 4):
|
|||
print('Glances requires at least Python 2.7 or 3.4 to run.')
|
||||
sys.exit(1)
|
||||
|
||||
# Check PSutil version
|
||||
psutil_min_version = (2, 0, 0)
|
||||
# Check psutil version
|
||||
psutil_min_version = (5, 3, 0)
|
||||
psutil_version_info = tuple([int(num) for num in psutil_version.split('.')])
|
||||
if psutil_version_info < psutil_min_version:
|
||||
print('PSutil 2.0 or higher is needed. Glances cannot start.')
|
||||
print('psutil 5.3.0 or higher is needed. Glances cannot start.')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@ import errno
|
|||
import os
|
||||
import sys
|
||||
|
||||
# Operating system flag
|
||||
# Note: Somes libs depends of OS
|
||||
# Note2: Included in PsUtil 4.0 or higher
|
||||
# OS constants (some libraries/features are OS-dependent)
|
||||
BSD = sys.platform.find('bsd') != -1
|
||||
LINUX = sys.platform.startswith('linux')
|
||||
MACOS = sys.platform.startswith('darwin')
|
||||
|
|
|
|||
|
|
@ -29,15 +29,17 @@ batinfo_tag = True
|
|||
try:
|
||||
import batinfo
|
||||
except ImportError:
|
||||
logger.debug("batpercent plugin - Batinfo library not found. Trying fallback to PsUtil.")
|
||||
logger.debug("batinfo library not found. Fallback to psutil.")
|
||||
batinfo_tag = False
|
||||
|
||||
# PsUtil library 5.2.0 or higher (optional; Linux-only)
|
||||
# Availability:
|
||||
# Linux, Windows, FreeBSD (psutil>=5.1.0)
|
||||
# macOS (psutil>=5.4.2)
|
||||
psutil_tag = True
|
||||
try:
|
||||
psutil.sensors_battery()
|
||||
except AttributeError:
|
||||
logger.debug("batpercent plugin - PsUtil 5.2.0 or higher is needed to grab battery stats.")
|
||||
logger.debug("Cannot grab battery status. Platform not supported.")
|
||||
psutil_tag = False
|
||||
|
||||
|
||||
|
|
@ -110,7 +112,7 @@ class GlancesGrabBat(object):
|
|||
'value': self.battery_percent,
|
||||
'unit': '%'}]
|
||||
elif psutil_tag and hasattr(self.bat.sensors_battery(), 'percent'):
|
||||
# Use the PSUtil 5.2.0 or higher lib to grab the stats
|
||||
# Use psutil to grab the stats
|
||||
# Give directly the battery percent
|
||||
self.bat_list = [{
|
||||
'label': 'Battery',
|
||||
|
|
|
|||
|
|
@ -109,38 +109,33 @@ class Plugin(GlancesPlugin):
|
|||
if hasattr(cpu_times_percent, stat):
|
||||
self.stats[stat] = getattr(cpu_times_percent, stat)
|
||||
|
||||
# Additionnal CPU stats (number of events / not as a %)
|
||||
# Additional CPU stats (number of events not as a %; psutil>=4.1.0)
|
||||
# ctx_switches: number of context switches (voluntary + involuntary) per second
|
||||
# interrupts: number of interrupts per second
|
||||
# soft_interrupts: number of software interrupts per second. Always set to 0 on Windows and SunOS.
|
||||
# syscalls: number of system calls since boot. Always set to 0 on Linux.
|
||||
try:
|
||||
cpu_stats = psutil.cpu_stats()
|
||||
except AttributeError:
|
||||
# cpu_stats only available with PSUtil 4.1 or +
|
||||
pass
|
||||
cpu_stats = psutil.cpu_stats()
|
||||
# By storing time data we enable Rx/s and Tx/s calculations in the
|
||||
# XML/RPC API, which would otherwise be overly difficult work
|
||||
# for users of the API
|
||||
time_since_update = getTimeSinceLastUpdate('cpu')
|
||||
|
||||
# Previous CPU stats are stored in the cpu_stats_old variable
|
||||
if not hasattr(self, 'cpu_stats_old'):
|
||||
# First call, we init the cpu_stats_old var
|
||||
self.cpu_stats_old = cpu_stats
|
||||
else:
|
||||
# By storing time data we enable Rx/s and Tx/s calculations in the
|
||||
# XML/RPC API, which would otherwise be overly difficult work
|
||||
# for users of the API
|
||||
time_since_update = getTimeSinceLastUpdate('cpu')
|
||||
for stat in cpu_stats._fields:
|
||||
if getattr(cpu_stats, stat) is not None:
|
||||
self.stats[stat] = getattr(cpu_stats, stat) - getattr(self.cpu_stats_old, stat)
|
||||
|
||||
# Previous CPU stats are stored in the cpu_stats_old variable
|
||||
if not hasattr(self, 'cpu_stats_old'):
|
||||
# First call, we init the cpu_stats_old var
|
||||
self.cpu_stats_old = cpu_stats
|
||||
else:
|
||||
for stat in cpu_stats._fields:
|
||||
if getattr(cpu_stats, stat) is not None:
|
||||
self.stats[stat] = getattr(cpu_stats, stat) - getattr(self.cpu_stats_old, stat)
|
||||
self.stats['time_since_update'] = time_since_update
|
||||
|
||||
self.stats['time_since_update'] = time_since_update
|
||||
# Core number is needed to compute the CTX switch limit
|
||||
self.stats['cpucore'] = self.nb_log_core
|
||||
|
||||
# Core number is needed to compute the CTX switch limit
|
||||
self.stats['cpucore'] = self.nb_log_core
|
||||
|
||||
# Save stats to compute next step
|
||||
self.cpu_stats_old = cpu_stats
|
||||
# Save stats to compute next step
|
||||
self.cpu_stats_old = cpu_stats
|
||||
|
||||
def update_snmp(self):
|
||||
"""Update CPU stats using SNMP."""
|
||||
|
|
|
|||
|
|
@ -87,13 +87,14 @@ class Plugin(GlancesPlugin):
|
|||
except UnicodeDecodeError:
|
||||
return self.stats
|
||||
|
||||
# New in PsUtil 3.0
|
||||
# New in psutil 3.0.0
|
||||
# - import the interface's status (issue #765)
|
||||
# - import the interface's speed (issue #718)
|
||||
netstatus = {}
|
||||
try:
|
||||
netstatus = psutil.net_if_stats()
|
||||
except (AttributeError, OSError):
|
||||
except OSError:
|
||||
# see psutil #797/glances #1106
|
||||
pass
|
||||
|
||||
# Previous network interface stats are stored in the network_old variable
|
||||
|
|
@ -134,18 +135,11 @@ class Plugin(GlancesPlugin):
|
|||
except KeyError:
|
||||
continue
|
||||
else:
|
||||
# Optional stats (only compliant with PsUtil 3.0+)
|
||||
# Interface status
|
||||
try:
|
||||
netstat['is_up'] = netstatus[net].isup
|
||||
except (KeyError, AttributeError):
|
||||
pass
|
||||
netstat['is_up'] = netstatus[net].isup
|
||||
# Interface speed in Mbps, convert it to bps
|
||||
# Can be always 0 on some OS
|
||||
try:
|
||||
netstat['speed'] = netstatus[net].speed * 1048576
|
||||
except (KeyError, AttributeError):
|
||||
pass
|
||||
# Can be always 0 on some OSes
|
||||
netstat['speed'] = netstatus[net].speed * 1048576
|
||||
|
||||
# Finaly, set the key
|
||||
netstat['key'] = self.get_key()
|
||||
|
|
|
|||
|
|
@ -262,8 +262,7 @@ class Plugin(GlancesPlugin):
|
|||
# the bare process name instead
|
||||
cmdline = p['cmdline']
|
||||
try:
|
||||
# XXX: remove `cmdline != ['']` when we'll drop support for psutil<4.0.0
|
||||
if cmdline and cmdline != ['']:
|
||||
if cmdline:
|
||||
path, cmd, arguments = split_cmdline(cmdline)
|
||||
if os.path.isdir(path) and not args.process_short_name:
|
||||
msg = ' {}'.format(path) + os.sep
|
||||
|
|
|
|||
|
|
@ -226,14 +226,10 @@ class GlancesGrabSensors(object):
|
|||
self.init_temp = False
|
||||
self.stemps = {}
|
||||
try:
|
||||
# psutil>=5.1.0 is required
|
||||
# psutil>=5.1.0, Linux-only
|
||||
self.stemps = psutil.sensors_temperatures()
|
||||
except AttributeError:
|
||||
logger.warning("Temperature sensors are only available on Linux")
|
||||
logger.warning("PsUtil 5.1.0 or higher is needed to grab temperatures sensors")
|
||||
except OSError as e:
|
||||
# FreeBSD: If oid 'hw.acpi.battery' not present, Glances wont start #1055
|
||||
logger.error("Can not grab temperatures sensors ({})".format(e))
|
||||
logger.debug("Cannot grab temperatures. Platform not supported.")
|
||||
else:
|
||||
self.init_temp = True
|
||||
|
||||
|
|
@ -241,13 +237,10 @@ class GlancesGrabSensors(object):
|
|||
self.init_fan = False
|
||||
self.sfans = {}
|
||||
try:
|
||||
# psutil>=5.2.0 is required
|
||||
# psutil>=5.2.0, Linux-only
|
||||
self.sfans = psutil.sensors_fans()
|
||||
except AttributeError:
|
||||
logger.warning("Fan speed sensors are only available on Linux")
|
||||
logger.warning("PsUtil 5.2.0 or higher is needed to grab fans sensors")
|
||||
except OSError as e:
|
||||
logger.error("Can not grab fans sensors ({})".format(e))
|
||||
logger.debug("Cannot grab fans speed. Platform not supported.")
|
||||
else:
|
||||
self.init_fan = True
|
||||
|
||||
|
|
|
|||
|
|
@ -242,31 +242,16 @@ class GlancesProcesses(object):
|
|||
if not WINDOWS:
|
||||
standard_attrs += ['gids']
|
||||
|
||||
# and build the processes stats list
|
||||
try:
|
||||
# PsUtil 2.0 or higher
|
||||
self.processlist = [p.info for p in psutil.process_iter(attrs=standard_attrs,
|
||||
ad_value=None)
|
||||
# OS specifics processes filter
|
||||
if not (BSD and p.info['name'] == 'idle') and
|
||||
not (WINDOWS and p.info['name'] == 'System Idle Process') and
|
||||
not (MACOS and p.info['name'] == 'kernel_task') and
|
||||
# Kernel threads filter
|
||||
not (self.no_kernel_threads and LINUX and p.info['gids'].real == 0) and
|
||||
# User filter
|
||||
not (self._filter.is_filtered(p.info))]
|
||||
except TypeError:
|
||||
# Fallback for PsUtil 2.0
|
||||
before_filter = [p.as_dict(attrs=standard_attrs, ad_value=None) for p in psutil.process_iter()]
|
||||
self.processlist = [p for p in before_filter
|
||||
# OS specifics processes filter
|
||||
if not (BSD and p['name'] == 'idle') and
|
||||
not (WINDOWS and p['name'] == 'System Idle Process') and
|
||||
not (MACOS and p['name'] == 'kernel_task') and
|
||||
# Kernel threads filter
|
||||
not (self.no_kernel_threads and LINUX and p['gids'].real == 0) and
|
||||
# User filter
|
||||
not (self._filter.is_filtered(p))]
|
||||
# and build the processes stats list (psutil>=5.3.0)
|
||||
self.processlist = [p.info for p in psutil.process_iter(attrs=standard_attrs, ad_value=None)
|
||||
# OS-related processes filter
|
||||
if not (BSD and p.info['name'] == 'idle') and
|
||||
not (WINDOWS and p.info['name'] == 'System Idle Process') and
|
||||
not (MACOS and p.info['name'] == 'kernel_task') and
|
||||
# Kernel threads filter
|
||||
not (self.no_kernel_threads and LINUX and p.info['gids'].real == 0) and
|
||||
# User filter
|
||||
not (self._filter.is_filtered(p.info))]
|
||||
|
||||
# Sort the processes list by the current sort_key
|
||||
self.processlist = sort_stats(self.processlist,
|
||||
|
|
@ -305,11 +290,10 @@ class GlancesProcesses(object):
|
|||
extended['memory_swap'] = sum([v.swap for v in top_process.memory_maps()])
|
||||
except psutil.NoSuchProcess:
|
||||
pass
|
||||
except (psutil.AccessDenied, TypeError, NotImplementedError):
|
||||
except (psutil.AccessDenied, NotImplementedError):
|
||||
# NotImplementedError: /proc/${PID}/smaps file doesn't exist
|
||||
# on kernel < 2.6.14 or CONFIG_MMU kernel configuration option
|
||||
# is not enabled (see psutil #533/glances #413).
|
||||
# XXX: Remove TypeError once we'll drop psutil < 3.0.0.
|
||||
extended['memory_swap'] = None
|
||||
try:
|
||||
extended['tcp'] = len(top_process.connections(kind="tcp"))
|
||||
|
|
|
|||
Loading…
Reference in New Issue