chg: ruff - pyupgrade

This commit is contained in:
Bharath Vignesh J K 2024-05-17 03:05:33 +05:30
parent f9a06a31f0
commit 108ffcdfb6
120 changed files with 835 additions and 1060 deletions

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# Glances documentation build configuration file, created by # Glances documentation build configuration file, created by
# sphinx-quickstart on Tue Mar 1 10:53:59 2016. # sphinx-quickstart on Tue Mar 1 10:53:59 2016.

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -44,11 +43,6 @@ try:
except locale.Error: except locale.Error:
print("Warning: Unable to set locale. Expect encoding problems.") print("Warning: Unable to set locale. Expect encoding problems.")
# Check Python version
if sys.version_info < (3, 4):
print('Glances requires at least Python 3.4 to run.')
sys.exit(1)
# Check psutil version # Check psutil version
psutil_min_version = (5, 3, 0) psutil_min_version = (5, 3, 0)
psutil_version_info = tuple([int(num) for num in psutil_version.split('.')]) psutil_version_info = tuple([int(num) for num in psutil_version.split('.')])
@ -56,11 +50,12 @@ if psutil_version_info < psutil_min_version:
print('psutil 5.3.0 or higher is needed. Glances cannot start.') print('psutil 5.3.0 or higher is needed. Glances cannot start.')
sys.exit(1) sys.exit(1)
# Trac malloc is only available on Python 3.4 or higher # Trac malloc is only available on Python 3.4 or higher
def __signal_handler(signal, frame): def __signal_handler(signal, frame):
logger.debug("Signal {} catched".format(signal)) logger.debug(f"Signal {signal} catched")
end() end()
@ -103,20 +98,16 @@ def start(config, args):
from glances.webserver import GlancesWebServer as GlancesMode from glances.webserver import GlancesWebServer as GlancesMode
# Init the mode # Init the mode
logger.info("Start {} mode".format(GlancesMode.__name__)) logger.info(f"Start {GlancesMode.__name__} mode")
mode = GlancesMode(config=config, args=args) mode = GlancesMode(config=config, args=args)
# Start the main loop # Start the main loop
logger.debug("Glances started in {} seconds".format(start_duration.get())) logger.debug(f"Glances started in {start_duration.get()} seconds")
if args.stop_after: if args.stop_after:
logger.info('Glances will be stopped in ~{} seconds'.format(args.stop_after * args.time)) logger.info(f'Glances will be stopped in ~{args.stop_after * args.time} seconds')
if args.memory_leak: if args.memory_leak:
print( print(f'Memory leak detection, please wait ~{args.stop_after * args.time * args.memory_leak * 2} seconds...')
'Memory leak detection, please wait ~{} seconds...'.format(
args.stop_after * args.time * args.memory_leak * 2
)
)
# First run without dump to fill the memory # First run without dump to fill the memory
mode.serve_n(args.stop_after) mode.serve_n(args.stop_after)
# Then start the memory-leak loop # Then start the memory-leak loop
@ -133,7 +124,7 @@ def start(config, args):
snapshot_end = tracemalloc.take_snapshot() snapshot_end = tracemalloc.take_snapshot()
snapshot_diff = snapshot_end.compare_to(snapshot_begin, 'filename') snapshot_diff = snapshot_end.compare_to(snapshot_begin, 'filename')
memory_leak = sum([s.size_diff for s in snapshot_diff]) memory_leak = sum([s.size_diff for s in snapshot_diff])
print("Memory consumption: {0:.1f}KB (see log for details)".format(memory_leak / 1000)) print(f"Memory consumption: {memory_leak / 1000:.1f}KB (see log for details)")
logger.info("Memory consumption (top 5):") logger.info("Memory consumption (top 5):")
for stat in snapshot_diff[:5]: for stat in snapshot_diff[:5]:
logger.info(stat) logger.info(stat)
@ -165,12 +156,10 @@ def main():
signal.signal(sig, __signal_handler) signal.signal(sig, __signal_handler)
# Log Glances and psutil version # Log Glances and psutil version
logger.info('Start Glances {}'.format(__version__)) logger.info(f'Start Glances {__version__}')
logger.info( python_impl = platform.python_implementation()
'{} {} ({}) and psutil {} detected'.format( python_ver = platform.python_version()
platform.python_implementation(), platform.python_version(), sys.executable, psutil_version logger.info(f'{python_impl} {python_ver} ({sys.executable}) and psutil {psutil_version} detected')
)
)
# Share global var # Share global var
global core global core

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# Glances - An eye on your system # Glances - An eye on your system
# #

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -22,7 +21,7 @@ else:
chevron_tag = True chevron_tag = True
class GlancesActions(object): class GlancesActions:
"""This class manage action if an alert is reached.""" """This class manage action if an alert is reached."""
def __init__(self, args=None): def __init__(self, args=None):
@ -80,13 +79,13 @@ class GlancesActions(object):
else: else:
cmd_full = cmd cmd_full = cmd
# Execute the action # Execute the action
logger.info("Action triggered for {} ({}): {}".format(stat_name, criticality, cmd_full)) logger.info(f"Action triggered for {stat_name} ({criticality}): {cmd_full}")
try: try:
ret = secure_popen(cmd_full) ret = secure_popen(cmd_full)
except OSError as e: except OSError as e:
logger.error("Action error for {} ({}): {}".format(stat_name, criticality, e)) logger.error(f"Action error for {stat_name} ({criticality}): {e}")
else: else:
logger.debug("Action result for {} ({}): {}".format(stat_name, criticality, ret)) logger.debug(f"Action result for {stat_name} ({criticality}): {ret}")
self.set(stat_name, criticality) self.set(stat_name, criticality)

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -27,7 +26,7 @@ from glances.logger import logger
from glances.timer import Timer from glances.timer import Timer
class GlancesAmp(object): class GlancesAmp:
"""Main class for Glances AMP.""" """Main class for Glances AMP."""
NAME = '?' NAME = '?'
@ -38,7 +37,7 @@ class GlancesAmp(object):
def __init__(self, name=None, args=None): def __init__(self, name=None, args=None):
"""Init AMP class.""" """Init AMP class."""
logger.debug("AMP - Init {} version {}".format(self.NAME, self.VERSION)) logger.debug(f"AMP - Init {self.NAME} version {self.VERSION}")
# AMP name (= module name without glances_) # AMP name (= module name without glances_)
if name is None: if name is None:
@ -74,7 +73,7 @@ class GlancesAmp(object):
amp_section = 'amp_' + self.amp_name amp_section = 'amp_' + self.amp_name
if hasattr(config, 'has_section') and config.has_section(amp_section): if hasattr(config, 'has_section') and config.has_section(amp_section):
logger.debug("AMP - {}: Load configuration".format(self.NAME)) logger.debug(f"AMP - {self.NAME}: Load configuration")
for param, _ in config.items(amp_section): for param, _ in config.items(amp_section):
try: try:
self.configs[param] = config.get_float_value(amp_section, param) self.configs[param] = config.get_float_value(amp_section, param)
@ -82,9 +81,9 @@ class GlancesAmp(object):
self.configs[param] = config.get_value(amp_section, param).split(',') self.configs[param] = config.get_value(amp_section, param).split(',')
if len(self.configs[param]) == 1: if len(self.configs[param]) == 1:
self.configs[param] = self.configs[param][0] self.configs[param] = self.configs[param][0]
logger.debug("AMP - {}: Load parameter: {} = {}".format(self.NAME, param, self.configs[param])) logger.debug(f"AMP - {self.NAME}: Load parameter: {param} = {self.configs[param]}")
else: else:
logger.debug("AMP - {}: Can not find section {} in the configuration file".format(self.NAME, self.amp_name)) logger.debug(f"AMP - {self.NAME}: Can not find section {self.amp_name} in the configuration file")
return False return False
if self.enable(): if self.enable():
@ -92,13 +91,12 @@ class GlancesAmp(object):
for k in ['refresh']: for k in ['refresh']:
if k not in self.configs: if k not in self.configs:
logger.warning( logger.warning(
"AMP - {}: Can not find configuration key {} in section {} (the AMP will be disabled)".format( f"AMP - {self.NAME}: Can not find configuration key {k} in section {self.amp_name} "
self.NAME, k, self.amp_name f"(the AMP will be disabled)"
)
) )
self.configs['enable'] = 'false' self.configs['enable'] = 'false'
else: else:
logger.debug("AMP - {} is disabled".format(self.NAME)) logger.debug(f"AMP - {self.NAME} is disabled")
# Init the count to 0 # Init the count to 0
self.configs['count'] = 0 self.configs['count'] = 0

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -44,7 +43,7 @@ class Amp(GlancesAmp):
def __init__(self, name=None, args=None): def __init__(self, name=None, args=None):
"""Init the AMP.""" """Init the AMP."""
self.NAME = name.capitalize() self.NAME = name.capitalize()
super(Amp, self).__init__(name=name, args=args) super().__init__(name=name, args=args)
def update(self, process_list): def update(self, process_list):
"""Update the AMP""" """Update the AMP"""
@ -54,7 +53,7 @@ class Amp(GlancesAmp):
try: try:
res = self.get('command') res = self.get('command')
except OSError as e: except OSError as e:
logger.debug('{}: Error while executing command ({})'.format(self.NAME, e)) logger.debug(f'{self.NAME}: Error while executing command ({e})')
return self.result() return self.result()
# No command found, use default message # No command found, use default message
if res is None: if res is None:

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -62,7 +61,7 @@ class Amp(GlancesAmp):
try: try:
res = check_output(self.get('systemctl_cmd').split()) res = check_output(self.get('systemctl_cmd').split())
except (OSError, CalledProcessError) as e: except (OSError, CalledProcessError) as e:
logger.debug('{}: Error while executing systemctl ({})'.format(self.NAME, e)) logger.debug(f'{self.NAME}: Error while executing systemctl ({e})')
else: else:
status = {} status = {}
# For each line # For each line
@ -79,7 +78,7 @@ class Amp(GlancesAmp):
# Build the output (string) message # Build the output (string) message
output = 'Services\n' output = 'Services\n'
for k, v in iteritems(status): for k, v in iteritems(status):
output += '{}: {}\n'.format(k, v) output += f'{k}: {v}\n'
self.set_result(output, separator=' ') self.set_result(output, separator=' ')
return self.result() return self.result()

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -61,7 +60,7 @@ class Amp(GlancesAmp):
try: try:
res = check_output(self.get('service_cmd').split(), stderr=STDOUT).decode('utf-8') res = check_output(self.get('service_cmd').split(), stderr=STDOUT).decode('utf-8')
except OSError as e: except OSError as e:
logger.debug('{}: Error while executing service ({})'.format(self.NAME, e)) logger.debug(f'{self.NAME}: Error while executing service ({e})')
else: else:
status = {'running': 0, 'stopped': 0, 'upstart': 0} status = {'running': 0, 'stopped': 0, 'upstart': 0}
# For each line # For each line
@ -79,7 +78,7 @@ class Amp(GlancesAmp):
# Build the output (string) message # Build the output (string) message
output = 'Services\n' output = 'Services\n'
for k, v in iteritems(status): for k, v in iteritems(status):
output += '{}: {}\n'.format(k, v) output += f'{k}: {v}\n'
self.set_result(output, separator=' ') self.set_result(output, separator=' ')
return self.result() return self.result()

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -18,7 +17,7 @@ from glances.logger import logger
from glances.processes import glances_processes from glances.processes import glances_processes
class AmpsList(object): class AmpsList:
"""This class describes the optional application monitoring process list. """This class describes the optional application monitoring process list.
The AMP list is a list of processes with a specific monitoring action. The AMP list is a list of processes with a specific monitoring action.
@ -57,9 +56,9 @@ class AmpsList(object):
try: try:
amp = __import__(os.path.basename(amp_module)) amp = __import__(os.path.basename(amp_module))
except ImportError as e: except ImportError as e:
logger.warning("Missing Python Lib ({}), cannot load AMP {}".format(e, amp_name)) logger.warning(f"Missing Python Lib ({e}), cannot load AMP {amp_name}")
except Exception as e: except Exception as e:
logger.warning("Cannot load AMP {} ({})".format(amp_name, e)) logger.warning(f"Cannot load AMP {amp_name} ({e})")
else: else:
# Add the AMP to the dictionary # Add the AMP to the dictionary
# The key is the AMP name # The key is the AMP name
@ -69,7 +68,7 @@ class AmpsList(object):
# Load the AMP configuration # Load the AMP configuration
self.__amps_dict[amp_name].load_config(self.config) self.__amps_dict[amp_name].load_config(self.config)
# Log AMPs list # Log AMPs list
logger.debug("AMPs list: {}".format(self.getList())) logger.debug(f"AMPs list: {self.getList()}")
return True return True
@ -108,7 +107,7 @@ class AmpsList(object):
if len(amps_list) > 0: if len(amps_list) > 0:
# At least one process is matching the regex # At least one process is matching the regex
logger.debug("AMPS: {} processes {} detected ({})".format(len(amps_list), k, amps_list)) logger.debug(f"AMPS: {len(amps_list)} processes {k} detected ({amps_list})")
# Call the AMP update method # Call the AMP update method
thread = threading.Thread(target=v.update_wrapper, args=[amps_list]) thread = threading.Thread(target=v.update_wrapper, args=[amps_list])
thread.start() thread.start()
@ -140,7 +139,7 @@ class AmpsList(object):
) )
except (TypeError, KeyError) as e: except (TypeError, KeyError) as e:
logger.debug("Can not build AMPS list ({})".format(e)) logger.debug(f"Can not build AMPS list ({e})")
return ret return ret

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -12,7 +11,7 @@
from datetime import datetime from datetime import datetime
class GlancesAttribute(object): class GlancesAttribute:
def __init__(self, name, description='', history_max_size=None): def __init__(self, name, description='', history_max_size=None):
"""Init the attribute """Init the attribute

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -27,7 +26,7 @@ except ImportError:
if zeroconf_tag: if zeroconf_tag:
zeroconf_min_version = (0, 17, 0) zeroconf_min_version = (0, 17, 0)
zeroconf_version = tuple([int(num) for num in __zeroconf_version.split('.')]) zeroconf_version = tuple([int(num) for num in __zeroconf_version.split('.')])
logger.debug("Zeroconf version {} detected.".format(__zeroconf_version)) logger.debug(f"Zeroconf version {__zeroconf_version} detected.")
if zeroconf_version < zeroconf_min_version: if zeroconf_version < zeroconf_min_version:
logger.critical("Please install zeroconf 0.17 or higher.") logger.critical("Please install zeroconf 0.17 or higher.")
sys.exit(1) sys.exit(1)
@ -35,10 +34,10 @@ if zeroconf_tag:
# Global var # Global var
# Recent versions of the zeroconf python package doesn't like a zeroconf type that ends with '._tcp.'. # Recent versions of the zeroconf python package doesn't like a zeroconf type that ends with '._tcp.'.
# Correct issue: zeroconf problem with zeroconf_type = "_%s._tcp." % 'glances' #888 # Correct issue: zeroconf problem with zeroconf_type = "_%s._tcp." % 'glances' #888
zeroconf_type = "_%s._tcp.local." % 'glances' zeroconf_type = "_{}._tcp.local.".format('glances')
class AutoDiscovered(object): class AutoDiscovered:
"""Class to manage the auto discovered servers dict.""" """Class to manage the auto discovered servers dict."""
def __init__(self): def __init__(self):
@ -67,7 +66,7 @@ class AutoDiscovered(object):
'type': 'DYNAMIC', 'type': 'DYNAMIC',
} # Server type: 'STATIC' or 'DYNAMIC' } # Server type: 'STATIC' or 'DYNAMIC'
self._server_list.append(new_server) self._server_list.append(new_server)
logger.debug("Updated servers list (%s servers): %s" % (len(self._server_list), self._server_list)) logger.debug(f"Updated servers list ({len(self._server_list)} servers): {self._server_list}")
def remove_server(self, name): def remove_server(self, name):
"""Remove a server from the dict.""" """Remove a server from the dict."""
@ -75,13 +74,13 @@ class AutoDiscovered(object):
if i['key'] == name: if i['key'] == name:
try: try:
self._server_list.remove(i) self._server_list.remove(i)
logger.debug("Remove server %s from the list" % name) logger.debug(f"Remove server {name} from the list")
logger.debug("Updated servers list (%s servers): %s" % (len(self._server_list), self._server_list)) logger.debug(f"Updated servers list ({len(self._server_list)} servers): {self._server_list}")
except ValueError: except ValueError:
logger.error("Cannot remove server %s from the list" % name) logger.error(f"Cannot remove server {name} from the list")
class GlancesAutoDiscoverListener(object): class GlancesAutoDiscoverListener:
"""Zeroconf listener for Glances server.""" """Zeroconf listener for Glances server."""
def __init__(self): def __init__(self):
@ -105,7 +104,7 @@ class GlancesAutoDiscoverListener(object):
""" """
if srv_type != zeroconf_type: if srv_type != zeroconf_type:
return False return False
logger.debug("Check new Zeroconf server: %s / %s" % (srv_type, srv_name)) logger.debug(f"Check new Zeroconf server: {srv_type} / {srv_name}")
info = zeroconf.get_service_info(srv_type, srv_name) info = zeroconf.get_service_info(srv_type, srv_name)
if info and (info.addresses or info.parsed_addresses): if info and (info.addresses or info.parsed_addresses):
address = info.addresses[0] if info.addresses else info.parsed_addresses[0] address = info.addresses[0] if info.addresses else info.parsed_addresses[0]
@ -114,7 +113,7 @@ class GlancesAutoDiscoverListener(object):
# Add server to the global dict # Add server to the global dict
self.servers.add_server(srv_name, new_server_ip, new_server_port) self.servers.add_server(srv_name, new_server_ip, new_server_port)
logger.info("New Glances server detected (%s from %s:%s)" % (srv_name, new_server_ip, new_server_port)) logger.info(f"New Glances server detected ({srv_name} from {new_server_ip}:{new_server_port})")
else: else:
logger.warning("New Glances server detected, but failed to be get Zeroconf ServiceInfo ") logger.warning("New Glances server detected, but failed to be get Zeroconf ServiceInfo ")
return True return True
@ -122,10 +121,10 @@ class GlancesAutoDiscoverListener(object):
def remove_service(self, zeroconf, srv_type, srv_name): def remove_service(self, zeroconf, srv_type, srv_name):
"""Remove the server from the list.""" """Remove the server from the list."""
self.servers.remove_server(srv_name) self.servers.remove_server(srv_name)
logger.info("Glances server %s removed from the autodetect list" % srv_name) logger.info(f"Glances server {srv_name} removed from the autodetect list")
class GlancesAutoDiscoverServer(object): class GlancesAutoDiscoverServer:
"""Implementation of the Zeroconf protocol (server side for the Glances client).""" """Implementation of the Zeroconf protocol (server side for the Glances client)."""
def __init__(self, args=None): def __init__(self, args=None):
@ -133,8 +132,8 @@ class GlancesAutoDiscoverServer(object):
logger.info("Init autodiscover mode (Zeroconf protocol)") logger.info("Init autodiscover mode (Zeroconf protocol)")
try: try:
self.zeroconf = Zeroconf() self.zeroconf = Zeroconf()
except socket.error as e: except OSError as e:
logger.error("Cannot start Zeroconf (%s)" % e) logger.error(f"Cannot start Zeroconf ({e})")
self.zeroconf_enable_tag = False self.zeroconf_enable_tag = False
else: else:
self.listener = GlancesAutoDiscoverListener() self.listener = GlancesAutoDiscoverListener()
@ -160,7 +159,7 @@ class GlancesAutoDiscoverServer(object):
self.zeroconf.close() self.zeroconf.close()
class GlancesAutoDiscoverClient(object): class GlancesAutoDiscoverClient:
"""Implementation of the zeroconf protocol (client side for the Glances server).""" """Implementation of the zeroconf protocol (client side for the Glances server)."""
def __init__(self, hostname, args=None): def __init__(self, hostname, args=None):
@ -168,8 +167,8 @@ class GlancesAutoDiscoverClient(object):
zeroconf_bind_address = args.bind_address zeroconf_bind_address = args.bind_address
try: try:
self.zeroconf = Zeroconf() self.zeroconf = Zeroconf()
except socket.error as e: except OSError as e:
logger.error("Cannot start zeroconf: {}".format(e)) logger.error(f"Cannot start zeroconf: {e}")
# XXX *BSDs: Segmentation fault (core dumped) # XXX *BSDs: Segmentation fault (core dumped)
# -- https://bitbucket.org/al45tair/netifaces/issues/15 # -- https://bitbucket.org/al45tair/netifaces/issues/15
@ -192,7 +191,7 @@ class GlancesAutoDiscoverClient(object):
try: try:
self.info = ServiceInfo( self.info = ServiceInfo(
zeroconf_type, zeroconf_type,
'{}:{}.{}'.format(hostname, args.port, zeroconf_type), f'{hostname}:{args.port}.{zeroconf_type}',
address=socket.inet_pton(address_family, zeroconf_bind_address), address=socket.inet_pton(address_family, zeroconf_bind_address),
port=args.port, port=args.port,
weight=0, weight=0,
@ -205,7 +204,7 @@ class GlancesAutoDiscoverClient(object):
# address (only one address) is replaced by addresses (list of addresses) # address (only one address) is replaced by addresses (list of addresses)
self.info = ServiceInfo( self.info = ServiceInfo(
zeroconf_type, zeroconf_type,
name='{}:{}.{}'.format(hostname, args.port, zeroconf_type), name=f'{hostname}:{args.port}.{zeroconf_type}',
addresses=[socket.inet_pton(address_family, zeroconf_bind_address)], addresses=[socket.inet_pton(address_family, zeroconf_bind_address)],
port=args.port, port=args.port,
weight=0, weight=0,
@ -216,9 +215,9 @@ class GlancesAutoDiscoverClient(object):
try: try:
self.zeroconf.register_service(self.info) self.zeroconf.register_service(self.info)
except Exception as e: except Exception as e:
logger.error("Error while announcing Glances server: {}".format(e)) logger.error(f"Error while announcing Glances server: {e}")
else: else:
print("Announce the Glances server on the LAN (using {} IP address)".format(zeroconf_bind_address)) print(f"Announce the Glances server on the LAN (using {zeroconf_bind_address} IP address)")
else: else:
logger.error("Cannot announce Glances server on the network: zeroconf library not found.") logger.error("Cannot announce Glances server on the network: zeroconf library not found.")

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -9,7 +8,6 @@
"""Manage the Glances client.""" """Manage the Glances client."""
import socket
import sys import sys
import time import time
@ -30,7 +28,7 @@ class GlancesClientTransport(Transport):
self.timeout = timeout self.timeout = timeout
class GlancesClient(object): class GlancesClient:
"""This class creates and manages the TCP client.""" """This class creates and manages the TCP client."""
def __init__(self, config=None, args=None, timeout=7, return_to_browser=False): def __init__(self, config=None, args=None, timeout=7, return_to_browser=False):
@ -49,10 +47,10 @@ class GlancesClient(object):
# Build the URI # Build the URI
if args.password != "": if args.password != "":
self.uri = 'http://{}:{}@{}:{}'.format(args.username, args.password, args.client, args.port) self.uri = f'http://{args.username}:{args.password}@{args.client}:{args.port}'
else: else:
self.uri = 'http://{}:{}'.format(args.client, args.port) self.uri = f'http://{args.client}:{args.port}'
logger.debug("Try to connect to {}".format(self.uri)) logger.debug(f"Try to connect to {self.uri}")
# Try to connect to the URI # Try to connect to the URI
transport = GlancesClientTransport() transport = GlancesClientTransport()
@ -61,7 +59,7 @@ class GlancesClient(object):
try: try:
self.client = ServerProxy(self.uri, transport=transport) self.client = ServerProxy(self.uri, transport=transport)
except Exception as e: except Exception as e:
self.log_and_exit("Client couldn't create socket {}: {}".format(self.uri, e)) self.log_and_exit(f"Client couldn't create socket {self.uri}: {e}")
@property @property
def quiet(self): def quiet(self):
@ -94,10 +92,10 @@ class GlancesClient(object):
client_version = None client_version = None
try: try:
client_version = self.client.init() client_version = self.client.init()
except socket.error as err: except OSError as err:
# Fallback to SNMP # Fallback to SNMP
self.client_mode = 'snmp' self.client_mode = 'snmp'
logger.error("Connection to Glances server failed ({} {})".format(err.errno, err.strerror)) logger.error(f"Connection to Glances server failed ({err.errno} {err.strerror})")
fall_back_msg = 'No Glances server found. Trying fallback to SNMP...' fall_back_msg = 'No Glances server found. Trying fallback to SNMP...'
if not self.return_to_browser: if not self.return_to_browser:
print(fall_back_msg) print(fall_back_msg)
@ -105,11 +103,11 @@ class GlancesClient(object):
logger.info(fall_back_msg) logger.info(fall_back_msg)
except ProtocolError as err: except ProtocolError as err:
# Other errors # Other errors
msg = "Connection to server {} failed".format(self.uri) msg = f"Connection to server {self.uri} failed"
if err.errcode == 401: if err.errcode == 401:
msg += " (Bad username/password)" msg += " (Bad username/password)"
else: else:
msg += " ({} {})".format(err.errcode, err.errmsg) msg += f" ({err.errcode} {err.errmsg})"
self.log_and_exit(msg) self.log_and_exit(msg)
return False return False
@ -119,14 +117,11 @@ class GlancesClient(object):
# Init stats # Init stats
self.stats = GlancesStatsClient(config=self.config, args=self.args) self.stats = GlancesStatsClient(config=self.config, args=self.args)
self.stats.set_plugins(ujson.loads(self.client.getAllPlugins())) self.stats.set_plugins(ujson.loads(self.client.getAllPlugins()))
logger.debug("Client version: {} / Server version: {}".format(__version__, client_version)) logger.debug(f"Client version: {__version__} / Server version: {client_version}")
else: else:
self.log_and_exit( self.log_and_exit(
( 'Client and server not compatible: '
'Client and server not compatible: ' 'Client version: {} / Server version: {}'.format( f'Client version: {__version__} / Server version: {client_version}'
__version__, client_version
)
)
) )
return False return False
@ -186,7 +181,7 @@ class GlancesClient(object):
return self.update_snmp() return self.update_snmp()
self.end() self.end()
logger.critical("Unknown server mode: {}".format(self.client_mode)) logger.critical(f"Unknown server mode: {self.client_mode}")
sys.exit(2) sys.exit(2)
def update_glances(self): def update_glances(self):
@ -199,7 +194,7 @@ class GlancesClient(object):
# Update the stats # Update the stats
try: try:
server_stats = ujson.loads(self.client.getAll()) server_stats = ujson.loads(self.client.getAll())
except socket.error: except OSError:
# Client cannot get server stats # Client cannot get server stats
return "Disconnected" return "Disconnected"
except Fault: except Fault:
@ -242,12 +237,12 @@ class GlancesClient(object):
# Update the stats # Update the stats
counter = Counter() counter = Counter()
cs_status = self.update() cs_status = self.update()
logger.debug('Stats updated duration: {} seconds'.format(counter.get())) logger.debug(f'Stats updated duration: {counter.get()} seconds')
# Export stats using export modules # Export stats using export modules
counter_export = Counter() counter_export = Counter()
self.stats.export(self.stats) self.stats.export(self.stats)
logger.debug('Stats exported duration: {} seconds'.format(counter_export.get())) logger.debug(f'Stats exported duration: {counter_export.get()} seconds')
# Patch for issue1326 to avoid < 0 refresh # Patch for issue1326 to avoid < 0 refresh
adapted_refresh = self.refresh_time - counter.get() adapted_refresh = self.refresh_time - counter.get()

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -9,7 +8,6 @@
"""Manage the Glances client browser (list of Glances server).""" """Manage the Glances client browser (list of Glances server)."""
import socket
import threading import threading
import ujson import ujson
@ -23,7 +21,7 @@ from glances.password_list import GlancesPasswordList as GlancesPassword
from glances.static_list import GlancesStaticServer from glances.static_list import GlancesStaticServer
class GlancesClientBrowser(object): class GlancesClientBrowser:
"""This class creates and manages the TCP client browser (servers list).""" """This class creates and manages the TCP client browser (servers list)."""
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
@ -92,19 +90,19 @@ class GlancesClientBrowser(object):
try: try:
s = ServerProxy(uri, transport=t) s = ServerProxy(uri, transport=t)
except Exception as e: except Exception as e:
logger.warning("Client browser couldn't create socket ({})".format(e)) logger.warning(f"Client browser couldn't create socket ({e})")
else: else:
# Mandatory stats # Mandatory stats
try: try:
# CPU% # CPU%
cpu_percent = 100 - ujson.loads(s.getCpu())['idle'] cpu_percent = 100 - ujson.loads(s.getCpu())['idle']
server['cpu_percent'] = '{:.1f}'.format(cpu_percent) server['cpu_percent'] = f'{cpu_percent:.1f}'
# MEM% # MEM%
server['mem_percent'] = ujson.loads(s.getMem())['percent'] server['mem_percent'] = ujson.loads(s.getMem())['percent']
# OS (Human Readable name) # OS (Human Readable name)
server['hr_name'] = ujson.loads(s.getSystem())['hr_name'] server['hr_name'] = ujson.loads(s.getSystem())['hr_name']
except (socket.error, Fault, KeyError) as e: except (OSError, Fault, KeyError) as e:
logger.debug("Error while grabbing stats form server ({})".format(e)) logger.debug(f"Error while grabbing stats form server ({e})")
server['status'] = 'OFFLINE' server['status'] = 'OFFLINE'
except ProtocolError as e: except ProtocolError as e:
if e.errcode == 401: if e.errcode == 401:
@ -114,7 +112,7 @@ class GlancesClientBrowser(object):
server['status'] = 'PROTECTED' server['status'] = 'PROTECTED'
else: else:
server['status'] = 'OFFLINE' server['status'] = 'OFFLINE'
logger.debug("Cannot grab stats from server ({} {})".format(e.errcode, e.errmsg)) logger.debug(f"Cannot grab stats from server ({e.errcode} {e.errmsg})")
else: else:
# Status # Status
server['status'] = 'ONLINE' server['status'] = 'ONLINE'
@ -123,16 +121,16 @@ class GlancesClientBrowser(object):
try: try:
# LOAD # LOAD
load_min5 = ujson.loads(s.getLoad())['min5'] load_min5 = ujson.loads(s.getLoad())['min5']
server['load_min5'] = '{:.2f}'.format(load_min5) server['load_min5'] = f'{load_min5:.2f}'
except Exception as e: except Exception as e:
logger.warning("Error while grabbing stats form server ({})".format(e)) logger.warning(f"Error while grabbing stats form server ({e})")
return server return server
def __display_server(self, server): def __display_server(self, server):
"""Connect and display the given server""" """Connect and display the given server"""
# Display the Glances client for the selected server # Display the Glances client for the selected server
logger.debug("Selected server {}".format(server)) logger.debug(f"Selected server {server}")
# Connection can take time # Connection can take time
# Display a popup # Display a popup
@ -201,7 +199,7 @@ class GlancesClientBrowser(object):
# For each server in the list, grab elementary stats (CPU, LOAD, MEM, OS...) # For each server in the list, grab elementary stats (CPU, LOAD, MEM, OS...)
thread_list = {} thread_list = {}
while not self.screen.is_end: while not self.screen.is_end:
logger.debug("Iter through the following server list: {}".format(self.get_servers_list())) logger.debug(f"Iter through the following server list: {self.get_servers_list()}")
for v in self.get_servers_list(): for v in self.get_servers_list():
key = v["key"] key = v["key"]
thread = thread_list.get(key, None) thread = thread_list.get(key, None)

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -9,11 +8,11 @@
"""Manage the configuration file.""" """Manage the configuration file."""
import builtins
import multiprocessing import multiprocessing
import os import os
import re import re
import sys import sys
from io import open
from glances.globals import BSD, LINUX, MACOS, SUNOS, WINDOWS, ConfigParser, NoOptionError, NoSectionError, system_exec from glances.globals import BSD, LINUX, MACOS, SUNOS, WINDOWS, ConfigParser, NoOptionError, NoSectionError, system_exec
from glances.logger import logger from glances.logger import logger
@ -94,7 +93,7 @@ def default_config_dir():
return [path] return [path]
class Config(object): class Config:
"""This class is used to access/read config file, if it exists. """This class is used to access/read config file, if it exists.
:param config_dir: the path to search for config file :param config_dir: the path to search for config file
@ -153,15 +152,15 @@ class Config(object):
def read(self): def read(self):
"""Read the config file, if it exists. Using defaults otherwise.""" """Read the config file, if it exists. Using defaults otherwise."""
for config_file in self.config_file_paths(): for config_file in self.config_file_paths():
logger.debug('Search glances.conf file in {}'.format(config_file)) logger.debug(f'Search glances.conf file in {config_file}')
if os.path.exists(config_file): if os.path.exists(config_file):
try: try:
with open(config_file, encoding='utf-8') as f: with builtins.open(config_file, encoding='utf-8') as f:
self.parser.read_file(f) self.parser.read_file(f)
self.parser.read(f) self.parser.read(f)
logger.info("Read configuration file '{}'".format(config_file)) logger.info(f"Read configuration file '{config_file}'")
except UnicodeDecodeError as err: except UnicodeDecodeError as err:
logger.error("Can not read configuration file '{}': {}".format(config_file, err)) logger.error(f"Can not read configuration file '{config_file}': {err}")
sys.exit(1) sys.exit(1)
# Save the loaded configuration file path (issue #374) # Save the loaded configuration file path (issue #374)
self._loaded_config_file = config_file self._loaded_config_file = config_file

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -15,7 +14,7 @@ from glances.logger import logger
from glances.timer import Timer from glances.timer import Timer
class CpuPercent(object): class CpuPercent:
"""Get and store the CPU percent.""" """Get and store the CPU percent."""
def __init__(self, cached_timer_cpu=3): def __init__(self, cached_timer_cpu=3):
@ -56,7 +55,7 @@ class CpuPercent(object):
try: try:
cpu_freq = psutil.cpu_freq() cpu_freq = psutil.cpu_freq()
except Exception as e: except Exception as e:
logger.debug('Can not grab CPU information ({})'.format(e)) logger.debug(f'Can not grab CPU information ({e})')
else: else:
if hasattr(cpu_freq, 'current'): if hasattr(cpu_freq, 'current'):
self.cpu_info['cpu_hz_current'] = cpu_freq.current self.cpu_info['cpu_hz_current'] = cpu_freq.current
@ -74,7 +73,7 @@ class CpuPercent(object):
# Get the CPU name once from the /proc/cpuinfo file # Get the CPU name once from the /proc/cpuinfo file
# TODO: Multisystem... # TODO: Multisystem...
try: try:
self.cpu_info['cpu_name'] = open('/proc/cpuinfo', 'r').readlines()[4].split(':')[1].strip() self.cpu_info['cpu_name'] = open('/proc/cpuinfo').readlines()[4].split(':')[1].strip()
except (FileNotFoundError, PermissionError, IndexError, KeyError, AttributeError): except (FileNotFoundError, PermissionError, IndexError, KeyError, AttributeError):
self.cpu_info['cpu_name'] = 'CPU' self.cpu_info['cpu_name'] = 'CPU'
return self.cpu_info['cpu_name'] return self.cpu_info['cpu_name']

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -161,7 +160,7 @@ def build_global_message():
return tree[0]['msg'] return tree[0]['msg']
class GlancesEventsList(object): class GlancesEventsList:
"""This class manages events inside the Glances software. """This class manages events inside the Glances software.
GlancesEventsList is a list of GlancesEvent. GlancesEventsList is a list of GlancesEvent.
GlancesEvent is defined in the event.py file GlancesEvent is defined in the event.py file

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -18,7 +17,7 @@ from glances.logger import logger
from glances.timer import Counter from glances.timer import Counter
class GlancesExport(object): class GlancesExport:
"""Main class for Glances export IF.""" """Main class for Glances export IF."""
# List of non exportable plugins # List of non exportable plugins
@ -39,7 +38,7 @@ class GlancesExport(object):
"""Init the export class.""" """Init the export class."""
# Export name # Export name
self.export_name = self.__class__.__module__ self.export_name = self.__class__.__module__
logger.debug("Init export module %s" % self.export_name) logger.debug(f"Init export module {self.export_name}")
# Init the config & args # Init the config & args
self.config = config self.config = config
@ -63,18 +62,16 @@ class GlancesExport(object):
counter = Counter() counter = Counter()
ret = fct(*args, **kw) ret = fct(*args, **kw)
duration = counter.get() duration = counter.get()
logger.debug( class_name = args[0].__class__.__name__
"{} {} {} return {} in {} seconds".format( class_module = args[0].__class__.__module__
args[0].__class__.__name__, args[0].__class__.__module__, fct.__name__, ret, duration logger.debug(f"{class_name} {class_module} {fct.__name__} return {ret} in {duration} seconds")
)
)
return ret return ret
return wrapper return wrapper
def exit(self): def exit(self):
"""Close the export module.""" """Close the export module."""
logger.debug("Finalise export interface %s" % self.export_name) logger.debug(f"Finalise export interface {self.export_name}")
def load_conf(self, section, mandatories=['host', 'port'], options=None): def load_conf(self, section, mandatories=['host', 'port'], options=None):
"""Load the export <section> configuration in the Glances configuration file. """Load the export <section> configuration in the Glances configuration file.
@ -95,10 +92,10 @@ class GlancesExport(object):
for opt in mandatories: for opt in mandatories:
setattr(self, opt, self.config.get_value(section, opt)) setattr(self, opt, self.config.get_value(section, opt))
except NoSectionError: except NoSectionError:
logger.error("No {} configuration found".format(section)) logger.error(f"No {section} configuration found")
return False return False
except NoOptionError as e: except NoOptionError as e:
logger.error("Error in the {} configuration ({})".format(section, e)) logger.error(f"Error in the {section} configuration ({e})")
return False return False
# Load options # Load options
@ -108,8 +105,8 @@ class GlancesExport(object):
except NoOptionError: except NoOptionError:
pass pass
logger.debug("Load {} from the Glances configuration file".format(section)) logger.debug(f"Load {section} from the Glances configuration file")
logger.debug("{} parameters: {}".format(section, {opt: getattr(self, opt) for opt in mandatories + options})) logger.debug(f"{section} parameters: {({opt: getattr(self, opt) for opt in mandatories + options})}")
return True return True
@ -119,7 +116,7 @@ class GlancesExport(object):
try: try:
ret = item[item['key']] ret = item[item['key']]
except KeyError: except KeyError:
logger.error("No 'key' available in {}".format(item)) logger.error(f"No 'key' available in {item}")
if isinstance(ret, list): if isinstance(ret, list):
return ret[0] return ret[0]
return ret return ret

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -27,7 +26,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
"""Init the Cassandra export IF.""" """Init the Cassandra export IF."""
super(Export, self).__init__(config=config, args=args) super().__init__(config=config, args=args)
# Mandatory configuration keys (additional to host and port) # Mandatory configuration keys (additional to host and port)
self.keyspace = None self.keyspace = None
@ -69,53 +68,52 @@ class Export(GlancesExport):
) )
session = cluster.connect() session = cluster.connect()
except Exception as e: except Exception as e:
logger.critical("Cannot connect to Cassandra cluster '%s:%s' (%s)" % (self.host, self.port, e)) logger.critical(f"Cannot connect to Cassandra cluster '{self.host}:{self.port}' ({e})")
sys.exit(2) sys.exit(2)
# Keyspace # Keyspace
try: try:
session.set_keyspace(self.keyspace) session.set_keyspace(self.keyspace)
except InvalidRequest: except InvalidRequest:
logger.info("Create keyspace {} on the Cassandra cluster".format(self.keyspace)) logger.info(f"Create keyspace {self.keyspace} on the Cassandra cluster")
c = "CREATE KEYSPACE %s WITH replication = { 'class': 'SimpleStrategy', 'replication_factor': '%s' }" % ( c = (
self.keyspace, f"CREATE KEYSPACE {self.keyspace} WITH "
self.replication_factor, f"replication = {{ 'class': 'SimpleStrategy', 'replication_factor': '{self.replication_factor}' }}"
) )
session.execute(c) session.execute(c)
session.set_keyspace(self.keyspace) session.set_keyspace(self.keyspace)
logger.info( logger.info(
"Stats will be exported to Cassandra cluster {} ({}) in keyspace {}".format( f"Stats will be exported to Cassandra cluster {cluster.metadata.cluster_name} "
cluster.metadata.cluster_name, cluster.metadata.all_hosts(), self.keyspace f"({cluster.metadata.all_hosts()}) in keyspace {self.keyspace}"
)
) )
# Table # Table
try: try:
session.execute( session.execute(
"CREATE TABLE %s (plugin text, time timeuuid, stat map<text,float>, PRIMARY KEY (plugin, time)) \ f"CREATE TABLE {self.table} "
WITH CLUSTERING ORDER BY (time DESC)" f"(plugin text, time timeuuid, stat map<text,float>, PRIMARY KEY (plugin, time)) "
% self.table f"WITH CLUSTERING ORDER BY (time DESC)"
) )
except Exception: except Exception:
logger.debug("Cassandra table %s already exist" % self.table) logger.debug(f"Cassandra table {self.table} already exist")
return cluster, session return cluster, session
def export(self, name, columns, points): def export(self, name, columns, points):
"""Write the points to the Cassandra cluster.""" """Write the points to the Cassandra cluster."""
logger.debug("Export {} stats to Cassandra".format(name)) logger.debug(f"Export {name} stats to Cassandra")
# Remove non number stats and convert all to float (for Boolean) # Remove non number stats and convert all to float (for Boolean)
data = {k: float(v) for (k, v) in dict(zip(columns, points)).iteritems() if isinstance(v, Number)} data = {k: float(v) for (k, v) in dict(zip(columns, points)).iteritems() if isinstance(v, Number)}
# Write input to the Cassandra table # Write input to the Cassandra table
try: try:
stmt = "INSERT INTO {} (plugin, time, stat) VALUES (?, ?, ?)".format(self.table) stmt = f"INSERT INTO {self.table} (plugin, time, stat) VALUES (?, ?, ?)"
query = self.session.prepare(stmt) query = self.session.prepare(stmt)
self.session.execute(query, (name, uuid_from_time(datetime.now()), data)) self.session.execute(query, (name, uuid_from_time(datetime.now()), data))
except Exception as e: except Exception as e:
logger.error("Cannot export {} stats to Cassandra ({})".format(name, e)) logger.error(f"Cannot export {name} stats to Cassandra ({e})")
def exit(self): def exit(self):
"""Close the Cassandra export module.""" """Close the Cassandra export module."""
@ -123,4 +121,4 @@ class Export(GlancesExport):
self.session.shutdown() self.session.shutdown()
self.cluster.shutdown() self.cluster.shutdown()
# Call the father method # Call the father method
super(Export, self).exit() super().exit()

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -31,7 +30,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
"""Init the CouchDB export IF.""" """Init the CouchDB export IF."""
super(Export, self).__init__(config=config, args=args) super().__init__(config=config, args=args)
# Load the CouchDB configuration file section # Load the CouchDB configuration file section
# User and Password are mandatory with CouchDB 3.0 and higher # User and Password are mandatory with CouchDB 3.0 and higher
@ -48,15 +47,15 @@ class Export(GlancesExport):
return None return None
# @TODO: https # @TODO: https
server_uri = 'http://{}:{}@{}:{}/'.format(self.user, self.password, self.host, self.port) server_uri = f'http://{self.user}:{self.password}@{self.host}:{self.port}/'
try: try:
s = pycouchdb.Server(server_uri) s = pycouchdb.Server(server_uri)
except Exception as e: except Exception as e:
logger.critical("Cannot connect to CouchDB server (%s)" % e) logger.critical(f"Cannot connect to CouchDB server ({e})")
sys.exit(2) sys.exit(2)
else: else:
logger.info("Connected to the CouchDB server version %s" % s.info()['version']) logger.info("Connected to the CouchDB server version {}".format(s.info()['version']))
try: try:
s.database(self.db) s.database(self.db)
@ -64,15 +63,15 @@ class Export(GlancesExport):
# Database did not exist # Database did not exist
# Create it... # Create it...
s.create(self.db) s.create(self.db)
logger.info("Create CouchDB database %s" % self.db) logger.info(f"Create CouchDB database {self.db}")
else: else:
logger.info("CouchDB database %s already exist" % self.db) logger.info(f"CouchDB database {self.db} already exist")
return s.database(self.db) return s.database(self.db)
def export(self, name, columns, points): def export(self, name, columns, points):
"""Write the points to the CouchDB server.""" """Write the points to the CouchDB server."""
logger.debug("Export {} stats to CouchDB".format(name)) logger.debug(f"Export {name} stats to CouchDB")
# Create DB input # Create DB input
data = dict(zip(columns, points)) data = dict(zip(columns, points))
@ -85,4 +84,4 @@ class Export(GlancesExport):
try: try:
self.client.save(data) self.client.save(data)
except Exception as e: except Exception as e:
logger.error("Cannot export {} stats to CouchDB ({})".format(name, e)) logger.error(f"Cannot export {name} stats to CouchDB ({e})")

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -23,7 +22,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
"""Init the CSV export IF.""" """Init the CSV export IF."""
super(Export, self).__init__(config=config, args=args) super().__init__(config=config, args=args)
# CSV file name # CSV file name
self.csv_filename = args.export_csv_file self.csv_filename = args.export_csv_file
@ -42,8 +41,8 @@ class Export(GlancesExport):
try: try:
self.csv_file = open_csv_file(self.csv_filename, 'r') self.csv_file = open_csv_file(self.csv_filename, 'r')
reader = csv.reader(self.csv_file) reader = csv.reader(self.csv_file)
except IOError as e: except OSError as e:
logger.critical("Cannot open existing CSV file: {}".format(e)) logger.critical(f"Cannot open existing CSV file: {e}")
sys.exit(2) sys.exit(2)
self.old_header = next(reader, None) self.old_header = next(reader, None)
self.csv_file.close() self.csv_file.close()
@ -51,11 +50,11 @@ class Export(GlancesExport):
try: try:
self.csv_file = open_csv_file(self.csv_filename, file_mode) self.csv_file = open_csv_file(self.csv_filename, file_mode)
self.writer = csv.writer(self.csv_file) self.writer = csv.writer(self.csv_file)
except IOError as e: except OSError as e:
logger.critical("Cannot create the CSV file: {}".format(e)) logger.critical(f"Cannot create the CSV file: {e}")
sys.exit(2) sys.exit(2)
logger.info("Stats exported to CSV file: {}".format(self.csv_filename)) logger.info(f"Stats exported to CSV file: {self.csv_filename}")
self.export_enable = True self.export_enable = True
@ -63,7 +62,7 @@ class Export(GlancesExport):
def exit(self): def exit(self):
"""Close the CSV file.""" """Close the CSV file."""
logger.debug("Finalise export interface %s" % self.export_name) logger.debug(f"Finalise export interface {self.export_name}")
self.csv_file.close() self.csv_file.close()
def update(self, stats): def update(self, stats):
@ -95,8 +94,8 @@ class Export(GlancesExport):
if self.old_header != csv_header and self.old_header is not None: if self.old_header != csv_header and self.old_header is not None:
# Header are different, log an error and do not write data # Header are different, log an error and do not write data
logger.error("Cannot append data to existing CSV file. Headers are different.") logger.error("Cannot append data to existing CSV file. Headers are different.")
logger.debug("Old header: {}".format(self.old_header)) logger.debug(f"Old header: {self.old_header}")
logger.debug("New header: {}".format(csv_header)) logger.debug(f"New header: {csv_header}")
else: else:
# Header are equals, ready to write data # Header are equals, ready to write data
self.old_header = None self.old_header = None

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -23,7 +22,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
"""Init the ES export IF.""" """Init the ES export IF."""
super(Export, self).__init__(config=config, args=args) super().__init__(config=config, args=args)
# Mandatory configuration keys (additional to host and port) # Mandatory configuration keys (additional to host and port)
self.index = None self.index = None
@ -44,24 +43,22 @@ class Export(GlancesExport):
return None return None
try: try:
es = Elasticsearch(hosts=['{}://{}:{}'.format(self.scheme, self.host, self.port)]) es = Elasticsearch(hosts=[f'{self.scheme}://{self.host}:{self.port}'])
except Exception as e: except Exception as e:
logger.critical( logger.critical(f"Cannot connect to ElasticSearch server {self.scheme}://{self.host}:{self.port} ({e})")
"Cannot connect to ElasticSearch server %s://%s:%s (%s)" % (self.scheme, self.host, self.port, e)
)
sys.exit(2) sys.exit(2)
if not es.ping(): if not es.ping():
logger.critical("Cannot ping the ElasticSearch server %s://%s:%s" % (self.scheme, self.host, self.port)) logger.critical(f"Cannot ping the ElasticSearch server {self.scheme}://{self.host}:{self.port}")
sys.exit(2) sys.exit(2)
else: else:
logger.info("Connected to the ElasticSearch server %s://%s:%s" % (self.scheme, self.host, self.port)) logger.info(f"Connected to the ElasticSearch server {self.scheme}://{self.host}:{self.port}")
return es return es
def export(self, name, columns, points): def export(self, name, columns, points):
"""Write the points to the ES server.""" """Write the points to the ES server."""
logger.debug("Export {} stats to ElasticSearch".format(name)) logger.debug(f"Export {name} stats to ElasticSearch")
# Generate index name with the index field + current day # Generate index name with the index field + current day
index = '{}-{}'.format(self.index, datetime.utcnow().strftime("%Y.%m.%d")) index = '{}-{}'.format(self.index, datetime.utcnow().strftime("%Y.%m.%d"))
@ -72,17 +69,17 @@ class Export(GlancesExport):
dt_now = datetime.utcnow().isoformat('T') dt_now = datetime.utcnow().isoformat('T')
action = { action = {
"_index": index, "_index": index,
"_id": '{}.{}'.format(name, dt_now), "_id": f'{name}.{dt_now}',
"_type": 'glances-{}'.format(name), "_type": f'glances-{name}',
"_source": {"plugin": name, "timestamp": dt_now}, "_source": {"plugin": name, "timestamp": dt_now},
} }
action['_source'].update(zip(columns, [str(p) for p in points])) action['_source'].update(zip(columns, [str(p) for p in points]))
actions.append(action) actions.append(action)
logger.debug("Exporting the following object to elasticsearch: {}".format(action)) logger.debug(f"Exporting the following object to elasticsearch: {action}")
# Write input to the ES index # Write input to the ES index
try: try:
helpers.bulk(self.client, actions) helpers.bulk(self.client, actions)
except Exception as e: except Exception as e:
logger.error("Cannot export {} stats to ElasticSearch ({})".format(name, e)) logger.error(f"Cannot export {name} stats to ElasticSearch ({e})")

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -28,7 +27,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
"""Init the export IF.""" """Init the export IF."""
super(Export, self).__init__(config=config, args=args) super().__init__(config=config, args=args)
# Load the Graph configuration file section (is exists) # Load the Graph configuration file section (is exists)
self.export_enable = self.load_conf('graph', options=['path', 'generate_every', 'width', 'height', 'style']) self.export_enable = self.load_conf('graph', options=['path', 'generate_every', 'width', 'height', 'style'])
@ -45,19 +44,19 @@ class Export(GlancesExport):
os.makedirs(self.path) os.makedirs(self.path)
except OSError as e: except OSError as e:
if e.errno != errno.EEXIST: if e.errno != errno.EEXIST:
logger.critical("Cannot create the Graph output folder {} ({})".format(self.path, e)) logger.critical(f"Cannot create the Graph output folder {self.path} ({e})")
sys.exit(2) sys.exit(2)
# Check if output folder is writeable # Check if output folder is writeable
try: try:
tempfile.TemporaryFile(dir=self.path) tempfile.TemporaryFile(dir=self.path)
except OSError: except OSError:
logger.critical("Graph output folder {} is not writeable".format(self.path)) logger.critical(f"Graph output folder {self.path} is not writeable")
sys.exit(2) sys.exit(2)
logger.info("Graphs will be created in the {} folder".format(self.path)) logger.info(f"Graphs will be created in the {self.path} folder")
if self.generate_every != 0: if self.generate_every != 0:
logger.info("Graphs will be created automatically every {} seconds".format(self.generate_every)) logger.info(f"Graphs will be created automatically every {self.generate_every} seconds")
logger.info("or when 'g' key is pressed (only through the CLI interface)") logger.info("or when 'g' key is pressed (only through the CLI interface)")
# Start the timer # Start the timer
self._timer = Timer(self.generate_every) self._timer = Timer(self.generate_every)
@ -67,7 +66,7 @@ class Export(GlancesExport):
def exit(self): def exit(self):
"""Close the files.""" """Close the files."""
logger.debug("Finalise export interface %s" % self.export_name) logger.debug(f"Finalise export interface {self.export_name}")
def update(self, stats): def update(self, stats):
"""Generate Graph file in the output folder.""" """Generate Graph file in the output folder."""
@ -85,7 +84,7 @@ class Export(GlancesExport):
if plugin_name in self.plugins_to_export(stats): if plugin_name in self.plugins_to_export(stats):
self.export(plugin_name, plugin.get_export_history()) self.export(plugin_name, plugin.get_export_history())
logger.info("Graphs created in {}".format(self.path)) logger.info(f"Graphs created in {self.path}")
self.args.generate_graph = False self.args.generate_graph = False
def export(self, title, data): def export(self, title, data):

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -23,7 +22,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
"""Init the Graphite export IF.""" """Init the Graphite export IF."""
super(Export, self).__init__(config=config, args=args) super().__init__(config=config, args=args)
# Mandatory configuration keys (additional to host and port) # Mandatory configuration keys (additional to host and port)
# N/A # N/A
@ -74,25 +73,25 @@ class Export(GlancesExport):
debug=self.debug, debug=self.debug,
) )
except Exception as e: except Exception as e:
logger.error("Can not write data to Graphite server: {}:{} ({})".format(self.host, self.port, e)) logger.error(f"Can not write data to Graphite server: {self.host}:{self.port} ({e})")
client = None client = None
else: else:
logger.info("Stats will be exported to Graphite server: {}:{}".format(self.host, self.port)) logger.info(f"Stats will be exported to Graphite server: {self.host}:{self.port}")
return client return client
def export(self, name, columns, points): def export(self, name, columns, points):
"""Export the stats to the Graphite server.""" """Export the stats to the Graphite server."""
if self.client is None: if self.client is None:
return False return False
before_filtering_dict = dict(zip([normalize('{}.{}'.format(name, i)) for i in columns], points)) before_filtering_dict = dict(zip([normalize(f'{name}.{i}') for i in columns], points))
after_filtering_dict = dict(filter(lambda i: isinstance(i[1], Number), before_filtering_dict.items())) after_filtering_dict = dict(filter(lambda i: isinstance(i[1], Number), before_filtering_dict.items()))
try: try:
self.client.send_dict(after_filtering_dict) self.client.send_dict(after_filtering_dict)
except Exception as e: except Exception as e:
logger.error("Can not export stats to Graphite (%s)" % e) logger.error(f"Can not export stats to Graphite ({e})")
return False return False
else: else:
logger.debug("Export {} stats to Graphite".format(name)) logger.debug(f"Export {name} stats to Graphite")
return True return True

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -26,7 +25,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
"""Init the InfluxDB export IF.""" """Init the InfluxDB export IF."""
super(Export, self).__init__(config=config, args=args) super().__init__(config=config, args=args)
# Mandatory configuration keys (additional to host and port) # Mandatory configuration keys (additional to host and port)
self.user = None self.user = None
@ -75,13 +74,13 @@ class Export(GlancesExport):
) )
get_all_db = [i['name'] for i in db.get_list_database()] get_all_db = [i['name'] for i in db.get_list_database()]
except InfluxDBClientError as e: except InfluxDBClientError as e:
logger.critical("Cannot connect to InfluxDB database '%s' (%s)" % (self.db, e)) logger.critical(f"Cannot connect to InfluxDB database '{self.db}' ({e})")
sys.exit(2) sys.exit(2)
if self.db in get_all_db: if self.db in get_all_db:
logger.info("Stats will be exported to InfluxDB server: {}".format(db._baseurl)) logger.info(f"Stats will be exported to InfluxDB server: {db._baseurl}")
else: else:
logger.critical("InfluxDB database '%s' did not exist. Please create it" % self.db) logger.critical(f"InfluxDB database '{self.db}' did not exist. Please create it")
sys.exit(2) sys.exit(2)
return db return db
@ -106,9 +105,7 @@ class Export(GlancesExport):
# Manage field # Manage field
if measurement is not None: if measurement is not None:
fields = { fields = {
k.replace('{}.'.format(measurement), ''): data_dict[k] k.replace(f'{measurement}.', ''): data_dict[k] for k in data_dict if k.startswith(f'{measurement}.')
for k in data_dict
if k.startswith('{}.'.format(measurement))
} }
else: else:
fields = data_dict fields = data_dict
@ -155,12 +152,12 @@ class Export(GlancesExport):
name = self.prefix + '.' + name name = self.prefix + '.' + name
# Write input to the InfluxDB database # Write input to the InfluxDB database
if len(points) == 0: if len(points) == 0:
logger.debug("Cannot export empty {} stats to InfluxDB".format(name)) logger.debug(f"Cannot export empty {name} stats to InfluxDB")
else: else:
try: try:
self.client.write_points(self._normalize(name, columns, points), time_precision="s") self.client.write_points(self._normalize(name, columns, points), time_precision="s")
except Exception as e: except Exception as e:
# Log level set to debug instead of error (see: issue #1561) # Log level set to debug instead of error (see: issue #1561)
logger.debug("Cannot export {} stats to InfluxDB ({})".format(name, e)) logger.debug(f"Cannot export {name} stats to InfluxDB ({e})")
else: else:
logger.debug("Export {} stats to InfluxDB".format(name)) logger.debug(f"Export {name} stats to InfluxDB")

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -25,7 +24,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
"""Init the InfluxDB export IF.""" """Init the InfluxDB export IF."""
super(Export, self).__init__(config=config, args=args) super().__init__(config=config, args=args)
# Mandatory configuration keys (additional to host and port) # Mandatory configuration keys (additional to host and port)
self.org = None self.org = None
@ -58,7 +57,7 @@ class Export(GlancesExport):
self.interval = 0 self.interval = 0
# and should be set to the Glances refresh time if the value is 0 # and should be set to the Glances refresh time if the value is 0
self.interval = self.interval if self.interval > 0 else self.args.time self.interval = self.interval if self.interval > 0 else self.args.time
logger.debug("InfluxDB export interval is set to {} seconds".format(self.interval)) logger.debug(f"InfluxDB export interval is set to {self.interval} seconds")
# The hostname is always add as a tag # The hostname is always add as a tag
self.hostname = node().split('.')[0] self.hostname = node().split('.')[0]
@ -71,17 +70,15 @@ class Export(GlancesExport):
if not self.export_enable: if not self.export_enable:
return None return None
url = '{}://{}:{}'.format(self.protocol, self.host, self.port) url = f'{self.protocol}://{self.host}:{self.port}'
try: try:
# See docs: https://influxdb-client.readthedocs.io/en/stable/api.html#influxdbclient # See docs: https://influxdb-client.readthedocs.io/en/stable/api.html#influxdbclient
client = InfluxDBClient(url=url, enable_gzip=False, verify_ssl=False, org=self.org, token=self.token) client = InfluxDBClient(url=url, enable_gzip=False, verify_ssl=False, org=self.org, token=self.token)
except Exception as e: except Exception as e:
logger.critical("Cannot connect to InfluxDB server '%s' (%s)" % (url, e)) logger.critical(f"Cannot connect to InfluxDB server '{url}' ({e})")
sys.exit(2) sys.exit(2)
else: else:
logger.info( logger.info(f"Connected to InfluxDB server version {client.health().version} ({client.health().message})")
"Connected to InfluxDB server version {} ({})".format(client.health().version, client.health().message)
)
# Create the write client # Create the write client
return client.write_api( return client.write_api(
@ -116,9 +113,7 @@ class Export(GlancesExport):
# Manage field # Manage field
if measurement is not None: if measurement is not None:
fields = { fields = {
k.replace('{}.'.format(measurement), ''): data_dict[k] k.replace(f'{measurement}.', ''): data_dict[k] for k in data_dict if k.startswith(f'{measurement}.')
for k in data_dict
if k.startswith('{}.'.format(measurement))
} }
else: else:
fields = data_dict fields = data_dict
@ -165,12 +160,12 @@ class Export(GlancesExport):
name = self.prefix + '.' + name name = self.prefix + '.' + name
# Write input to the InfluxDB database # Write input to the InfluxDB database
if len(points) == 0: if len(points) == 0:
logger.debug("Cannot export empty {} stats to InfluxDB".format(name)) logger.debug(f"Cannot export empty {name} stats to InfluxDB")
else: else:
try: try:
self.client.write(self.bucket, self.org, self._normalize(name, columns, points), time_precision="s") self.client.write(self.bucket, self.org, self._normalize(name, columns, points), time_precision="s")
except Exception as e: except Exception as e:
# Log level set to debug instead of error (see: issue #1561) # Log level set to debug instead of error (see: issue #1561)
logger.debug("Cannot export {} stats to InfluxDB ({})".format(name, e)) logger.debug(f"Cannot export {name} stats to InfluxDB ({e})")
else: else:
logger.debug("Export {} stats to InfluxDB".format(name)) logger.debug(f"Export {name} stats to InfluxDB")

View File

@ -12,7 +12,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
"""Init the JSON export IF.""" """Init the JSON export IF."""
super(Export, self).__init__(config=config, args=args) super().__init__(config=config, args=args)
# JSON file name # JSON file name
self.json_filename = args.export_json_file self.json_filename = args.export_json_file
@ -21,11 +21,11 @@ class Export(GlancesExport):
try: try:
self.json_file = open(self.json_filename, 'w') self.json_file = open(self.json_filename, 'w')
self.json_file.close() self.json_file.close()
except IOError as e: except OSError as e:
logger.critical("Cannot create the JSON file: {}".format(e)) logger.critical(f"Cannot create the JSON file: {e}")
sys.exit(2) sys.exit(2)
logger.info("Exporting stats to file: {}".format(self.json_filename)) logger.info(f"Exporting stats to file: {self.json_filename}")
self.export_enable = True self.export_enable = True
@ -34,7 +34,7 @@ class Export(GlancesExport):
def exit(self): def exit(self):
"""Close the JSON file.""" """Close the JSON file."""
logger.debug("Finalise export interface %s" % self.export_name) logger.debug(f"Finalise export interface {self.export_name}")
self.json_file.close() self.json_file.close()
def export(self, name, columns, points): def export(self, name, columns, points):
@ -44,11 +44,11 @@ class Export(GlancesExport):
if name == self.last_exported_list()[0] and self.buffer != {}: if name == self.last_exported_list()[0] and self.buffer != {}:
# One whole loop has been completed # One whole loop has been completed
# Flush stats to file # Flush stats to file
logger.debug("Exporting stats ({}) to JSON file ({})".format(listkeys(self.buffer), self.json_filename)) logger.debug(f"Exporting stats ({listkeys(self.buffer)}) to JSON file ({self.json_filename})")
# Export stats to JSON file # Export stats to JSON file
with open(self.json_filename, "w") as self.json_file: with open(self.json_filename, "w") as self.json_file:
self.json_file.write("{}\n".format(json_dumps(self.buffer))) self.json_file.write(f"{json_dumps(self.buffer)}\n")
# Reset buffer # Reset buffer
self.buffer = {} self.buffer = {}

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -23,7 +22,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
"""Init the Kafka export IF.""" """Init the Kafka export IF."""
super(Export, self).__init__(config=config, args=args) super().__init__(config=config, args=args)
# Mandatory configuration keys (additional to host and port) # Mandatory configuration keys (additional to host and port)
self.topic = None self.topic = None
@ -48,7 +47,7 @@ class Export(GlancesExport):
return None return None
# Build the server URI with host and port # Build the server URI with host and port
server_uri = '{}:{}'.format(self.host, self.port) server_uri = f'{self.host}:{self.port}'
try: try:
s = KafkaProducer( s = KafkaProducer(
@ -57,16 +56,16 @@ class Export(GlancesExport):
compression_type=self.compression, compression_type=self.compression,
) )
except Exception as e: except Exception as e:
logger.critical("Cannot connect to Kafka server %s (%s)" % (server_uri, e)) logger.critical(f"Cannot connect to Kafka server {server_uri} ({e})")
sys.exit(2) sys.exit(2)
else: else:
logger.info("Connected to the Kafka server %s" % server_uri) logger.info(f"Connected to the Kafka server {server_uri}")
return s return s
def export(self, name, columns, points): def export(self, name, columns, points):
"""Write the points to the kafka server.""" """Write the points to the kafka server."""
logger.debug("Export {} stats to Kafka".format(name)) logger.debug(f"Export {name} stats to Kafka")
# Create DB input # Create DB input
data = dict(zip(columns, points)) data = dict(zip(columns, points))
@ -84,7 +83,7 @@ class Export(GlancesExport):
value=data, value=data,
) )
except Exception as e: except Exception as e:
logger.error("Cannot export {} stats to Kafka ({})".format(name, e)) logger.error(f"Cannot export {name} stats to Kafka ({e})")
def exit(self): def exit(self):
"""Close the Kafka export module.""" """Close the Kafka export module."""
@ -92,4 +91,4 @@ class Export(GlancesExport):
self.client.flush() self.client.flush()
self.client.close() self.client.close()
# Call the father method # Call the father method
super(Export, self).exit() super().exit()

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -23,7 +22,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
"""Init the MongoDB export IF.""" """Init the MongoDB export IF."""
super(Export, self).__init__(config=config, args=args) super().__init__(config=config, args=args)
# Mandatory configuration keys (additional to host and port) # Mandatory configuration keys (additional to host and port)
self.db = None self.db = None
@ -45,13 +44,13 @@ class Export(GlancesExport):
if not self.export_enable: if not self.export_enable:
return None return None
server_uri = 'mongodb://%s:%s@%s:%s' % (quote_plus(self.user), quote_plus(self.password), self.host, self.port) server_uri = f'mongodb://{quote_plus(self.user)}:{quote_plus(self.password)}@{self.host}:{self.port}'
try: try:
client = pymongo.MongoClient(server_uri) client = pymongo.MongoClient(server_uri)
client.admin.command('ping') client.admin.command('ping')
except Exception as e: except Exception as e:
logger.critical("Cannot connect to MongoDB server %s:%s (%s)" % (self.host, self.port, e)) logger.critical(f"Cannot connect to MongoDB server {self.host}:{self.port} ({e})")
sys.exit(2) sys.exit(2)
else: else:
logger.info("Connected to the MongoDB server") logger.info("Connected to the MongoDB server")
@ -64,7 +63,7 @@ class Export(GlancesExport):
def export(self, name, columns, points): def export(self, name, columns, points):
"""Write the points to the MongoDB server.""" """Write the points to the MongoDB server."""
logger.debug("Export {} stats to MongoDB".format(name)) logger.debug(f"Export {name} stats to MongoDB")
# Create DB input # Create DB input
data = dict(zip(columns, points)) data = dict(zip(columns, points))
@ -73,4 +72,4 @@ class Export(GlancesExport):
try: try:
self.database()[name].insert_one(data) self.database()[name].insert_one(data)
except Exception as e: except Exception as e:
logger.error("Cannot export {} stats to MongoDB ({})".format(name, e)) logger.error(f"Cannot export {name} stats to MongoDB ({e})")

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -27,7 +26,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
"""Init the MQTT export IF.""" """Init the MQTT export IF."""
super(Export, self).__init__(config=config, args=args) super().__init__(config=config, args=args)
# Mandatory configuration keys (additional to host and port) # Mandatory configuration keys (additional to host and port)
self.user = None self.user = None
@ -87,7 +86,7 @@ class Export(GlancesExport):
client.loop_start() client.loop_start()
return client return client
except Exception as e: except Exception as e:
logger.critical("Connection to MQTT server %s:%s failed with error: %s " % (self.host, self.port, e)) logger.critical(f"Connection to MQTT server {self.host}:{self.port} failed with error: {e} ")
return None return None
def export(self, name, columns, points): def export(self, name, columns, points):
@ -109,7 +108,7 @@ class Export(GlancesExport):
self.client.publish(topic, value) self.client.publish(topic, value)
except Exception as e: except Exception as e:
logger.error("Can not export stats to MQTT server (%s)" % e) logger.error(f"Can not export stats to MQTT server ({e})")
elif self.topic_structure == 'per-plugin': elif self.topic_structure == 'per-plugin':
try: try:
topic = '/'.join([self.topic, self.devicename, name]) topic = '/'.join([self.topic, self.devicename, name])
@ -133,4 +132,4 @@ class Export(GlancesExport):
json_value = json_dumps(output_value) json_value = json_dumps(output_value)
self.client.publish(topic, json_value) self.client.publish(topic, json_value)
except Exception as e: except Exception as e:
logger.error("Can not export stats to MQTT server (%s)" % e) logger.error(f"Can not export stats to MQTT server ({e})")

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -23,7 +22,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
"""Init the OpenTSDB export IF.""" """Init the OpenTSDB export IF."""
super(Export, self).__init__(config=config, args=args) super().__init__(config=config, args=args)
# Mandatory configuration keys (additional to host and port) # Mandatory configuration keys (additional to host and port)
# N/A # N/A
@ -52,7 +51,7 @@ class Export(GlancesExport):
try: try:
db = potsdb.Client(self.host, port=int(self.port), check_host=True) db = potsdb.Client(self.host, port=int(self.port), check_host=True)
except Exception as e: except Exception as e:
logger.critical("Cannot connect to OpenTSDB server %s:%s (%s)" % (self.host, self.port, e)) logger.critical(f"Cannot connect to OpenTSDB server {self.host}:{self.port} ({e})")
sys.exit(2) sys.exit(2)
return db return db
@ -62,18 +61,18 @@ class Export(GlancesExport):
for i in range(len(columns)): for i in range(len(columns)):
if not isinstance(points[i], Number): if not isinstance(points[i], Number):
continue continue
stat_name = '{}.{}.{}'.format(self.prefix, name, columns[i]) stat_name = f'{self.prefix}.{name}.{columns[i]}'
stat_value = points[i] stat_value = points[i]
tags = self.parse_tags(self.tags) tags = self.parse_tags(self.tags)
try: try:
self.client.send(stat_name, stat_value, **tags) self.client.send(stat_name, stat_value, **tags)
except Exception as e: except Exception as e:
logger.error("Can not export stats %s to OpenTSDB (%s)" % (name, e)) logger.error(f"Can not export stats {name} to OpenTSDB ({e})")
logger.debug("Export {} stats to OpenTSDB".format(name)) logger.debug(f"Export {name} stats to OpenTSDB")
def exit(self): def exit(self):
"""Close the OpenTSDB export module.""" """Close the OpenTSDB export module."""
# Waits for all outstanding metrics to be sent and background thread closes # Waits for all outstanding metrics to be sent and background thread closes
self.client.wait() self.client.wait()
# Call the father method # Call the father method
super(Export, self).exit() super().exit()

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -26,7 +25,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
"""Init the Prometheus export IF.""" """Init the Prometheus export IF."""
super(Export, self).__init__(config=config, args=args) super().__init__(config=config, args=args)
# Load the Prometheus configuration file section # Load the Prometheus configuration file section
self.export_enable = self.load_conf('prometheus', mandatories=['host', 'port', 'labels'], options=['prefix']) self.export_enable = self.load_conf('prometheus', mandatories=['host', 'port', 'labels'], options=['prefix'])
@ -52,14 +51,14 @@ class Export(GlancesExport):
try: try:
start_http_server(port=int(self.port), addr=self.host) start_http_server(port=int(self.port), addr=self.host)
except Exception as e: except Exception as e:
logger.critical("Can not start Prometheus exporter on {}:{} ({})".format(self.host, self.port, e)) logger.critical(f"Can not start Prometheus exporter on {self.host}:{self.port} ({e})")
sys.exit(2) sys.exit(2)
else: else:
logger.info("Start Prometheus exporter on {}:{}".format(self.host, self.port)) logger.info(f"Start Prometheus exporter on {self.host}:{self.port}")
def export(self, name, columns, points): def export(self, name, columns, points):
"""Write the points to the Prometheus exporter using Gauge.""" """Write the points to the Prometheus exporter using Gauge."""
logger.debug("Export {} stats to Prometheus exporter".format(name)) logger.debug(f"Export {name} stats to Prometheus exporter")
# Remove non number stats and convert all to float (for Boolean) # Remove non number stats and convert all to float (for Boolean)
data = {k: float(v) for (k, v) in iteritems(dict(zip(columns, points))) if isinstance(v, Number)} data = {k: float(v) for (k, v) in iteritems(dict(zip(columns, points))) if isinstance(v, Number)}

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -26,7 +25,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
"""Init the RabbitMQ export IF.""" """Init the RabbitMQ export IF."""
super(Export, self).__init__(config=config, args=args) super().__init__(config=config, args=args)
# Mandatory configuration keys (additional to host and port) # Mandatory configuration keys (additional to host and port)
self.user = None self.user = None
@ -69,7 +68,7 @@ class Export(GlancesExport):
connection = pika.BlockingConnection(parameters) connection = pika.BlockingConnection(parameters)
return connection.channel() return connection.channel()
except Exception as e: except Exception as e:
logger.critical("Connection to rabbitMQ server %s:%s failed. %s" % (self.host, self.port, e)) logger.critical(f"Connection to rabbitMQ server {self.host}:{self.port} failed. {e}")
sys.exit(2) sys.exit(2)
def export(self, name, columns, points): def export(self, name, columns, points):
@ -84,4 +83,4 @@ class Export(GlancesExport):
try: try:
self.client.basic_publish(exchange='', routing_key=self.queue, body=data) self.client.basic_publish(exchange='', routing_key=self.queue, body=data)
except Exception as e: except Exception as e:
logger.error("Can not export stats to RabbitMQ (%s)" % e) logger.error(f"Can not export stats to RabbitMQ ({e})")

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -22,7 +21,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
"""Init the RESTful export IF.""" """Init the RESTful export IF."""
super(Export, self).__init__(config=config, args=args) super().__init__(config=config, args=args)
# Mandatory configuration keys (additional to host and port) # Mandatory configuration keys (additional to host and port)
self.protocol = None self.protocol = None
@ -45,15 +44,15 @@ class Export(GlancesExport):
if not self.export_enable: if not self.export_enable:
return None return None
# Build the RESTful URL where the stats will be posted # Build the RESTful URL where the stats will be posted
url = '{}://{}:{}{}'.format(self.protocol, self.host, self.port, self.path) url = f'{self.protocol}://{self.host}:{self.port}{self.path}'
logger.info("Stats will be exported to the RESTful endpoint {}".format(url)) logger.info(f"Stats will be exported to the RESTful endpoint {url}")
return url return url
def export(self, name, columns, points): def export(self, name, columns, points):
"""Export the stats to the Statsd server.""" """Export the stats to the Statsd server."""
if name == self.last_exported_list()[0] and self.buffer != {}: if name == self.last_exported_list()[0] and self.buffer != {}:
# One complete loop have been done # One complete loop have been done
logger.debug("Export stats ({}) to RESTful endpoint ({})".format(listkeys(self.buffer), self.client)) logger.debug(f"Export stats ({listkeys(self.buffer)}) to RESTful endpoint ({self.client})")
# Export stats # Export stats
post(self.client, json=self.buffer, allow_redirects=True) post(self.client, json=self.buffer, allow_redirects=True)
# Reset buffer # Reset buffer

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -24,7 +23,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
"""Init the Riemann export IF.""" """Init the Riemann export IF."""
super(Export, self).__init__(config=config, args=args) super().__init__(config=config, args=args)
# Mandatory configuration keys (additional to host and port) # Mandatory configuration keys (additional to host and port)
# N/A # N/A
@ -50,7 +49,7 @@ class Export(GlancesExport):
try: try:
return bernhard.Client(host=self.host, port=self.port) return bernhard.Client(host=self.host, port=self.port)
except Exception as e: except Exception as e:
logger.critical("Connection to Riemann failed : %s " % e) logger.critical(f"Connection to Riemann failed : {e} ")
return None return None
def export(self, name, columns, points): def export(self, name, columns, points):
@ -64,4 +63,4 @@ class Export(GlancesExport):
try: try:
self.client.send(data) self.client.send(data)
except Exception as e: except Exception as e:
logger.error("Cannot export stats to Riemann (%s)" % e) logger.error(f"Cannot export stats to Riemann ({e})")

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -22,7 +21,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
"""Init the Statsd export IF.""" """Init the Statsd export IF."""
super(Export, self).__init__(config=config, args=args) super().__init__(config=config, args=args)
# Mandatory configuration keys (additional to host and port) # Mandatory configuration keys (additional to host and port)
# N/A # N/A
@ -46,7 +45,7 @@ class Export(GlancesExport):
"""Init the connection to the Statsd server.""" """Init the connection to the Statsd server."""
if not self.export_enable: if not self.export_enable:
return None return None
logger.info("Stats will be exported to StatsD server: {}:{}".format(self.host, self.port)) logger.info(f"Stats will be exported to StatsD server: {self.host}:{self.port}")
return StatsClient(self.host, int(self.port), prefix=self.prefix) return StatsClient(self.host, int(self.port), prefix=self.prefix)
def export(self, name, columns, points): def export(self, name, columns, points):
@ -54,13 +53,13 @@ class Export(GlancesExport):
for i in range(len(columns)): for i in range(len(columns)):
if not isinstance(points[i], Number): if not isinstance(points[i], Number):
continue continue
stat_name = '{}.{}'.format(name, columns[i]) stat_name = f'{name}.{columns[i]}'
stat_value = points[i] stat_value = points[i]
try: try:
self.client.gauge(normalize(stat_name), stat_value) self.client.gauge(normalize(stat_name), stat_value)
except Exception as e: except Exception as e:
logger.error("Can not export stats to Statsd (%s)" % e) logger.error(f"Can not export stats to Statsd ({e})")
logger.debug("Export {} stats to Statsd".format(name)) logger.debug(f"Export {name} stats to Statsd")
def normalize(name): def normalize(name):

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -24,7 +23,7 @@ class Export(GlancesExport):
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
"""Init the ZeroMQ export IF.""" """Init the ZeroMQ export IF."""
super(Export, self).__init__(config=config, args=args) super().__init__(config=config, args=args)
# Mandatory configuration keys (additional to host and port) # Mandatory configuration keys (additional to host and port)
self.prefix = None self.prefix = None
@ -46,17 +45,17 @@ class Export(GlancesExport):
if not self.export_enable: if not self.export_enable:
return None return None
server_uri = 'tcp://{}:{}'.format(self.host, self.port) server_uri = f'tcp://{self.host}:{self.port}'
try: try:
self.context = zmq.Context() self.context = zmq.Context()
publisher = self.context.socket(zmq.PUB) publisher = self.context.socket(zmq.PUB)
publisher.bind(server_uri) publisher.bind(server_uri)
except Exception as e: except Exception as e:
logger.critical("Cannot connect to ZeroMQ server %s (%s)" % (server_uri, e)) logger.critical(f"Cannot connect to ZeroMQ server {server_uri} ({e})")
sys.exit(2) sys.exit(2)
else: else:
logger.info("Connected to the ZeroMQ server %s" % server_uri) logger.info(f"Connected to the ZeroMQ server {server_uri}")
return publisher return publisher
@ -69,7 +68,7 @@ class Export(GlancesExport):
def export(self, name, columns, points): def export(self, name, columns, points):
"""Write the points to the ZeroMQ server.""" """Write the points to the ZeroMQ server."""
logger.debug("Export {} stats to ZeroMQ".format(name)) logger.debug(f"Export {name} stats to ZeroMQ")
# Create DB input # Create DB input
data = dict(zip(columns, points)) data = dict(zip(columns, points))
@ -89,6 +88,6 @@ class Export(GlancesExport):
try: try:
self.client.send_multipart(message) self.client.send_multipart(message)
except Exception as e: except Exception as e:
logger.error("Cannot export {} stats to ZeroMQ ({})".format(name, e)) logger.error(f"Cannot export {name} stats to ZeroMQ ({e})")
return True return True

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -12,7 +11,7 @@ import re
from glances.logger import logger from glances.logger import logger
class GlancesFilterList(object): class GlancesFilterList:
"""Manage a lis of GlancesFilter objects """Manage a lis of GlancesFilter objects
>>> fl = GlancesFilterList() >>> fl = GlancesFilterList()
@ -55,7 +54,7 @@ class GlancesFilterList(object):
return False return False
class GlancesFilter(object): class GlancesFilter:
"""Allow Glances to filter processes """Allow Glances to filter processes
>>> f = GlancesFilter() >>> f = GlancesFilter()
@ -127,9 +126,9 @@ class GlancesFilter(object):
# Compute the regular expression # Compute the regular expression
try: try:
self._filter_re = re.compile(self.filter) self._filter_re = re.compile(self.filter)
logger.debug("Filter regex compilation OK: {}".format(self.filter)) logger.debug(f"Filter regex compilation OK: {self.filter}")
except Exception as e: except Exception as e:
logger.error("Cannot compile filter regex: {} ({})".format(self.filter, e)) logger.error(f"Cannot compile filter regex: {self.filter} ({e})")
self._filter = None self._filter = None
self._filter_re = None self._filter_re = None
self._filter_key = None self._filter_key = None

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -9,14 +8,12 @@
"""Manage the folder list.""" """Manage the folder list."""
from __future__ import unicode_literals
from glances.globals import folder_size, nativestr from glances.globals import folder_size, nativestr
from glances.logger import logger from glances.logger import logger
from glances.timer import Timer from glances.timer import Timer
class FolderList(object): class FolderList:
"""This class describes the optional monitored folder list. """This class describes the optional monitored folder list.
The folder list is a list of 'important' folder to monitor. The folder list is a list of 'important' folder to monitor.

View File

@ -1,5 +1,4 @@
# ruff: noqa: F401 # ruff: noqa: F401
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -145,7 +144,7 @@ def system_exec(command):
try: try:
res = subprocess.run(command.split(' '), stdout=subprocess.PIPE).stdout.decode('utf-8') res = subprocess.run(command.split(' '), stdout=subprocess.PIPE).stdout.decode('utf-8')
except Exception as e: except Exception as e:
res = 'ERROR: {}'.format(e) res = f'ERROR: {e}'
return res.rstrip() return res.rstrip()
@ -202,7 +201,7 @@ def is_admin():
try: try:
return ctypes.windll.shell32.IsUserAnAdmin() return ctypes.windll.shell32.IsUserAnAdmin()
except Exception as e: except Exception as e:
print("Admin check failed with error: %s" % e) print(f"Admin check failed with error: {e}")
traceback.print_exc() traceback.print_exc()
return False return False
else: else:
@ -299,7 +298,7 @@ def urlopen_auth(url, username, password):
return urlopen( return urlopen(
Request( Request(
url, url,
headers={'Authorization': 'Basic ' + base64.b64encode(('%s:%s' % (username, password)).encode()).decode()}, headers={'Authorization': 'Basic ' + base64.b64encode((f'{username}:{password}').encode()).decode()},
) )
) )

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -12,7 +11,7 @@
from glances.attribute import GlancesAttribute from glances.attribute import GlancesAttribute
class GlancesHistory(object): class GlancesHistory:
"""This class manage a dict of GlancesAttribute """This class manage a dict of GlancesAttribute
- key: stats name - key: stats name
- value: GlancesAttribute""" - value: GlancesAttribute"""

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -36,7 +35,7 @@ elif os.path.isdir(_XDG_CACHE_HOME) and os.access(_XDG_CACHE_HOME, os.W_OK):
safe_makedirs(os.path.join(_XDG_CACHE_HOME, 'glances')) safe_makedirs(os.path.join(_XDG_CACHE_HOME, 'glances'))
LOG_FILENAME = os.path.join(_XDG_CACHE_HOME, 'glances', 'glances.log') LOG_FILENAME = os.path.join(_XDG_CACHE_HOME, 'glances', 'glances.log')
else: else:
LOG_FILENAME = os.path.join(tempfile.gettempdir(), 'glances-{}.log'.format(getpass.getuser())) LOG_FILENAME = os.path.join(tempfile.gettempdir(), f'glances-{getpass.getuser()}.log')
# Define the logging configuration # Define the logging configuration
LOGGING_CFG = { LOGGING_CFG = {
@ -88,7 +87,7 @@ def glances_logger(env_key='LOG_CFG'):
user_file = os.getenv(env_key, None) user_file = os.getenv(env_key, None)
if user_file and os.path.exists(user_file): if user_file and os.path.exists(user_file):
# A user file as been defined. Use it... # A user file as been defined. Use it...
with open(user_file, 'rt') as f: with open(user_file) as f:
config = json.load(f) config = json.load(f)
# Load the configuration # Load the configuration

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -22,7 +21,7 @@ from glances.logger import LOG_FILENAME, logger
from glances.processes import sort_processes_key_list from glances.processes import sort_processes_key_list
class GlancesMain(object): class GlancesMain:
"""Main class to manage Glances instance.""" """Main class to manage Glances instance."""
# Default stats' minimum refresh time is 2 seconds # Default stats' minimum refresh time is 2 seconds
@ -101,10 +100,10 @@ Examples of use:
def version_msg(self): def version_msg(self):
"""Return the version message.""" """Return the version message."""
version = 'Glances version:\t{}\n'.format(__version__) version = f'Glances version:\t{__version__}\n'
version += 'Glances API version:\t{}\n'.format(__apiversion__) version += f'Glances API version:\t{__apiversion__}\n'
version += 'PsUtil version:\t\t{}\n'.format(psutil_version) version += f'PsUtil version:\t\t{psutil_version}\n'
version += 'Log file:\t\t{}\n'.format(LOG_FILENAME) version += f'Log file:\t\t{LOG_FILENAME}\n'
return version return version
def init_args(self): def init_args(self):
@ -334,7 +333,7 @@ Examples of use:
default=None, default=None,
type=int, type=int,
dest='port', dest='port',
help='define the client/server TCP port [default: {}]'.format(self.server_port), help=f'define the client/server TCP port [default: {self.server_port}]',
) )
parser.add_argument( parser.add_argument(
'-B', '-B',
@ -374,7 +373,7 @@ Examples of use:
default=self.DEFAULT_REFRESH_TIME, default=self.DEFAULT_REFRESH_TIME,
type=float, type=float,
dest='time', dest='time',
help='set minimum refresh rate in seconds [default: {} sec]'.format(self.DEFAULT_REFRESH_TIME), help=f'set minimum refresh rate in seconds [default: {self.DEFAULT_REFRESH_TIME} sec]',
) )
parser.add_argument( parser.add_argument(
'-w', '-w',
@ -389,7 +388,7 @@ Examples of use:
default=self.cached_time, default=self.cached_time,
type=int, type=int,
dest='cached_time', dest='cached_time',
help='set the server cache time [default: {} sec]'.format(self.cached_time), help=f'set the server cache time [default: {self.cached_time} sec]',
) )
parser.add_argument( parser.add_argument(
'--stop-after', '--stop-after',
@ -577,7 +576,7 @@ Examples of use:
if args.time == self.DEFAULT_REFRESH_TIME: if args.time == self.DEFAULT_REFRESH_TIME:
args.time = global_refresh args.time = global_refresh
logger.debug('Global refresh rate is set to {} seconds'.format(args.time)) logger.debug(f'Global refresh rate is set to {args.time} seconds')
def init_plugins(self, args): def init_plugins(self, args):
"""Init Glances plugins""" """Init Glances plugins"""
@ -585,7 +584,7 @@ Examples of use:
for s in self.config.sections(): for s in self.config.sections():
if self.config.has_section(s) and (self.config.get_bool_value(s, 'disable', False)): if self.config.has_section(s) and (self.config.get_bool_value(s, 'disable', False)):
disable(args, s) disable(args, s)
logger.debug('{} disabled by the configuration file'.format(s)) logger.debug(f'{s} disabled by the configuration file')
# The configuration key can be overwrite from the command line # The configuration key can be overwrite from the command line
if args and args.disable_plugin and 'all' in args.disable_plugin.split(','): if args and args.disable_plugin and 'all' in args.disable_plugin.split(','):
if not args.enable_plugin: if not args.enable_plugin:
@ -664,19 +663,19 @@ Examples of use:
# Interactive or file password # Interactive or file password
if args.server: if args.server:
args.password = self.__get_password( args.password = self.__get_password(
description='Define the Glances server password ({} username): '.format(args.username), description=f'Define the Glances server password ({args.username} username): ',
confirm=True, confirm=True,
username=args.username, username=args.username,
) )
elif args.webserver: elif args.webserver:
args.password = self.__get_password( args.password = self.__get_password(
description='Define the Glances webserver password ({} username): '.format(args.username), description=f'Define the Glances webserver password ({args.username} username): ',
confirm=True, confirm=True,
username=args.username, username=args.username,
) )
elif args.client: elif args.client:
args.password = self.__get_password( args.password = self.__get_password(
description='Enter the Glances server password ({} username): '.format(args.username), description=f'Enter the Glances server password ({args.username} username): ',
clear=True, clear=True,
username=args.username, username=args.username,
) )

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -26,13 +25,13 @@ try:
PACKAGING_IMPORT = True PACKAGING_IMPORT = True
except Exception as e: except Exception as e:
logger.warning("Unable to import 'packaging' module ({}). Glances cannot check for updates.".format(e)) logger.warning(f"Unable to import 'packaging' module ({e}). Glances cannot check for updates.")
PACKAGING_IMPORT = False PACKAGING_IMPORT = False
PYPI_API_URL = 'https://pypi.python.org/pypi/Glances/json' PYPI_API_URL = 'https://pypi.python.org/pypi/Glances/json'
class Outdated(object): class Outdated:
""" """
This class aims at providing methods to warn the user when a new Glances This class aims at providing methods to warn the user when a new Glances
version is available on the PyPI repository (https://pypi.python.org/pypi/Glances/). version is available on the PyPI repository (https://pypi.python.org/pypi/Glances/).
@ -56,7 +55,7 @@ class Outdated(object):
if not self.args.disable_check_update: if not self.args.disable_check_update:
self.load_config(config) self.load_config(config)
logger.debug("Check Glances version up-to-date: {}".format(not self.args.disable_check_update)) logger.debug(f"Check Glances version up-to-date: {not self.args.disable_check_update}")
# And update ! # And update !
self.get_pypi_version() self.get_pypi_version()
@ -68,7 +67,7 @@ class Outdated(object):
if hasattr(config, 'has_section') and config.has_section(global_section): if hasattr(config, 'has_section') and config.has_section(global_section):
self.args.disable_check_update = config.get_value(global_section, 'check_update').lower() == 'false' self.args.disable_check_update = config.get_value(global_section, 'check_update').lower() == 'false'
else: else:
logger.debug("Cannot find section {} in the configuration file".format(global_section)) logger.debug(f"Cannot find section {global_section} in the configuration file")
return False return False
return True return True
@ -110,9 +109,7 @@ class Outdated(object):
# Check is disabled by configuration # Check is disabled by configuration
return False return False
logger.debug( logger.debug(f"Check Glances version (installed: {self.installed_version()} / latest: {self.latest_version()})")
"Check Glances version (installed: {} / latest: {})".format(self.installed_version(), self.latest_version())
)
return Version(self.latest_version()) > Version(self.installed_version()) return Version(self.latest_version()) > Version(self.installed_version())
def _load_cache(self): def _load_cache(self):
@ -124,7 +121,7 @@ class Outdated(object):
with open(self.cache_file, 'rb') as f: with open(self.cache_file, 'rb') as f:
cached_data = pickle.load(f) cached_data = pickle.load(f)
except Exception as e: except Exception as e:
logger.debug("Cannot read version from cache file: {} ({})".format(self.cache_file, e)) logger.debug(f"Cannot read version from cache file: {self.cache_file} ({e})")
else: else:
logger.debug("Read version from cache file") logger.debug("Read version from cache file")
if ( if (
@ -147,11 +144,11 @@ class Outdated(object):
with open(self.cache_file, 'wb') as f: with open(self.cache_file, 'wb') as f:
pickle.dump(self.data, f) pickle.dump(self.data, f)
except Exception as e: except Exception as e:
logger.error("Cannot write version to cache file {} ({})".format(self.cache_file, e)) logger.error(f"Cannot write version to cache file {self.cache_file} ({e})")
def _update_pypi_version(self): def _update_pypi_version(self):
"""Get the latest PyPI version (as a string) via the RESTful JSON API""" """Get the latest PyPI version (as a string) via the RESTful JSON API"""
logger.debug("Get latest Glances version from the PyPI RESTful API ({})".format(PYPI_API_URL)) logger.debug(f"Get latest Glances version from the PyPI RESTful API ({PYPI_API_URL})")
# Update the current time # Update the current time
self.data['refresh_date'] = datetime.now() self.data['refresh_date'] = datetime.now()
@ -159,7 +156,7 @@ class Outdated(object):
try: try:
res = urlopen(PYPI_API_URL, timeout=3).read() res = urlopen(PYPI_API_URL, timeout=3).read()
except (HTTPError, URLError, CertificateError) as e: except (HTTPError, URLError, CertificateError) as e:
logger.debug("Cannot get Glances version from the PyPI RESTful API ({})".format(e)) logger.debug(f"Cannot get Glances version from the PyPI RESTful API ({e})")
else: else:
self.data['latest_version'] = json.loads(nativestr(res))['info']['version'] self.data['latest_version'] = json.loads(nativestr(res))['info']['version']
logger.debug("Save Glances version to the cache file") logger.debug("Save Glances version to the cache file")

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -9,12 +8,10 @@
"""Manage bars for Glances output.""" """Manage bars for Glances output."""
from __future__ import division
from math import modf from math import modf
class Bar(object): class Bar:
"""Manage bar (progression or status). """Manage bar (progression or status).
import sys import sys
@ -115,7 +112,7 @@ class Bar(object):
ret, '>' if self.percent > self.max_value else ' ', self.max_value, self.__unit_char ret, '>' if self.percent > self.max_value else ' ', self.max_value, self.__unit_char
) )
else: else:
ret = '{}{:5.1f}{}'.format(ret, self.percent, self.__unit_char) ret = f'{ret}{self.percent:5.1f}{self.__unit_char}'
# Add overlay # Add overlay
if overlay and len(overlay) < len(ret) - 6: if overlay and len(overlay) < len(ret) - 6:

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -9,8 +8,6 @@
"""Curses interface class.""" """Curses interface class."""
from __future__ import unicode_literals
import getpass import getpass
import sys import sys
@ -33,7 +30,7 @@ except ImportError:
sys.exit(1) sys.exit(1)
class _GlancesCurses(object): class _GlancesCurses:
"""This class manages the curses display (and key pressed). """This class manages the curses display (and key pressed).
Note: It is a private class, use GlancesCursesClient or GlancesCursesBrowser. Note: It is a private class, use GlancesCursesClient or GlancesCursesBrowser.
@ -148,14 +145,14 @@ class _GlancesCurses(object):
logger.critical("Cannot init the curses library.\n") logger.critical("Cannot init the curses library.\n")
sys.exit(1) sys.exit(1)
else: else:
logger.debug("Curses library initialized with term: {}".format(curses.longname())) logger.debug(f"Curses library initialized with term: {curses.longname()}")
except Exception as e: except Exception as e:
if args.export: if args.export:
logger.info("Cannot init the curses library, quiet mode on and export.") logger.info("Cannot init the curses library, quiet mode on and export.")
args.quiet = True args.quiet = True
return return
logger.critical("Cannot init the curses library ({})".format(e)) logger.critical(f"Cannot init the curses library ({e})")
sys.exit(1) sys.exit(1)
# Load configuration file # Load configuration file
@ -224,11 +221,11 @@ class _GlancesCurses(object):
try: try:
if hasattr(curses, 'start_color'): if hasattr(curses, 'start_color'):
curses.start_color() curses.start_color()
logger.debug('Curses interface compatible with {} colors'.format(curses.COLORS)) logger.debug(f'Curses interface compatible with {curses.COLORS} colors')
if hasattr(curses, 'use_default_colors'): if hasattr(curses, 'use_default_colors'):
curses.use_default_colors() curses.use_default_colors()
except Exception as e: except Exception as e:
logger.warning('Error initializing terminal color ({})'.format(e)) logger.warning(f'Error initializing terminal color ({e})')
# Init colors # Init colors
if self.args.disable_bold: if self.args.disable_bold:
@ -368,7 +365,7 @@ class _GlancesCurses(object):
return -1 return -1
# Actions (available in the global hotkey dict)... # Actions (available in the global hotkey dict)...
logger.debug("Keypressed (code: {})".format(self.pressedkey)) logger.debug(f"Keypressed (code: {self.pressedkey})")
for hotkey in self._hotkeys: for hotkey in self._hotkeys:
if self.pressedkey == ord(hotkey) and 'switch' in self._hotkeys[hotkey]: if self.pressedkey == ord(hotkey) and 'switch' in self._hotkeys[hotkey]:
self._handle_switch(hotkey) self._handle_switch(hotkey)
@ -495,7 +492,7 @@ class _GlancesCurses(object):
if return_to_browser: if return_to_browser:
logger.info("Stop Glances client and return to the browser") logger.info("Stop Glances client and return to the browser")
else: else:
logger.info("Stop Glances (keypressed: {})".format(self.pressedkey)) logger.info(f"Stop Glances (keypressed: {self.pressedkey})")
def _handle_refresh(self): def _handle_refresh(self):
pass pass
@ -716,7 +713,7 @@ class _GlancesCurses(object):
# Display graph generation popup # Display graph generation popup
if self.args.generate_graph: if self.args.generate_graph:
if 'graph' in stats.getExportsList(): if 'graph' in stats.getExportsList():
self.display_popup('Generate graph in {}'.format(self.args.export_graph_path)) self.display_popup(f'Generate graph in {self.args.export_graph_path}')
else: else:
logger.warning('Graph export module is disable. Run Glances with --export graph to enable it.') logger.warning('Graph export module is disable. Run Glances with --export graph to enable it.')
self.args.generate_graph = False self.args.generate_graph = False
@ -735,7 +732,7 @@ class _GlancesCurses(object):
:param process :param process
:return: None :return: None
""" """
logger.debug("Selected process to kill: {}".format(process)) logger.debug(f"Selected process to kill: {process}")
if 'childrens' in process: if 'childrens' in process:
pid_to_kill = process['childrens'] pid_to_kill = process['childrens']
@ -755,9 +752,9 @@ class _GlancesCurses(object):
try: try:
ret_kill = glances_processes.kill(pid) ret_kill = glances_processes.kill(pid)
except Exception as e: except Exception as e:
logger.error('Can not kill process {} ({})'.format(pid, e)) logger.error(f'Can not kill process {pid} ({e})')
else: else:
logger.info('Kill signal has been sent to process {} (return code: {})'.format(pid, ret_kill)) logger.info(f'Kill signal has been sent to process {pid} (return code: {ret_kill})')
def __display_header(self, stat_display): def __display_header(self, stat_display):
"""Display the firsts lines (header) in the Curses interface. """Display the firsts lines (header) in the Curses interface.
@ -829,7 +826,7 @@ class _GlancesCurses(object):
max_width=quicklook_width, args=self.args max_width=quicklook_width, args=self.args
) )
except AttributeError as e: except AttributeError as e:
logger.debug("Quicklook plugin not available (%s)" % e) logger.debug(f"Quicklook plugin not available ({e})")
else: else:
plugin_widths['quicklook'] = self.get_stats_display_width(stat_display["quicklook"]) plugin_widths['quicklook'] = self.get_stats_display_width(stat_display["quicklook"])
stats_width = sum(itervalues(plugin_widths)) + 1 stats_width = sum(itervalues(plugin_widths)) + 1
@ -1258,7 +1255,7 @@ class _GlancesCurses(object):
) )
) )
except Exception as e: except Exception as e:
logger.debug('ERROR: Can not compute plugin width ({})'.format(e)) logger.debug(f'ERROR: Can not compute plugin width ({e})')
return 0 return 0
else: else:
return c return c
@ -1271,7 +1268,7 @@ class _GlancesCurses(object):
try: try:
c = [i['msg'] for i in curse_msg['msgdict']].count('\n') c = [i['msg'] for i in curse_msg['msgdict']].count('\n')
except Exception as e: except Exception as e:
logger.debug('ERROR: Can not compute plugin height ({})'.format(e)) logger.debug(f'ERROR: Can not compute plugin height ({e})')
return 0 return 0
else: else:
return c + 1 return c + 1
@ -1285,21 +1282,21 @@ class GlancesCursesClient(_GlancesCurses):
"""Class for the Glances curse client.""" """Class for the Glances curse client."""
class GlancesTextbox(Textbox, object): class GlancesTextbox(Textbox):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(GlancesTextbox, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def do_command(self, ch): def do_command(self, ch):
if ch == 10: # Enter if ch == 10: # Enter
return 0 return 0
if ch == 127: # Back if ch == 127: # Back
return 8 return 8
return super(GlancesTextbox, self).do_command(ch) return super().do_command(ch)
class GlancesTextboxYesNo(Textbox, object): class GlancesTextboxYesNo(Textbox):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(GlancesTextboxYesNo, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def do_command(self, ch): def do_command(self, ch):
return super(GlancesTextboxYesNo, self).do_command(ch) return super().do_command(ch)

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -22,7 +21,7 @@ class GlancesCursesBrowser(_GlancesCurses):
def __init__(self, args=None): def __init__(self, args=None):
"""Init the father class.""" """Init the father class."""
super(GlancesCursesBrowser, self).__init__(args=args) super().__init__(args=args)
_colors_list = { _colors_list = {
'UNKNOWN': self.no_color, 'UNKNOWN': self.no_color,
@ -151,7 +150,7 @@ class GlancesCursesBrowser(_GlancesCurses):
self.pressedkey = self.get_key(self.term_window) self.pressedkey = self.get_key(self.term_window)
refresh = False refresh = False
if self.pressedkey != -1: if self.pressedkey != -1:
logger.debug("Key pressed. Code=%s" % self.pressedkey) logger.debug(f"Key pressed. Code={self.pressedkey}")
# Actions... # Actions...
if self.pressedkey == ord('\x1b') or self.pressedkey == ord('q'): if self.pressedkey == ord('\x1b') or self.pressedkey == ord('q'):
@ -163,23 +162,23 @@ class GlancesCursesBrowser(_GlancesCurses):
elif self.pressedkey == 10: elif self.pressedkey == 10:
# 'ENTER' > Run Glances on the selected server # 'ENTER' > Run Glances on the selected server
self.active_server = self._current_page * self._page_max_lines + self.cursor_position self.active_server = self._current_page * self._page_max_lines + self.cursor_position
logger.debug("Server {}/{} selected".format(self.active_server, len(stats))) logger.debug(f"Server {self.active_server}/{len(stats)} selected")
elif self.pressedkey == curses.KEY_UP or self.pressedkey == 65: elif self.pressedkey == curses.KEY_UP or self.pressedkey == 65:
# 'UP' > Up in the server list # 'UP' > Up in the server list
self.cursor_up(stats) self.cursor_up(stats)
logger.debug("Server {}/{} selected".format(self.cursor + 1, len(stats))) logger.debug(f"Server {self.cursor + 1}/{len(stats)} selected")
elif self.pressedkey == curses.KEY_DOWN or self.pressedkey == 66: elif self.pressedkey == curses.KEY_DOWN or self.pressedkey == 66:
# 'DOWN' > Down in the server list # 'DOWN' > Down in the server list
self.cursor_down(stats) self.cursor_down(stats)
logger.debug("Server {}/{} selected".format(self.cursor + 1, len(stats))) logger.debug(f"Server {self.cursor + 1}/{len(stats)} selected")
elif self.pressedkey == curses.KEY_PPAGE: elif self.pressedkey == curses.KEY_PPAGE:
# 'Page UP' > Prev page in the server list # 'Page UP' > Prev page in the server list
self.cursor_pageup(stats) self.cursor_pageup(stats)
logger.debug("PageUP: Server ({}/{}) pages.".format(self._current_page + 1, self._page_max)) logger.debug(f"PageUP: Server ({self._current_page + 1}/{self._page_max}) pages.")
elif self.pressedkey == curses.KEY_NPAGE: elif self.pressedkey == curses.KEY_NPAGE:
# 'Page Down' > Next page in the server list # 'Page Down' > Next page in the server list
self.cursor_pagedown(stats) self.cursor_pagedown(stats)
logger.debug("PageDown: Server {}/{} pages".format(self._current_page + 1, self._page_max)) logger.debug(f"PageDown: Server {self._current_page + 1}/{self._page_max} pages")
elif self.pressedkey == ord('1'): elif self.pressedkey == ord('1'):
self._stats_list = None self._stats_list = None
refresh = True refresh = True
@ -211,7 +210,7 @@ class GlancesCursesBrowser(_GlancesCurses):
:param return_to_browser: :param return_to_browser:
""" """
# Flush display # Flush display
logger.debug('Servers list: {}'.format(stats)) logger.debug(f'Servers list: {stats}')
self.flush(stats) self.flush(stats)
# Wait # Wait
@ -268,19 +267,19 @@ class GlancesCursesBrowser(_GlancesCurses):
elif len(stats) == 1: elif len(stats) == 1:
msg = 'One Glances server available' msg = 'One Glances server available'
else: else:
msg = '{} Glances servers available'.format(stats_len) msg = f'{stats_len} Glances servers available'
if self.args.disable_autodiscover: if self.args.disable_autodiscover:
msg += ' (auto discover is disabled)' msg += ' (auto discover is disabled)'
if screen_y > 1: if screen_y > 1:
self.term_window.addnstr(y, x, msg, screen_x - x, self.colors_list['TITLE']) self.term_window.addnstr(y, x, msg, screen_x - x, self.colors_list['TITLE'])
msg = '{}'.format(self._get_status_count(stats)) msg = f'{self._get_status_count(stats)}'
self.term_window.addnstr(y + 1, x, msg, screen_x - x) self.term_window.addnstr(y + 1, x, msg, screen_x - x)
if stats_len > stats_max and screen_y > 2: if stats_len > stats_max and screen_y > 2:
msg = '{} servers displayed.({}/{}) {}'.format( page_lines = self.get_pagelines(stats)
self.get_pagelines(stats), self._current_page + 1, self._page_max, self._get_status_count(stats) status_count = self._get_status_count(stats)
) msg = f'{page_lines} servers displayed.({self._current_page + 1}/{self._page_max}) {status_count}'
self.term_window.addnstr(y + 1, x, msg, screen_x - x) self.term_window.addnstr(y + 1, x, msg, screen_x - x)
if stats_len == 0: if stats_len == 0:
@ -335,7 +334,7 @@ class GlancesCursesBrowser(_GlancesCurses):
try: try:
server_stat[c[0]] = v[c[0]] server_stat[c[0]] = v[c[0]]
except KeyError as e: except KeyError as e:
logger.debug("Cannot grab stats {} from server (KeyError: {})".format(c[0], e)) logger.debug(f"Cannot grab stats {c[0]} from server (KeyError: {e})")
server_stat[c[0]] = '?' server_stat[c[0]] = '?'
# Display alias instead of name # Display alias instead of name
try: try:

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -13,7 +12,6 @@ import os
import sys import sys
import tempfile import tempfile
import webbrowser import webbrowser
from io import open
from urllib.parse import urljoin from urllib.parse import urljoin
try: try:
@ -46,6 +44,7 @@ try:
except ImportError: except ImportError:
logger.critical('Uvicorn import error. Glances cannot start in web server mode.') logger.critical('Uvicorn import error. Glances cannot start in web server mode.')
sys.exit(2) sys.exit(2)
import builtins
import contextlib import contextlib
import threading import threading
import time import time
@ -77,7 +76,7 @@ class GlancesUvicornServer(uvicorn.Server):
thread.join() thread.join()
class GlancesRestfulApi(object): class GlancesRestfulApi:
"""This class manages the Restful API server.""" """This class manages the Restful API server."""
API_VERSION = __apiversion__ API_VERSION = __apiversion__
@ -102,7 +101,7 @@ class GlancesRestfulApi(object):
self.load_config(config) self.load_config(config)
# Set the bind URL # Set the bind URL
self.bind_url = urljoin('http://{}:{}/'.format(self.args.bind_address, self.args.port), self.url_prefix) self.bind_url = urljoin(f'http://{self.args.bind_address}:{self.args.port}/', self.url_prefix)
# FastAPI Init # FastAPI Init
if self.args.password: if self.args.password:
@ -151,9 +150,9 @@ class GlancesRestfulApi(object):
self.url_prefix = '/' self.url_prefix = '/'
if config is not None and config.has_section('outputs'): if config is not None and config.has_section('outputs'):
n = config.get_value('outputs', 'max_processes_display', default=None) n = config.get_value('outputs', 'max_processes_display', default=None)
logger.debug('Number of processes to display in the WebUI: {}'.format(n)) logger.debug(f'Number of processes to display in the WebUI: {n}')
self.url_prefix = config.get_value('outputs', 'url_prefix', default='/') self.url_prefix = config.get_value('outputs', 'url_prefix', default='/')
logger.debug('URL prefix: {}'.format(self.url_prefix)) logger.debug(f'URL prefix: {self.url_prefix}')
def __update__(self): def __update__(self):
# Never update more than 1 time per cached_time # Never update more than 1 time per cached_time
@ -184,92 +183,92 @@ class GlancesRestfulApi(object):
# REST API # REST API
router.add_api_route( router.add_api_route(
'/api/%s/status' % self.API_VERSION, f'/api/{self.API_VERSION}/status',
status_code=status.HTTP_200_OK, status_code=status.HTTP_200_OK,
response_class=ORJSONResponse, response_class=ORJSONResponse,
endpoint=self._api_status, endpoint=self._api_status,
) )
router.add_api_route( router.add_api_route(
'/api/%s/config' % self.API_VERSION, response_class=ORJSONResponse, endpoint=self._api_config f'/api/{self.API_VERSION}/config', response_class=ORJSONResponse, endpoint=self._api_config
) )
router.add_api_route( router.add_api_route(
'/api/%s/config/{section}' % self.API_VERSION, f'/api/{self.API_VERSION}/config/{{section}}',
response_class=ORJSONResponse, response_class=ORJSONResponse,
endpoint=self._api_config_section, endpoint=self._api_config_section,
) )
router.add_api_route( router.add_api_route(
'/api/%s/config/{section}/{item}' % self.API_VERSION, f'/api/{self.API_VERSION}/config/{{section}}/{{item}}',
response_class=ORJSONResponse, response_class=ORJSONResponse,
endpoint=self._api_config_section_item, endpoint=self._api_config_section_item,
) )
router.add_api_route('/api/%s/args' % self.API_VERSION, response_class=ORJSONResponse, endpoint=self._api_args) router.add_api_route(f'/api/{self.API_VERSION}/args', response_class=ORJSONResponse, endpoint=self._api_args)
router.add_api_route( router.add_api_route(
'/api/%s/args/{item}' % self.API_VERSION, response_class=ORJSONResponse, endpoint=self._api_args_item f'/api/{self.API_VERSION}/args/{{item}}', response_class=ORJSONResponse, endpoint=self._api_args_item
) )
router.add_api_route( router.add_api_route(
'/api/%s/pluginslist' % self.API_VERSION, response_class=ORJSONResponse, endpoint=self._api_plugins f'/api/{self.API_VERSION}/pluginslist', response_class=ORJSONResponse, endpoint=self._api_plugins
) )
router.add_api_route('/api/%s/all' % self.API_VERSION, response_class=ORJSONResponse, endpoint=self._api_all) router.add_api_route(f'/api/{self.API_VERSION}/all', response_class=ORJSONResponse, endpoint=self._api_all)
router.add_api_route( router.add_api_route(
'/api/%s/all/limits' % self.API_VERSION, response_class=ORJSONResponse, endpoint=self._api_all_limits f'/api/{self.API_VERSION}/all/limits', response_class=ORJSONResponse, endpoint=self._api_all_limits
) )
router.add_api_route( router.add_api_route(
'/api/%s/all/views' % self.API_VERSION, response_class=ORJSONResponse, endpoint=self._api_all_views f'/api/{self.API_VERSION}/all/views', response_class=ORJSONResponse, endpoint=self._api_all_views
) )
router.add_api_route('/api/%s/help' % self.API_VERSION, response_class=ORJSONResponse, endpoint=self._api_help) router.add_api_route(f'/api/{self.API_VERSION}/help', response_class=ORJSONResponse, endpoint=self._api_help)
router.add_api_route('/api/%s/{plugin}' % self.API_VERSION, response_class=ORJSONResponse, endpoint=self._api) router.add_api_route(f'/api/{self.API_VERSION}/{{plugin}}', response_class=ORJSONResponse, endpoint=self._api)
router.add_api_route( router.add_api_route(
'/api/%s/{plugin}/history' % self.API_VERSION, response_class=ORJSONResponse, endpoint=self._api_history f'/api/{self.API_VERSION}/{{plugin}}/history', response_class=ORJSONResponse, endpoint=self._api_history
) )
router.add_api_route( router.add_api_route(
'/api/%s/{plugin}/history/{nb}' % self.API_VERSION, f'/api/{self.API_VERSION}/{{plugin}}/history/{{nb}}',
response_class=ORJSONResponse, response_class=ORJSONResponse,
endpoint=self._api_history, endpoint=self._api_history,
) )
router.add_api_route( router.add_api_route(
'/api/%s/{plugin}/top/{nb}' % self.API_VERSION, response_class=ORJSONResponse, endpoint=self._api_top f'/api/{self.API_VERSION}/{{plugin}}/top/{{nb}}', response_class=ORJSONResponse, endpoint=self._api_top
) )
router.add_api_route( router.add_api_route(
'/api/%s/{plugin}/limits' % self.API_VERSION, response_class=ORJSONResponse, endpoint=self._api_limits f'/api/{self.API_VERSION}/{{plugin}}/limits', response_class=ORJSONResponse, endpoint=self._api_limits
) )
router.add_api_route( router.add_api_route(
'/api/%s/{plugin}/views' % self.API_VERSION, response_class=ORJSONResponse, endpoint=self._api_views f'/api/{self.API_VERSION}/{{plugin}}/views', response_class=ORJSONResponse, endpoint=self._api_views
) )
router.add_api_route( router.add_api_route(
'/api/%s/{plugin}/{item}' % self.API_VERSION, response_class=ORJSONResponse, endpoint=self._api_item f'/api/{self.API_VERSION}/{{plugin}}/{{item}}', response_class=ORJSONResponse, endpoint=self._api_item
) )
router.add_api_route( router.add_api_route(
'/api/%s/{plugin}/{item}/history' % self.API_VERSION, f'/api/{self.API_VERSION}/{{plugin}}/{{item}}/history',
response_class=ORJSONResponse, response_class=ORJSONResponse,
endpoint=self._api_item_history, endpoint=self._api_item_history,
) )
router.add_api_route( router.add_api_route(
'/api/%s/{plugin}/{item}/history/{nb}' % self.API_VERSION, f'/api/{self.API_VERSION}/{{plugin}}/{{item}}/history/{{nb}}',
response_class=ORJSONResponse, response_class=ORJSONResponse,
endpoint=self._api_item_history, endpoint=self._api_item_history,
) )
router.add_api_route( router.add_api_route(
'/api/%s/{plugin}/{item}/description' % self.API_VERSION, f'/api/{self.API_VERSION}/{{plugin}}/{{item}}/description',
response_class=ORJSONResponse, response_class=ORJSONResponse,
endpoint=self._api_item_description, endpoint=self._api_item_description,
) )
router.add_api_route( router.add_api_route(
'/api/%s/{plugin}/{item}/unit' % self.API_VERSION, f'/api/{self.API_VERSION}/{{plugin}}/{{item}}/unit',
response_class=ORJSONResponse, response_class=ORJSONResponse,
endpoint=self._api_item_unit, endpoint=self._api_item_unit,
) )
router.add_api_route( router.add_api_route(
'/api/%s/{plugin}/{item}/{value}' % self.API_VERSION, f'/api/{self.API_VERSION}/{{plugin}}/{{item}}/{{value}}',
response_class=ORJSONResponse, response_class=ORJSONResponse,
endpoint=self._api_value, endpoint=self._api_value,
) )
# Restful API # Restful API
bindmsg = 'Glances RESTful API Server started on {}api/{}'.format(self.bind_url, self.API_VERSION) bindmsg = f'Glances RESTful API Server started on {self.bind_url}api/{self.API_VERSION}'
logger.info(bindmsg) logger.info(bindmsg)
# WEB UI # WEB UI
@ -280,9 +279,9 @@ class GlancesRestfulApi(object):
# Statics files # Statics files
self._app.mount("/static", StaticFiles(directory=self.STATIC_PATH), name="static") self._app.mount("/static", StaticFiles(directory=self.STATIC_PATH), name="static")
logger.info("Get WebUI in {}".format(self.STATIC_PATH)) logger.info(f"Get WebUI in {self.STATIC_PATH}")
bindmsg = 'Glances Web User Interface started on {}'.format(self.bind_url) bindmsg = f'Glances Web User Interface started on {self.bind_url}'
else: else:
bindmsg = 'The WebUI is disable (--disable-webui)' bindmsg = 'The WebUI is disable (--disable-webui)'
@ -317,7 +316,7 @@ class GlancesRestfulApi(object):
try: try:
self.uvicorn_server = GlancesUvicornServer(config=uvicorn_config) self.uvicorn_server = GlancesUvicornServer(config=uvicorn_config)
except Exception as e: except Exception as e:
logger.critical('Error: Can not ran Glances Web server ({})'.format(e)) logger.critical(f'Error: Can not ran Glances Web server ({e})')
self.uvicorn_server = None self.uvicorn_server = None
else: else:
with self.uvicorn_server.run_in_thread(): with self.uvicorn_server.run_in_thread():
@ -369,7 +368,7 @@ class GlancesRestfulApi(object):
try: try:
plist = self.stats.get_plugin("help").get_view_data() plist = self.stats.get_plugin("help").get_view_data()
except Exception as e: except Exception as e:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Cannot get help view data (%s)" % str(e)) raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Cannot get help view data ({str(e)})")
return ORJSONResponse(plist) return ORJSONResponse(plist)
@ -405,7 +404,7 @@ class GlancesRestfulApi(object):
try: try:
plist = self.plugins_list plist = self.plugins_list
except Exception as e: except Exception as e:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Cannot get plugin list (%s)" % str(e)) raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Cannot get plugin list ({str(e)})")
return ORJSONResponse(plist) return ORJSONResponse(plist)
@ -420,10 +419,10 @@ class GlancesRestfulApi(object):
if self.args.debug: if self.args.debug:
fname = os.path.join(tempfile.gettempdir(), 'glances-debug.json') fname = os.path.join(tempfile.gettempdir(), 'glances-debug.json')
try: try:
with open(fname) as f: with builtins.open(fname) as f:
return f.read() return f.read()
except IOError: except OSError:
logger.debug("Debug file (%s) not found" % fname) logger.debug(f"Debug file ({fname}) not found")
# Update the stat # Update the stat
self.__update__() self.__update__()
@ -432,7 +431,7 @@ class GlancesRestfulApi(object):
# Get the RAW value of the stat ID # Get the RAW value of the stat ID
statval = self.stats.getAllAsDict() statval = self.stats.getAllAsDict()
except Exception as e: except Exception as e:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Cannot get stats (%s)" % str(e)) raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Cannot get stats ({str(e)})")
return ORJSONResponse(statval) return ORJSONResponse(statval)
@ -448,7 +447,7 @@ class GlancesRestfulApi(object):
# Get the RAW value of the stat limits # Get the RAW value of the stat limits
limits = self.stats.getAllLimitsAsDict() limits = self.stats.getAllLimitsAsDict()
except Exception as e: except Exception as e:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Cannot get limits (%s)" % str(e)) raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Cannot get limits ({str(e)})")
return ORJSONResponse(limits) return ORJSONResponse(limits)
@ -464,7 +463,7 @@ class GlancesRestfulApi(object):
# Get the RAW value of the stat view # Get the RAW value of the stat view
limits = self.stats.getAllViewsAsDict() limits = self.stats.getAllViewsAsDict()
except Exception as e: except Exception as e:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Cannot get views (%s)" % str(e)) raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Cannot get views ({str(e)})")
return ORJSONResponse(limits) return ORJSONResponse(limits)
@ -479,7 +478,7 @@ class GlancesRestfulApi(object):
if plugin not in self.plugins_list: if plugin not in self.plugins_list:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail="Unknown plugin %s (available plugins: %s)" % (plugin, self.plugins_list), detail=f"Unknown plugin {plugin} (available plugins: {self.plugins_list})",
) )
# Update the stat # Update the stat
@ -489,9 +488,7 @@ class GlancesRestfulApi(object):
# Get the RAW value of the stat ID # Get the RAW value of the stat ID
statval = self.stats.get_plugin(plugin).get_raw() statval = self.stats.get_plugin(plugin).get_raw()
except Exception as e: except Exception as e:
raise HTTPException( raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Cannot get plugin {plugin} ({str(e)})")
status_code=status.HTTP_404_NOT_FOUND, detail="Cannot get plugin %s (%s)" % (plugin, str(e))
)
return ORJSONResponse(statval) return ORJSONResponse(statval)
@ -508,7 +505,7 @@ class GlancesRestfulApi(object):
if plugin not in self.plugins_list: if plugin not in self.plugins_list:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail="Unknown plugin %s (available plugins: %s)" % (plugin, self.plugins_list), detail=f"Unknown plugin {plugin} (available plugins: {self.plugins_list})",
) )
# Update the stat # Update the stat
@ -518,9 +515,7 @@ class GlancesRestfulApi(object):
# Get the RAW value of the stat ID # Get the RAW value of the stat ID
statval = self.stats.get_plugin(plugin).get_raw() statval = self.stats.get_plugin(plugin).get_raw()
except Exception as e: except Exception as e:
raise HTTPException( raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Cannot get plugin {plugin} ({str(e)})")
status_code=status.HTTP_404_NOT_FOUND, detail="Cannot get plugin %s (%s)" % (plugin, str(e))
)
print(statval) print(statval)
@ -541,7 +536,7 @@ class GlancesRestfulApi(object):
if plugin not in self.plugins_list: if plugin not in self.plugins_list:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail="Unknown plugin %s (available plugins: %s)" % (plugin, self.plugins_list), detail=f"Unknown plugin {plugin} (available plugins: {self.plugins_list})",
) )
# Update the stat # Update the stat
@ -552,7 +547,7 @@ class GlancesRestfulApi(object):
statval = self.stats.get_plugin(plugin).get_raw_history(nb=int(nb)) statval = self.stats.get_plugin(plugin).get_raw_history(nb=int(nb))
except Exception as e: except Exception as e:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Cannot get plugin history %s (%s)" % (plugin, str(e)) status_code=status.HTTP_404_NOT_FOUND, detail=f"Cannot get plugin history {plugin} ({str(e)})"
) )
return statval return statval
@ -568,7 +563,7 @@ class GlancesRestfulApi(object):
if plugin not in self.plugins_list: if plugin not in self.plugins_list:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail="Unknown plugin %s (available plugins: %s)" % (plugin, self.plugins_list), detail=f"Unknown plugin {plugin} (available plugins: {self.plugins_list})",
) )
try: try:
@ -576,7 +571,7 @@ class GlancesRestfulApi(object):
ret = self.stats.get_plugin(plugin).limits ret = self.stats.get_plugin(plugin).limits
except Exception as e: except Exception as e:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Cannot get limits for plugin %s (%s)" % (plugin, str(e)) status_code=status.HTTP_404_NOT_FOUND, detail=f"Cannot get limits for plugin {plugin} ({str(e)})"
) )
return ORJSONResponse(ret) return ORJSONResponse(ret)
@ -592,7 +587,7 @@ class GlancesRestfulApi(object):
if plugin not in self.plugins_list: if plugin not in self.plugins_list:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail="Unknown plugin %s (available plugins: %s)" % (plugin, self.plugins_list), detail=f"Unknown plugin {plugin} (available plugins: {self.plugins_list})",
) )
try: try:
@ -600,7 +595,7 @@ class GlancesRestfulApi(object):
ret = self.stats.get_plugin(plugin).get_views() ret = self.stats.get_plugin(plugin).get_views()
except Exception as e: except Exception as e:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Cannot get views for plugin %s (%s)" % (plugin, str(e)) status_code=status.HTTP_404_NOT_FOUND, detail=f"Cannot get views for plugin {plugin} ({str(e)})"
) )
return ORJSONResponse(ret) return ORJSONResponse(ret)
@ -616,7 +611,7 @@ class GlancesRestfulApi(object):
if plugin not in self.plugins_list: if plugin not in self.plugins_list:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail="Unknown plugin %s (available plugins: %s)" % (plugin, self.plugins_list), detail=f"Unknown plugin {plugin} (available plugins: {self.plugins_list})",
) )
# Update the stat # Update the stat
@ -628,7 +623,7 @@ class GlancesRestfulApi(object):
except Exception as e: except Exception as e:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, status_code=status.HTTP_404_NOT_FOUND,
detail="Cannot get item %s in plugin %s (%s)" % (item, plugin, str(e)), detail=f"Cannot get item {item} in plugin {plugin} ({str(e)})",
) )
return ORJSONResponse(ret) return ORJSONResponse(ret)
@ -645,7 +640,7 @@ class GlancesRestfulApi(object):
if plugin not in self.plugins_list: if plugin not in self.plugins_list:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail="Unknown plugin %s (available plugins: %s)" % (plugin, self.plugins_list), detail=f"Unknown plugin {plugin} (available plugins: {self.plugins_list})",
) )
# Update the stat # Update the stat
@ -656,7 +651,7 @@ class GlancesRestfulApi(object):
ret = self.stats.get_plugin(plugin).get_raw_history(item, nb=nb) ret = self.stats.get_plugin(plugin).get_raw_history(item, nb=nb)
except Exception as e: except Exception as e:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Cannot get history for plugin %s (%s)" % (plugin, str(e)) status_code=status.HTTP_404_NOT_FOUND, detail=f"Cannot get history for plugin {plugin} ({str(e)})"
) )
else: else:
return ORJSONResponse(ret) return ORJSONResponse(ret)
@ -672,7 +667,7 @@ class GlancesRestfulApi(object):
if plugin not in self.plugins_list: if plugin not in self.plugins_list:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail="Unknown plugin %s (available plugins: %s)" % (plugin, self.plugins_list), detail=f"Unknown plugin {plugin} (available plugins: {self.plugins_list})",
) )
try: try:
@ -681,7 +676,7 @@ class GlancesRestfulApi(object):
except Exception as e: except Exception as e:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, status_code=status.HTTP_404_NOT_FOUND,
detail="Cannot get %s description for plugin %s (%s)" % (item, plugin, str(e)), detail=f"Cannot get {item} description for plugin {plugin} ({str(e)})",
) )
else: else:
return ORJSONResponse(ret) return ORJSONResponse(ret)
@ -697,7 +692,7 @@ class GlancesRestfulApi(object):
if plugin not in self.plugins_list: if plugin not in self.plugins_list:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail="Unknown plugin %s (available plugins: %s)" % (plugin, self.plugins_list), detail=f"Unknown plugin {plugin} (available plugins: {self.plugins_list})",
) )
try: try:
@ -706,7 +701,7 @@ class GlancesRestfulApi(object):
except Exception as e: except Exception as e:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, status_code=status.HTTP_404_NOT_FOUND,
detail="Cannot get %s unit for plugin %s (%s)" % (item, plugin, str(e)), detail=f"Cannot get {item} unit for plugin {plugin} ({str(e)})",
) )
else: else:
return ORJSONResponse(ret) return ORJSONResponse(ret)
@ -722,7 +717,7 @@ class GlancesRestfulApi(object):
if plugin not in self.plugins_list: if plugin not in self.plugins_list:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail="Unknown plugin %s (available plugins: %s)" % (plugin, self.plugins_list), detail=f"Unknown plugin {plugin} (available plugins: {self.plugins_list})",
) )
# Update the stat # Update the stat
@ -734,7 +729,7 @@ class GlancesRestfulApi(object):
except Exception as e: except Exception as e:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, status_code=status.HTTP_404_NOT_FOUND,
detail="Cannot get %s = %s for plugin %s (%s)" % (item, value, plugin, str(e)), detail=f"Cannot get {item} = {value} for plugin {plugin} ({str(e)})",
) )
else: else:
return ORJSONResponse(ret) return ORJSONResponse(ret)
@ -750,7 +745,7 @@ class GlancesRestfulApi(object):
# Get the RAW value of the config' dict # Get the RAW value of the config' dict
args_json = self.config.as_dict() args_json = self.config.as_dict()
except Exception as e: except Exception as e:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Cannot get config (%s)" % str(e)) raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Cannot get config ({str(e)})")
else: else:
return ORJSONResponse(args_json) return ORJSONResponse(args_json)
@ -764,16 +759,14 @@ class GlancesRestfulApi(object):
""" """
config_dict = self.config.as_dict() config_dict = self.config.as_dict()
if section not in config_dict: if section not in config_dict:
raise HTTPException( raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f"Unknown configuration item {section}")
status_code=status.HTTP_400_BAD_REQUEST, detail="Unknown configuration item %s" % section
)
try: try:
# Get the RAW value of the config' dict # Get the RAW value of the config' dict
ret_section = config_dict[section] ret_section = config_dict[section]
except Exception as e: except Exception as e:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Cannot get config section %s (%s)" % (section, str(e)) status_code=status.HTTP_404_NOT_FOUND, detail=f"Cannot get config section {section} ({str(e)})"
) )
return ORJSONResponse(ret_section) return ORJSONResponse(ret_section)
@ -788,16 +781,14 @@ class GlancesRestfulApi(object):
""" """
config_dict = self.config.as_dict() config_dict = self.config.as_dict()
if section not in config_dict: if section not in config_dict:
raise HTTPException( raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f"Unknown configuration item {section}")
status_code=status.HTTP_400_BAD_REQUEST, detail="Unknown configuration item %s" % section
)
try: try:
# Get the RAW value of the config' dict section # Get the RAW value of the config' dict section
ret_section = config_dict[section] ret_section = config_dict[section]
except Exception as e: except Exception as e:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Cannot get config section %s (%s)" % (section, str(e)) status_code=status.HTTP_404_NOT_FOUND, detail=f"Cannot get config section {section} ({str(e)})"
) )
try: try:
@ -806,7 +797,7 @@ class GlancesRestfulApi(object):
except Exception as e: except Exception as e:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, status_code=status.HTTP_404_NOT_FOUND,
detail="Cannot get item %s in config section %s (%s)" % (item, section, str(e)), detail=f"Cannot get item {item} in config section {section} ({str(e)})",
) )
return ORJSONResponse(ret_item) return ORJSONResponse(ret_item)
@ -824,7 +815,7 @@ class GlancesRestfulApi(object):
# Source: https://docs.python.org/%s/library/functions.html#vars # Source: https://docs.python.org/%s/library/functions.html#vars
args_json = vars(self.args) args_json = vars(self.args)
except Exception as e: except Exception as e:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Cannot get args (%s)" % str(e)) raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Cannot get args ({str(e)})")
return ORJSONResponse(args_json) return ORJSONResponse(args_json)
@ -837,7 +828,7 @@ class GlancesRestfulApi(object):
HTTP/404 if others error HTTP/404 if others error
""" """
if item not in self.args: if item not in self.args:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Unknown argument item %s" % item) raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f"Unknown argument item {item}")
try: try:
# Get the RAW value of the args' dict # Get the RAW value of the args' dict
@ -845,6 +836,6 @@ class GlancesRestfulApi(object):
# Source: https://docs.python.org/%s/library/functions.html#vars # Source: https://docs.python.org/%s/library/functions.html#vars
args_json = vars(self.args)[item] args_json = vars(self.args)[item]
except Exception as e: except Exception as e:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Cannot get args item (%s)" % str(e)) raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Cannot get args item ({str(e)})")
return ORJSONResponse(args_json) return ORJSONResponse(args_json)

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -9,8 +8,6 @@
"""Manage sparklines for Glances output.""" """Manage sparklines for Glances output."""
from __future__ import division, unicode_literals
import sys import sys
from glances.globals import nativestr from glances.globals import nativestr
@ -21,17 +18,17 @@ sparklines_module = True
try: try:
from sparklines import sparklines from sparklines import sparklines
except ImportError as e: except ImportError as e:
logger.warning("Sparklines module not found ({})".format(e)) logger.warning(f"Sparklines module not found ({e})")
sparklines_module = False sparklines_module = False
try: try:
'┌┬┐╔╦╗╒╤╕╓╥╖│║─═├┼┤╠╬╣╞╪╡╟╫╢└┴┘╚╩╝╘╧╛╙╨╜'.encode(sys.stdout.encoding) '┌┬┐╔╦╗╒╤╕╓╥╖│║─═├┼┤╠╬╣╞╪╡╟╫╢└┴┘╚╩╝╘╧╛╙╨╜'.encode(sys.stdout.encoding)
except (UnicodeEncodeError, TypeError) as e: except (UnicodeEncodeError, TypeError) as e:
logger.warning("UTF-8 is mandatory for sparklines ({})".format(e)) logger.warning(f"UTF-8 is mandatory for sparklines ({e})")
sparklines_module = False sparklines_module = False
class Sparkline(object): class Sparkline:
"""Manage sparklines (see https://pypi.org/project/sparklines/).""" """Manage sparklines (see https://pypi.org/project/sparklines/)."""
def __init__(self, size, pre_char='[', post_char=']', unit_char='%', display_value=True): def __init__(self, size, pre_char='[', post_char=']', unit_char='%', display_value=True):
@ -83,7 +80,7 @@ class Sparkline(object):
if self.__display_value: if self.__display_value:
percents_without_none = [x for x in self.percents if x is not None] percents_without_none = [x for x in self.percents if x is not None]
if len(percents_without_none) > 0: if len(percents_without_none) > 0:
ret = '{}{:5.1f}{}'.format(ret, percents_without_none[-1], self.__unit_char) ret = f'{ret}{percents_without_none[-1]:5.1f}{self.__unit_char}'
ret = nativestr(ret) ret = nativestr(ret)
if overwrite and len(overwrite) < len(ret) - 6: if overwrite and len(overwrite) < len(ret) - 6:
ret = overwrite + ret[len(overwrite) :] ret = overwrite + ret[len(overwrite) :]

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -15,7 +14,7 @@ from glances.globals import printandflush
from glances.logger import logger from glances.logger import logger
class GlancesStdout(object): class GlancesStdout:
"""This class manages the Stdout display.""" """This class manages the Stdout display."""
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
@ -65,9 +64,9 @@ class GlancesStdout(object):
# With attribute # With attribute
if isinstance(stat, dict): if isinstance(stat, dict):
try: try:
printandflush("{}.{}: {}".format(plugin, attribute, stat[attribute])) printandflush(f"{plugin}.{attribute}: {stat[attribute]}")
except KeyError as err: except KeyError as err:
logger.error("Can not display stat {}.{} ({})".format(plugin, attribute, err)) logger.error(f"Can not display stat {plugin}.{attribute} ({err})")
elif isinstance(stat, list): elif isinstance(stat, list):
for i in stat: for i in stat:
if key is None: if key is None:
@ -77,12 +76,12 @@ class GlancesStdout(object):
else: else:
continue continue
try: try:
printandflush("{}.{}.{}: {}".format(plugin, i_key, attribute, i[attribute])) printandflush(f"{plugin}.{i_key}.{attribute}: {i[attribute]}")
except KeyError as err: except KeyError as err:
logger.error("Can not display stat {}.{} ({})".format(plugin, attribute, err)) logger.error(f"Can not display stat {plugin}.{attribute} ({err})")
else: else:
# Without attribute # Without attribute
printandflush("{}: {}".format(plugin, stat)) printandflush(f"{plugin}: {stat}")
# Wait until next refresh # Wait until next refresh
if duration > 0: if duration > 0:

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -17,15 +16,15 @@ from glances import __apiversion__
from glances.globals import iteritems from glances.globals import iteritems
from glances.logger import logger from glances.logger import logger
API_URL = "http://localhost:61208/api/{api_version}".format(api_version=__apiversion__) API_URL = f"http://localhost:61208/api/{__apiversion__}"
APIDOC_HEADER = """\ APIDOC_HEADER = f"""\
.. _api: .. _api:
API (Restfull/JSON) documentation API (Restfull/JSON) documentation
================================= =================================
This documentation describes the Glances API version {api_version} (Restfull/JSON) interface. This documentation describes the Glances API version {__apiversion__} (Restfull/JSON) interface.
For Glances version 3, please have a look on: For Glances version 3, please have a look on:
``https://github.com/nicolargo/glances/blob/support/glancesv3/docs/api.rst`` ``https://github.com/nicolargo/glances/blob/support/glancesv3/docs/api.rst``
@ -44,7 +43,7 @@ It is also ran automatically when Glances is started in Web server mode (-w).
API URL API URL
------- -------
The default root API URL is ``http://localhost:61208/api/{api_version}``. The default root API URL is ``http://localhost:61208/api/{__apiversion__}``.
The bind address and port could be changed using the ``--bind`` and ``--port`` command line options. The bind address and port could be changed using the ``--bind`` and ``--port`` command line options.
@ -59,7 +58,7 @@ For example:
[outputs] [outputs]
url_prefix = /glances/ url_prefix = /glances/
will change the root API URL to ``http://localhost:61208/glances/api/{api_version}`` and the Web UI URL to will change the root API URL to ``http://localhost:61208/glances/api/{__apiversion__}`` and the Web UI URL to
``http://localhost:61208/glances/`` ``http://localhost:61208/glances/``
API documentation URL API documentation URL
@ -74,7 +73,7 @@ WebUI refresh
It is possible to change the Web UI refresh rate (default is 2 seconds) using the following option in the URL: It is possible to change the Web UI refresh rate (default is 2 seconds) using the following option in the URL:
``http://localhost:61208/glances/?refresh=5`` ``http://localhost:61208/glances/?refresh=5``
""".format(api_version=__apiversion__) """
def indent_stat(stat, indent=' '): def indent_stat(stat, indent=' '):
@ -95,7 +94,7 @@ def print_api_status():
print('') print('')
print('Get the Rest API status::') print('Get the Rest API status::')
print('') print('')
print(' # curl -I {}/status'.format(API_URL)) print(f' # curl -I {API_URL}/status')
print(indent_stat('HTTP/1.0 200 OK')) print(indent_stat('HTTP/1.0 200 OK'))
print('') print('')
@ -107,20 +106,20 @@ def print_plugins_list(stat):
print('') print('')
print('Get the plugins list::') print('Get the plugins list::')
print('') print('')
print(' # curl {}/pluginslist'.format(API_URL)) print(f' # curl {API_URL}/pluginslist')
print(indent_stat(stat)) print(indent_stat(stat))
print('') print('')
def print_plugin_stats(plugin, stat): def print_plugin_stats(plugin, stat):
sub_title = 'GET {}'.format(plugin) sub_title = f'GET {plugin}'
print(sub_title) print(sub_title)
print('-' * len(sub_title)) print('-' * len(sub_title))
print('') print('')
print('Get plugin stats::') print('Get plugin stats::')
print('') print('')
print(' # curl {}/{}'.format(API_URL, plugin)) print(f' # curl {API_URL}/{plugin}')
print(indent_stat(json.loads(stat.get_stats()))) print(indent_stat(json.loads(stat.get_stats())))
print('') print('')
@ -179,7 +178,7 @@ def print_plugin_description(plugin, stat):
print('') print('')
else: else:
logger.error('No fields_description variable defined for plugin {}'.format(plugin)) logger.error(f'No fields_description variable defined for plugin {plugin}')
def print_plugin_item_value(plugin, stat, stat_export): def print_plugin_item_value(plugin, stat, stat_export):
@ -201,13 +200,13 @@ def print_plugin_item_value(plugin, stat, stat_export):
value = stat_item[item] value = stat_item[item]
print('Get a specific field::') print('Get a specific field::')
print('') print('')
print(' # curl {}/{}/{}'.format(API_URL, plugin, item)) print(f' # curl {API_URL}/{plugin}/{item}')
print(indent_stat(stat_item)) print(indent_stat(stat_item))
print('') print('')
if item and value and stat.get_stats_value(item, value): if item and value and stat.get_stats_value(item, value):
print('Get a specific item when field matches the given value::') print('Get a specific item when field matches the given value::')
print('') print('')
print(' # curl {}/{}/{}/{}'.format(API_URL, plugin, item, value)) print(f' # curl {API_URL}/{plugin}/{item}/{value}')
print(indent_stat(json.loads(stat.get_stats_value(item, value)))) print(indent_stat(json.loads(stat.get_stats_value(item, value))))
print('') print('')
@ -219,7 +218,7 @@ def print_all():
print('') print('')
print('Get all Glances stats::') print('Get all Glances stats::')
print('') print('')
print(' # curl {}/all'.format(API_URL)) print(f' # curl {API_URL}/all')
print(' Return a very big dictionary (avoid using this request, performances will be poor)...') print(' Return a very big dictionary (avoid using this request, performances will be poor)...')
print('') print('')
@ -233,7 +232,7 @@ def print_top(stats):
print('') print('')
print('Get top 2 processes of the processlist plugin::') print('Get top 2 processes of the processlist plugin::')
print('') print('')
print(' # curl {}/processlist/top/2'.format(API_URL)) print(f' # curl {API_URL}/processlist/top/2')
print(indent_stat(stats.get_plugin('processlist').get_export()[:2])) print(indent_stat(stats.get_plugin('processlist').get_export()[:2]))
print('') print('')
print('Note: Only work for plugin with a list of items') print('Note: Only work for plugin with a list of items')
@ -246,7 +245,7 @@ def print_fields_info(stats):
print('-' * len(sub_title)) print('-' * len(sub_title))
print('Get item description (human readable) for a specific plugin/item::') print('Get item description (human readable) for a specific plugin/item::')
print('') print('')
print(' # curl {}/diskio/read_bytes/description'.format(API_URL)) print(f' # curl {API_URL}/diskio/read_bytes/description')
print(indent_stat(stats.get_plugin('diskio').get_item_info('read_bytes', 'description'))) print(indent_stat(stats.get_plugin('diskio').get_item_info('read_bytes', 'description')))
print('') print('')
print('Note: the description is defined in the fields_description variable of the plugin.') print('Note: the description is defined in the fields_description variable of the plugin.')
@ -256,7 +255,7 @@ def print_fields_info(stats):
print('-' * len(sub_title)) print('-' * len(sub_title))
print('Get item unit for a specific plugin/item::') print('Get item unit for a specific plugin/item::')
print('') print('')
print(' # curl {}/diskio/read_bytes/unit'.format(API_URL)) print(f' # curl {API_URL}/diskio/read_bytes/unit')
print(indent_stat(stats.get_plugin('diskio').get_item_info('read_bytes', 'unit'))) print(indent_stat(stats.get_plugin('diskio').get_item_info('read_bytes', 'unit')))
print('') print('')
print('Note: the description is defined in the fields_description variable of the plugin.') print('Note: the description is defined in the fields_description variable of the plugin.')
@ -274,22 +273,22 @@ def print_history(stats):
print('') print('')
print('History of a plugin::') print('History of a plugin::')
print('') print('')
print(' # curl {}/cpu/history'.format(API_URL)) print(f' # curl {API_URL}/cpu/history')
print(indent_stat(json.loads(stats.get_plugin('cpu').get_stats_history(nb=3)))) print(indent_stat(json.loads(stats.get_plugin('cpu').get_stats_history(nb=3))))
print('') print('')
print('Limit history to last 2 values::') print('Limit history to last 2 values::')
print('') print('')
print(' # curl {}/cpu/history/2'.format(API_URL)) print(f' # curl {API_URL}/cpu/history/2')
print(indent_stat(json.loads(stats.get_plugin('cpu').get_stats_history(nb=2)))) print(indent_stat(json.loads(stats.get_plugin('cpu').get_stats_history(nb=2))))
print('') print('')
print('History for a specific field::') print('History for a specific field::')
print('') print('')
print(' # curl {}/cpu/system/history'.format(API_URL)) print(f' # curl {API_URL}/cpu/system/history')
print(indent_stat(json.loads(stats.get_plugin('cpu').get_stats_history('system')))) print(indent_stat(json.loads(stats.get_plugin('cpu').get_stats_history('system'))))
print('') print('')
print('Limit history for a specific field to last 2 values::') print('Limit history for a specific field to last 2 values::')
print('') print('')
print(' # curl {}/cpu/system/history'.format(API_URL)) print(f' # curl {API_URL}/cpu/system/history')
print(indent_stat(json.loads(stats.get_plugin('cpu').get_stats_history('system', nb=2)))) print(indent_stat(json.loads(stats.get_plugin('cpu').get_stats_history('system', nb=2))))
print('') print('')
@ -301,17 +300,17 @@ def print_limits(stats):
print('') print('')
print('All limits/thresholds::') print('All limits/thresholds::')
print('') print('')
print(' # curl {}/all/limits'.format(API_URL)) print(f' # curl {API_URL}/all/limits')
print(indent_stat(stats.getAllLimitsAsDict())) print(indent_stat(stats.getAllLimitsAsDict()))
print('') print('')
print('Limits/thresholds for the cpu plugin::') print('Limits/thresholds for the cpu plugin::')
print('') print('')
print(' # curl {}/cpu/limits'.format(API_URL)) print(f' # curl {API_URL}/cpu/limits')
print(indent_stat(stats.get_plugin('cpu').limits)) print(indent_stat(stats.get_plugin('cpu').limits))
print('') print('')
class GlancesStdoutApiDoc(object): class GlancesStdoutApiDoc:
"""This class manages the fields description display.""" """This class manages the fields description display."""
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -14,7 +13,7 @@ import time
from glances.globals import printandflush from glances.globals import printandflush
class GlancesStdoutCsv(object): class GlancesStdoutCsv:
"""This class manages the StdoutCsv display.""" """This class manages the StdoutCsv display."""
separator = ',' separator = ','
@ -53,18 +52,18 @@ class GlancesStdoutCsv(object):
line = '' line = ''
if attribute is not None: if attribute is not None:
line += '{}.{}{}'.format(plugin, attribute, self.separator) line += f'{plugin}.{attribute}{self.separator}'
else: else:
if isinstance(stat, dict): if isinstance(stat, dict):
for k in stat.keys(): for k in stat.keys():
line += '{}.{}{}'.format(plugin, str(k), self.separator) line += f'{plugin}.{str(k)}{self.separator}'
elif isinstance(stat, list): elif isinstance(stat, list):
for i in stat: for i in stat:
if isinstance(i, dict) and 'key' in i: if isinstance(i, dict) and 'key' in i:
for k in i.keys(): for k in i.keys():
line += '{}.{}.{}{}'.format(plugin, str(i[i['key']]), str(k), self.separator) line += '{}.{}.{}{}'.format(plugin, str(i[i['key']]), str(k), self.separator)
else: else:
line += '{}{}'.format(plugin, self.separator) line += f'{plugin}{self.separator}'
return line return line
@ -73,18 +72,18 @@ class GlancesStdoutCsv(object):
line = '' line = ''
if attribute is not None: if attribute is not None:
line += '{}{}'.format(str(stat.get(attribute, self.na)), self.separator) line += f'{str(stat.get(attribute, self.na))}{self.separator}'
else: else:
if isinstance(stat, dict): if isinstance(stat, dict):
for v in stat.values(): for v in stat.values():
line += '{}{}'.format(str(v), self.separator) line += f'{str(v)}{self.separator}'
elif isinstance(stat, list): elif isinstance(stat, list):
for i in stat: for i in stat:
if isinstance(i, dict) and 'key' in i: if isinstance(i, dict) and 'key' in i:
for v in i.values(): for v in i.values():
line += '{}{}'.format(str(v), self.separator) line += f'{str(v)}{self.separator}'
else: else:
line += '{}{}'.format(str(stat), self.separator) line += f'{str(stat)}{self.separator}'
return line return line

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -39,7 +38,7 @@ class colors:
self.NO = '' self.NO = ''
class GlancesStdoutIssue(object): class GlancesStdoutIssue:
"""This class manages the Issue display.""" """This class manages the Issue display."""
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
@ -52,18 +51,14 @@ class GlancesStdoutIssue(object):
def print_version(self): def print_version(self):
sys.stdout.write('=' * TERMINAL_WIDTH + '\n') sys.stdout.write('=' * TERMINAL_WIDTH + '\n')
sys.stdout.write( sys.stdout.write(f'Glances {colors.BLUE + __version__ + colors.NO} ({os.path.realpath(glances.__file__)})\n')
'Glances {} ({})\n'.format(colors.BLUE + __version__ + colors.NO, os.path.realpath(glances.__file__)) sys.stdout.write(f'Python {colors.BLUE + platform.python_version() + colors.NO} ({sys.executable})\n')
) sys.stdout.write(f'PsUtil {colors.BLUE + psutil_version + colors.NO} ({os.path.realpath(psutil.__file__)})\n')
sys.stdout.write('Python {} ({})\n'.format(colors.BLUE + platform.python_version() + colors.NO, sys.executable))
sys.stdout.write(
'PsUtil {} ({})\n'.format(colors.BLUE + psutil_version + colors.NO, os.path.realpath(psutil.__file__))
)
sys.stdout.write('=' * TERMINAL_WIDTH + '\n') sys.stdout.write('=' * TERMINAL_WIDTH + '\n')
sys.stdout.flush() sys.stdout.flush()
def print_issue(self, plugin, result, message): def print_issue(self, plugin, result, message):
sys.stdout.write('{}{}{}'.format(colors.BLUE + plugin, result, message)) sys.stdout.write(f'{colors.BLUE + plugin}{result}{message}')
sys.stdout.write(colors.NO + '\n') sys.stdout.write(colors.NO + '\n')
sys.stdout.flush() sys.stdout.flush()
@ -108,9 +103,7 @@ class GlancesStdoutIssue(object):
except Exception as e: except Exception as e:
stat_error = e stat_error = e
if stat_error is None: if stat_error is None:
result = (colors.GREEN + '[OK] ' + colors.BLUE + ' {:.5f}s '.format(counter.get())).rjust( result = (colors.GREEN + '[OK] ' + colors.BLUE + f' {counter.get():.5f}s ').rjust(41 - len(plugin))
41 - len(plugin)
)
if isinstance(stat, list) and len(stat) > 0 and 'key' in stat[0]: if isinstance(stat, list) and len(stat) > 0 and 'key' in stat[0]:
key = 'key={} '.format(stat[0]['key']) key = 'key={} '.format(stat[0]['key'])
stat_output = pprint.pformat([stat[0]], compact=True, width=120, depth=3) stat_output = pprint.pformat([stat[0]], compact=True, width=120, depth=3)
@ -118,9 +111,7 @@ class GlancesStdoutIssue(object):
else: else:
message = '\n' + colors.NO + pprint.pformat(stat, compact=True, width=120, depth=2) message = '\n' + colors.NO + pprint.pformat(stat, compact=True, width=120, depth=2)
else: else:
result = (colors.RED + '[ERROR]' + colors.BLUE + ' {:.5f}s '.format(counter.get())).rjust( result = (colors.RED + '[ERROR]' + colors.BLUE + f' {counter.get():.5f}s ').rjust(41 - len(plugin))
41 - len(plugin)
)
message = colors.NO + str(stat_error)[0 : TERMINAL_WIDTH - 41] message = colors.NO + str(stat_error)[0 : TERMINAL_WIDTH - 41]
# Display the result # Display the result
@ -128,7 +119,7 @@ class GlancesStdoutIssue(object):
# Display total time need to update all plugins # Display total time need to update all plugins
sys.stdout.write('=' * TERMINAL_WIDTH + '\n') sys.stdout.write('=' * TERMINAL_WIDTH + '\n')
print("Total time to update all stats: {}{:.5f}s{}".format(colors.BLUE, counter_total.get(), colors.NO)) print(f"Total time to update all stats: {colors.BLUE}{counter_total.get():.5f}s{colors.NO}")
sys.stdout.write('=' * TERMINAL_WIDTH + '\n') sys.stdout.write('=' * TERMINAL_WIDTH + '\n')
# Return True to exit directly (no refresh) # Return True to exit directly (no refresh)

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -14,7 +13,7 @@ import time
from glances.globals import printandflush from glances.globals import printandflush
class GlancesStdoutJson(object): class GlancesStdoutJson:
"""This class manages the Stdout JSON display.""" """This class manages the Stdout JSON display."""
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
@ -47,7 +46,7 @@ class GlancesStdoutJson(object):
else: else:
continue continue
# Display stats # Display stats
printandflush('{}: {}'.format(plugin, stat)) printandflush(f'{plugin}: {stat}')
# Wait until next refresh # Wait until next refresh
if duration > 0: if duration > 0:

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -9,19 +8,19 @@
"""Manage password.""" """Manage password."""
import builtins
import getpass import getpass
import hashlib import hashlib
import os import os
import sys import sys
import uuid import uuid
from io import open
from glances.config import user_config_dir from glances.config import user_config_dir
from glances.globals import b, safe_makedirs, weak_lru_cache from glances.globals import b, safe_makedirs, weak_lru_cache
from glances.logger import logger from glances.logger import logger
class GlancesPassword(object): class GlancesPassword:
"""This class contains all the methods relating to password.""" """This class contains all the methods relating to password."""
def __init__(self, username='glances', config=None): def __init__(self, username='glances', config=None):
@ -77,7 +76,7 @@ class GlancesPassword(object):
""" """
if os.path.exists(self.password_file) and not clear: if os.path.exists(self.password_file) and not clear:
# If the password file exist then use it # If the password file exist then use it
logger.info("Read password from file {}".format(self.password_file)) logger.info(f"Read password from file {self.password_file}")
password = self.load_password() password = self.load_password()
else: else:
# password_hash is the plain SHA-pbkdf2_hmac password # password_hash is the plain SHA-pbkdf2_hmac password
@ -112,11 +111,11 @@ class GlancesPassword(object):
safe_makedirs(self.password_dir) safe_makedirs(self.password_dir)
# Create/overwrite the password file # Create/overwrite the password file
with open(self.password_file, 'wb') as file_pwd: with builtins.open(self.password_file, 'wb') as file_pwd:
file_pwd.write(b(hashed_password)) file_pwd.write(b(hashed_password))
def load_password(self): def load_password(self):
"""Load the hashed password from the Glances folder.""" """Load the hashed password from the Glances folder."""
# Read the password file, if it exists # Read the password file, if it exists
with open(self.password_file, 'r') as file_pwd: with builtins.open(self.password_file) as file_pwd:
return file_pwd.read() return file_pwd.read()

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -19,7 +18,7 @@ class GlancesPasswordList(GlancesPassword):
_section = "passwords" _section = "passwords"
def __init__(self, config=None, args=None): def __init__(self, config=None, args=None):
super(GlancesPasswordList, self).__init__() super().__init__()
# password_dict is a dict (JSON compliant) # password_dict is a dict (JSON compliant)
# {'host': 'password', ... } # {'host': 'password', ... }
# Load the configuration file # Load the configuration file
@ -32,14 +31,14 @@ class GlancesPasswordList(GlancesPassword):
if config is None: if config is None:
logger.warning("No configuration file available. Cannot load password list.") logger.warning("No configuration file available. Cannot load password list.")
elif not config.has_section(self._section): elif not config.has_section(self._section):
logger.warning("No [%s] section in the configuration file. Cannot load password list." % self._section) logger.warning(f"No [{self._section}] section in the configuration file. Cannot load password list.")
else: else:
logger.info("Start reading the [%s] section in the configuration file" % self._section) logger.info(f"Start reading the [{self._section}] section in the configuration file")
password_dict = dict(config.items(self._section)) password_dict = dict(config.items(self._section))
# Password list loaded # Password list loaded
logger.info("%s password(s) loaded from the configuration file" % len(password_dict)) logger.info(f"{len(password_dict)} password(s) loaded from the configuration file")
return password_dict return password_dict

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -101,9 +100,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__( super().__init__(args=args, config=config, stats_init_value=[], fields_description=fields_description)
args=args, config=config, stats_init_value=[], fields_description=fields_description
)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
self.display_curse = True self.display_curse = True
@ -174,7 +171,7 @@ class PluginModel(GlancesPluginModel):
# Top processes # Top processes
top_process = ', '.join(alert['top']) top_process = ', '.join(alert['top'])
if top_process != '': if top_process != '':
msg = ': {}'.format(top_process) msg = f': {top_process}'
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
return ret return ret

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -35,9 +34,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__( super().__init__(args=args, config=config, stats_init_value=[], fields_description=fields_description)
args=args, config=config, stats_init_value=[], fields_description=fields_description
)
self.args = args self.args = args
self.config = config self.config = config
@ -119,10 +116,10 @@ class PluginModel(GlancesPluginModel):
second_column = '{}'.format(m['count'] if m['regex'] else '') second_column = '{}'.format(m['count'] if m['regex'] else '')
for line in m['result'].split('\n'): for line in m['result'].split('\n'):
# Display first column with the process name... # Display first column with the process name...
msg = '{:<16} '.format(first_column) msg = f'{first_column:<16} '
ret.append(self.curse_add_line(msg, first_column_style)) ret.append(self.curse_add_line(msg, first_column_style))
# ... and second column with the number of matching processes... # ... and second column with the number of matching processes...
msg = '{:<4} '.format(second_column) msg = f'{second_column:<4} '
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
# ... only on the first line # ... only on the first line
first_column = second_column = '' first_column = second_column = ''

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -26,7 +25,7 @@ try:
except ImportError as e: except ImportError as e:
import_error_tag = True import_error_tag = True
# Display debug message if import error # Display debug message if import error
logger.warning("Missing Python Lib ({}), Cloud plugin is disabled".format(e)) logger.warning(f"Missing Python Lib ({e}), Cloud plugin is disabled")
else: else:
import_error_tag = False import_error_tag = False
@ -44,7 +43,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config) super().__init__(args=args, config=config)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
self.display_curse = True self.display_curse = True
@ -65,7 +64,7 @@ class PluginModel(GlancesPluginModel):
self.OPENSTACK.stop() self.OPENSTACK.stop()
self.OPENSTACKEC2.stop() self.OPENSTACKEC2.stop()
# Call the father class # Call the father class
super(PluginModel, self).exit() super().exit()
@GlancesPluginModel._check_decorator @GlancesPluginModel._check_decorator
@GlancesPluginModel._log_result_decorator @GlancesPluginModel._log_result_decorator
@ -145,7 +144,7 @@ class ThreadOpenStack(threading.Thread):
def __init__(self): def __init__(self):
"""Init the class.""" """Init the class."""
logger.debug("cloud plugin - Create thread for OpenStack metadata") logger.debug("cloud plugin - Create thread for OpenStack metadata")
super(ThreadOpenStack, self).__init__() super().__init__()
# Event needed to stop properly the thread # Event needed to stop properly the thread
self._stopper = threading.Event() self._stopper = threading.Event()
# The class return the stats as a dict # The class return the stats as a dict
@ -161,12 +160,12 @@ class ThreadOpenStack(threading.Thread):
return False return False
for k, v in iteritems(self.OPENSTACK_API_METADATA): for k, v in iteritems(self.OPENSTACK_API_METADATA):
r_url = '{}/{}'.format(self.OPENSTACK_API_URL, v) r_url = f'{self.OPENSTACK_API_URL}/{v}'
try: try:
# Local request, a timeout of 3 seconds is OK # Local request, a timeout of 3 seconds is OK
r = requests.get(r_url, timeout=3) r = requests.get(r_url, timeout=3)
except Exception as e: except Exception as e:
logger.debug('cloud plugin - Cannot connect to the OpenStack metadata API {}: {}'.format(r_url, e)) logger.debug(f'cloud plugin - Cannot connect to the OpenStack metadata API {r_url}: {e}')
break break
else: else:
if r.ok: if r.ok:

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -9,8 +8,6 @@
"""Connections plugin.""" """Connections plugin."""
from __future__ import unicode_literals
import psutil import psutil
from glances.globals import nativestr from glances.globals import nativestr
@ -94,7 +91,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__( super().__init__(
args=args, args=args,
config=config, config=config,
# items_history_list=items_history_list, # items_history_list=items_history_list,
@ -123,7 +120,7 @@ class PluginModel(GlancesPluginModel):
try: try:
net_connections = psutil.net_connections(kind="tcp") net_connections = psutil.net_connections(kind="tcp")
except Exception as e: except Exception as e:
logger.warning('Can not get network connections stats ({})'.format(e)) logger.warning(f'Can not get network connections stats ({e})')
logger.info('Disable connections stats') logger.info('Disable connections stats')
stats['net_connections_enabled'] = False stats['net_connections_enabled'] = False
self.stats = stats self.stats = stats
@ -146,10 +143,10 @@ class PluginModel(GlancesPluginModel):
# Grab connections track directly from the /proc file # Grab connections track directly from the /proc file
for i in self.conntrack: for i in self.conntrack:
try: try:
with open(self.conntrack[i], 'r') as f: with open(self.conntrack[i]) as f:
stats[i] = float(f.readline().rstrip("\n")) stats[i] = float(f.readline().rstrip("\n"))
except (IOError, FileNotFoundError) as e: except (OSError, FileNotFoundError) as e:
logger.warning('Can not get network connections track ({})'.format(e)) logger.warning(f'Can not get network connections track ({e})')
logger.info('Disable connections track') logger.info('Disable connections track')
stats['nf_conntrack_enabled'] = False stats['nf_conntrack_enabled'] = False
self.stats = stats self.stats = stats
@ -172,7 +169,7 @@ class PluginModel(GlancesPluginModel):
def update_views(self): def update_views(self):
"""Update stats views.""" """Update stats views."""
# Call the father's method # Call the father's method
super(PluginModel, self).update_views() super().update_views()
# Add specific information # Add specific information
try: try:

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -127,7 +126,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__( super().__init__(
args=args, config=config, items_history_list=items_history_list, fields_description=fields_description args=args, config=config, items_history_list=items_history_list, fields_description=fields_description
) )
@ -173,7 +172,7 @@ class PluginModel(GlancesPluginModel):
if self.podman_extension: if self.podman_extension:
self.podman_extension.stop() self.podman_extension.stop()
# Call the father class # Call the father class
super(PluginModel, self).exit() super().exit()
def get_key(self): def get_key(self):
"""Return the key of the list.""" """Return the key of the list."""
@ -188,7 +187,7 @@ class PluginModel(GlancesPluginModel):
try: try:
ret = deepcopy(self.stats) ret = deepcopy(self.stats)
except KeyError as e: except KeyError as e:
logger.debug("docker plugin - Docker export error {}".format(e)) logger.debug(f"docker plugin - Docker export error {e}")
ret = [] ret = []
# Remove fields uses to compute rate # Remove fields uses to compute rate
@ -260,7 +259,7 @@ class PluginModel(GlancesPluginModel):
def update_views(self): def update_views(self):
"""Update stats views.""" """Update stats views."""
# Call the father's method # Call the father's method
super(PluginModel, self).update_views() super().update_views()
if not self.stats: if not self.stats:
return False return False
@ -319,9 +318,9 @@ class PluginModel(GlancesPluginModel):
# Title # Title
msg = '{}'.format('CONTAINERS') msg = '{}'.format('CONTAINERS')
ret.append(self.curse_add_line(msg, "TITLE")) ret.append(self.curse_add_line(msg, "TITLE"))
msg = ' {}'.format(len(self.stats)) msg = f' {len(self.stats)}'
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
msg = ' sorted by {}'.format(sort_for_human[self.sort_key]) msg = f' sorted by {sort_for_human[self.sort_key]}'
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
ret.append(self.curse_new_line()) ret.append(self.curse_new_line())
# Header # Header
@ -402,13 +401,13 @@ class PluginModel(GlancesPluginModel):
unit = 'B' unit = 'B'
try: try:
value = self.auto_unit(int(container['io_rx'])) + unit value = self.auto_unit(int(container['io_rx'])) + unit
msg = '{:>7}'.format(value) msg = f'{value:>7}'
except (KeyError, TypeError): except (KeyError, TypeError):
msg = '{:>7}'.format('_') msg = '{:>7}'.format('_')
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
try: try:
value = self.auto_unit(int(container['io_wx'])) + unit value = self.auto_unit(int(container['io_wx'])) + unit
msg = ' {:<7}'.format(value) msg = f' {value:<7}'
except (KeyError, TypeError): except (KeyError, TypeError):
msg = ' {:<7}'.format('_') msg = ' {:<7}'.format('_')
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
@ -423,13 +422,13 @@ class PluginModel(GlancesPluginModel):
unit = 'b' unit = 'b'
try: try:
value = self.auto_unit(int(container['network_rx'] * to_bit)) + unit value = self.auto_unit(int(container['network_rx'] * to_bit)) + unit
msg = '{:>7}'.format(value) msg = f'{value:>7}'
except (KeyError, TypeError): except (KeyError, TypeError):
msg = '{:>7}'.format('_') msg = '{:>7}'.format('_')
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
try: try:
value = self.auto_unit(int(container['network_tx'] * to_bit)) + unit value = self.auto_unit(int(container['network_tx'] * to_bit)) + unit
msg = ' {:<7}'.format(value) msg = f' {value:<7}'
except (KeyError, TypeError): except (KeyError, TypeError):
msg = ' {:<7}'.format('_') msg = ' {:<7}'.format('_')
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -24,7 +23,7 @@ try:
except Exception as e: except Exception as e:
import_docker_error_tag = True import_docker_error_tag = True
# Display debug message if import KeyError # Display debug message if import KeyError
logger.warning("Error loading Docker deps Lib. Docker plugin is disabled ({})".format(e)) logger.warning(f"Error loading Docker deps Lib. Docker plugin is disabled ({e})")
else: else:
import_docker_error_tag = False import_docker_error_tag = False
@ -47,7 +46,7 @@ class DockerStatsFetcher:
self._streamer = StatsStreamer(stats_iterable, initial_stream_value={}) self._streamer = StatsStreamer(stats_iterable, initial_stream_value={})
def _log_debug(self, msg, exception=None): def _log_debug(self, msg, exception=None):
logger.debug("containers (Docker) ID: {} - {} ({}) ".format(self._container.id, msg, exception)) logger.debug(f"containers (Docker) ID: {self._container.id} - {msg} ({exception}) ")
logger.debug(self._streamer.stats) logger.debug(self._streamer.stats)
def stop(self): def stop(self):
@ -229,7 +228,7 @@ class DockerContainersExtension:
# Do not use the timeout option (see issue #1878) # Do not use the timeout option (see issue #1878)
self.client = docker.from_env() self.client = docker.from_env()
except Exception as e: except Exception as e:
logger.error("{} plugin - Can't connect to Docker ({})".format(self.ext_name, e)) logger.error(f"{self.ext_name} plugin - Can't connect to Docker ({e})")
self.client = None self.client = None
def update_version(self): def update_version(self):
@ -256,7 +255,7 @@ class DockerContainersExtension:
# The Containers/all key of the configuration file should be set to True # The Containers/all key of the configuration file should be set to True
containers = self.client.containers.list(all=all_tag) containers = self.client.containers.list(all=all_tag)
except Exception as e: except Exception as e:
logger.error("{} plugin - Can't get containers list ({})".format(self.ext_name, e)) logger.error(f"{self.ext_name} plugin - Can't get containers list ({e})")
return version_stats, [] return version_stats, []
# Start new thread for new container # Start new thread for new container
@ -264,14 +263,14 @@ class DockerContainersExtension:
if container.id not in self.stats_fetchers: if container.id not in self.stats_fetchers:
# StatsFetcher did not exist in the internal dict # StatsFetcher did not exist in the internal dict
# Create it, add it to the internal dict # Create it, add it to the internal dict
logger.debug("{} plugin - Create thread for container {}".format(self.ext_name, container.id[:12])) logger.debug(f"{self.ext_name} plugin - Create thread for container {container.id[:12]}")
self.stats_fetchers[container.id] = DockerStatsFetcher(container) self.stats_fetchers[container.id] = DockerStatsFetcher(container)
# Stop threads for non-existing containers # Stop threads for non-existing containers
absent_containers = set(iterkeys(self.stats_fetchers)) - set(c.id for c in containers) absent_containers = set(iterkeys(self.stats_fetchers)) - set(c.id for c in containers)
for container_id in absent_containers: for container_id in absent_containers:
# Stop the StatsFetcher # Stop the StatsFetcher
logger.debug("{} plugin - Stop thread for old container {}".format(self.ext_name, container_id[:12])) logger.debug(f"{self.ext_name} plugin - Stop thread for old container {container_id[:12]}")
self.stats_fetchers[container_id].stop() self.stats_fetchers[container_id].stop()
# Delete the StatsFetcher from the dict # Delete the StatsFetcher from the dict
del self.stats_fetchers[container_id] del self.stats_fetchers[container_id]

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -21,7 +20,7 @@ try:
except Exception as e: except Exception as e:
import_podman_error_tag = True import_podman_error_tag = True
# Display debug message if import KeyError # Display debug message if import KeyError
logger.warning("Error loading Podman deps Lib. Podman feature in the Containers plugin is disabled ({})".format(e)) logger.warning(f"Error loading Podman deps Lib. Podman feature in the Containers plugin is disabled ({e})")
else: else:
import_podman_error_tag = False import_podman_error_tag = False
@ -37,7 +36,7 @@ class PodmanContainerStatsFetcher:
self._streamer = StatsStreamer(stats_iterable, initial_stream_value={}) self._streamer = StatsStreamer(stats_iterable, initial_stream_value={})
def _log_debug(self, msg, exception=None): def _log_debug(self, msg, exception=None):
logger.debug("containers (Podman) ID: {} - {} ({})".format(self._container.id, msg, exception)) logger.debug(f"containers (Podman) ID: {self._container.id} - {msg} ({exception})")
logger.debug(self._streamer.stats) logger.debug(self._streamer.stats)
def stop(self): def stop(self):
@ -96,7 +95,7 @@ class PodmanPodStatsFetcher:
self._streamer = StatsStreamer(stats_iterable, initial_stream_value={}, sleep_duration=2) self._streamer = StatsStreamer(stats_iterable, initial_stream_value={}, sleep_duration=2)
def _log_debug(self, msg, exception=None): def _log_debug(self, msg, exception=None):
logger.debug("containers (Podman): Pod Manager - {} ({})".format(msg, exception)) logger.debug(f"containers (Podman): Pod Manager - {msg} ({exception})")
logger.debug(self._streamer.stats) logger.debug(self._streamer.stats)
def stop(self): def stop(self):
@ -235,7 +234,7 @@ class PodmanContainersExtension:
# PodmanClient works lazily, so make a ping to determine if socket is open # PodmanClient works lazily, so make a ping to determine if socket is open
self.client.ping() self.client.ping()
except Exception as e: except Exception as e:
logger.debug("{} plugin - Can't connect to Podman ({})".format(self.ext_name, e)) logger.debug(f"{self.ext_name} plugin - Can't connect to Podman ({e})")
self.client = None self.client = None
def update_version(self): def update_version(self):
@ -267,7 +266,7 @@ class PodmanContainersExtension:
if not self.pods_stats_fetcher: if not self.pods_stats_fetcher:
self.pods_stats_fetcher = PodmanPodStatsFetcher(self.client.pods) self.pods_stats_fetcher = PodmanPodStatsFetcher(self.client.pods)
except Exception as e: except Exception as e:
logger.error("{} plugin - Can't get containers list ({})".format(self.ext_name, e)) logger.error(f"{self.ext_name} plugin - Can't get containers list ({e})")
return version_stats, [] return version_stats, []
# Start new thread for new container # Start new thread for new container
@ -275,14 +274,14 @@ class PodmanContainersExtension:
if container.id not in self.container_stats_fetchers: if container.id not in self.container_stats_fetchers:
# StatsFetcher did not exist in the internal dict # StatsFetcher did not exist in the internal dict
# Create it, add it to the internal dict # Create it, add it to the internal dict
logger.debug("{} plugin - Create thread for container {}".format(self.ext_name, container.id[:12])) logger.debug(f"{self.ext_name} plugin - Create thread for container {container.id[:12]}")
self.container_stats_fetchers[container.id] = PodmanContainerStatsFetcher(container) self.container_stats_fetchers[container.id] = PodmanContainerStatsFetcher(container)
# Stop threads for non-existing containers # Stop threads for non-existing containers
absent_containers = set(iterkeys(self.container_stats_fetchers)) - set(c.id for c in containers) absent_containers = set(iterkeys(self.container_stats_fetchers)) - set(c.id for c in containers)
for container_id in absent_containers: for container_id in absent_containers:
# Stop the StatsFetcher # Stop the StatsFetcher
logger.debug("{} plugin - Stop thread for old container {}".format(self.ext_name, container_id[:12])) logger.debug(f"{self.ext_name} plugin - Stop thread for old container {container_id[:12]}")
self.container_stats_fetchers[container_id].stop() self.container_stats_fetchers[container_id].stop()
# Delete the StatsFetcher from the dict # Delete the StatsFetcher from the dict
del self.container_stats_fetchers[container_id] del self.container_stats_fetchers[container_id]

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -63,7 +62,7 @@ class StatsStreamer:
break break
except Exception as e: except Exception as e:
logger.debug("docker plugin - Exception thrown during run ({})".format(e)) logger.debug(f"docker plugin - Exception thrown during run ({e})")
self.stop() self.stop()
def _pre_update_hook(self): def _pre_update_hook(self):

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -34,7 +33,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config, fields_description=fields_description) super().__init__(args=args, config=config, fields_description=fields_description)
# We dot not want to display the stat in the curse interface # We dot not want to display the stat in the curse interface
# The core number is displayed by the load plugin # The core number is displayed by the load plugin

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -144,7 +143,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the CPU plugin.""" """Init the CPU plugin."""
super(PluginModel, self).__init__( super().__init__(
args=args, config=config, items_history_list=items_history_list, fields_description=fields_description args=args, config=config, items_history_list=items_history_list, fields_description=fields_description
) )
@ -273,7 +272,7 @@ class PluginModel(GlancesPluginModel):
def update_views(self): def update_views(self):
"""Update stats views.""" """Update stats views."""
# Call the father's method # Call the father's method
super(PluginModel, self).update_views() super().update_views()
# Add specifics information # Add specifics information
# Alert and log # Alert and log

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -9,8 +8,6 @@
"""Disk I/O plugin.""" """Disk I/O plugin."""
from __future__ import unicode_literals
import psutil import psutil
from glances.globals import nativestr from glances.globals import nativestr
@ -62,7 +59,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__( super().__init__(
args=args, args=args,
config=config, config=config,
items_history_list=items_history_list, items_history_list=items_history_list,
@ -142,7 +139,7 @@ class PluginModel(GlancesPluginModel):
def update_views(self): def update_views(self):
"""Update stats views.""" """Update stats views."""
# Call the father's method # Call the father's method
super(PluginModel, self).update_views() super().update_views()
# Check if the stats should be hidden # Check if the stats should be hidden
self.update_views_hidden() self.update_views_hidden()
@ -172,7 +169,7 @@ class PluginModel(GlancesPluginModel):
name_max_width = max_width - 13 name_max_width = max_width - 13
else: else:
# No max_width defined, return an emptu curse message # No max_width defined, return an emptu curse message
logger.debug("No max_width defined for the {} plugin, it will not be displayed.".format(self.plugin_name)) logger.debug(f"No max_width defined for the {self.plugin_name} plugin, it will not be displayed.")
return ret return ret
# Header # Header
@ -206,13 +203,13 @@ class PluginModel(GlancesPluginModel):
# count # count
txps = self.auto_unit(i.get('read_count_rate_per_sec', None)) txps = self.auto_unit(i.get('read_count_rate_per_sec', None))
rxps = self.auto_unit(i.get('write_count_rate_per_sec', None)) rxps = self.auto_unit(i.get('write_count_rate_per_sec', None))
msg = '{:>7}'.format(txps) msg = f'{txps:>7}'
ret.append( ret.append(
self.curse_add_line( self.curse_add_line(
msg, self.get_views(item=i[self.get_key()], key='read_count', option='decoration') msg, self.get_views(item=i[self.get_key()], key='read_count', option='decoration')
) )
) )
msg = '{:>7}'.format(rxps) msg = f'{rxps:>7}'
ret.append( ret.append(
self.curse_add_line( self.curse_add_line(
msg, self.get_views(item=i[self.get_key()], key='write_count', option='decoration') msg, self.get_views(item=i[self.get_key()], key='write_count', option='decoration')
@ -222,13 +219,13 @@ class PluginModel(GlancesPluginModel):
# Bitrate # Bitrate
txps = self.auto_unit(i.get('read_bytes_rate_per_sec', None)) txps = self.auto_unit(i.get('read_bytes_rate_per_sec', None))
rxps = self.auto_unit(i.get('write_bytes_rate_per_sec', None)) rxps = self.auto_unit(i.get('write_bytes_rate_per_sec', None))
msg = '{:>7}'.format(txps) msg = f'{txps:>7}'
ret.append( ret.append(
self.curse_add_line( self.curse_add_line(
msg, self.get_views(item=i[self.get_key()], key='read_bytes', option='decoration') msg, self.get_views(item=i[self.get_key()], key='read_bytes', option='decoration')
) )
) )
msg = '{:>7}'.format(rxps) msg = f'{rxps:>7}'
ret.append( ret.append(
self.curse_add_line( self.curse_add_line(
msg, self.get_views(item=i[self.get_key()], key='write_bytes', option='decoration') msg, self.get_views(item=i[self.get_key()], key='write_bytes', option='decoration')

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -9,8 +8,6 @@
"""Folder plugin.""" """Folder plugin."""
from __future__ import unicode_literals
from glances.folder_list import FolderList as glancesFolderList from glances.folder_list import FolderList as glancesFolderList
from glances.globals import nativestr from glances.globals import nativestr
from glances.logger import logger from glances.logger import logger
@ -56,9 +53,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__( super().__init__(args=args, config=config, stats_init_value=[], fields_description=fields_description)
args=args, config=config, stats_init_value=[], fields_description=fields_description
)
self.args = args self.args = args
self.config = config self.config = config
@ -138,7 +133,7 @@ class PluginModel(GlancesPluginModel):
name_max_width = max_width - 7 name_max_width = max_width - 7
else: else:
# No max_width defined, return an emptu curse message # No max_width defined, return an emptu curse message
logger.debug("No max_width defined for the {} plugin, it will not be displayed.".format(self.plugin_name)) logger.debug(f"No max_width defined for the {self.plugin_name} plugin, it will not be displayed.")
return ret return ret
# Header # Header

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -9,8 +8,6 @@
"""File system plugin.""" """File system plugin."""
from __future__ import unicode_literals
import operator import operator
import psutil import psutil
@ -98,7 +95,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__( super().__init__(
args=args, args=args,
config=config, config=config,
items_history_list=items_history_list, items_history_list=items_history_list,
@ -241,7 +238,7 @@ class PluginModel(GlancesPluginModel):
def update_views(self): def update_views(self):
"""Update stats views.""" """Update stats views."""
# Call the father's method # Call the father's method
super(PluginModel, self).update_views() super().update_views()
# Add specifics information # Add specifics information
# Alert # Alert
@ -264,7 +261,7 @@ class PluginModel(GlancesPluginModel):
name_max_width = max_width - 13 name_max_width = max_width - 13
else: else:
# No max_width defined, return an emptu curse message # No max_width defined, return an emptu curse message
logger.debug("No max_width defined for the {} plugin, it will not be displayed.".format(self.plugin_name)) logger.debug(f"No max_width defined for the {self.plugin_name} plugin, it will not be displayed.")
return ret return ret
# Build the string message # Build the string message

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -67,7 +66,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__( super().__init__(
args=args, args=args,
config=config, config=config,
items_history_list=items_history_list, items_history_list=items_history_list,
@ -89,7 +88,7 @@ class PluginModel(GlancesPluginModel):
self.amd.exit() self.amd.exit()
# Call the father exit method # Call the father exit method
super(PluginModel, self).exit() super().exit()
def get_key(self): def get_key(self):
"""Return the key of the list.""" """Return the key of the list."""
@ -150,7 +149,7 @@ class PluginModel(GlancesPluginModel):
def update_views(self): def update_views(self):
"""Update stats views.""" """Update stats views."""
# Call the father's method # Call the father's method
super(PluginModel, self).update_views() super().update_views()
# Add specifics information # Add specifics information
# Alert # Alert
@ -190,7 +189,7 @@ class PluginModel(GlancesPluginModel):
# Header # Header
header = '' header = ''
if len(self.stats) > 1: if len(self.stats) > 1:
header += '{}'.format(len(self.stats)) header += f'{len(self.stats)}'
if same_name: if same_name:
header += ' {}'.format(gpu_stats['name']) header += ' {}'.format(gpu_stats['name'])
else: else:
@ -213,7 +212,7 @@ class PluginModel(GlancesPluginModel):
except TypeError: except TypeError:
mean_proc_msg = '{:>4}'.format('N/A') mean_proc_msg = '{:>4}'.format('N/A')
else: else:
mean_proc_msg = '{:>3.0f}%'.format(mean_proc) mean_proc_msg = f'{mean_proc:>3.0f}%'
if len(self.stats) > 1: if len(self.stats) > 1:
msg = '{:13}'.format('proc mean:') msg = '{:13}'.format('proc mean:')
else: else:
@ -232,7 +231,7 @@ class PluginModel(GlancesPluginModel):
except TypeError: except TypeError:
mean_mem_msg = '{:>4}'.format('N/A') mean_mem_msg = '{:>4}'.format('N/A')
else: else:
mean_mem_msg = '{:>3.0f}%'.format(mean_mem) mean_mem_msg = f'{mean_mem:>3.0f}%'
if len(self.stats) > 1: if len(self.stats) > 1:
msg = '{:13}'.format('mem mean:') msg = '{:13}'.format('mem mean:')
else: else:
@ -255,7 +254,7 @@ class PluginModel(GlancesPluginModel):
if args.fahrenheit: if args.fahrenheit:
mean_temperature = to_fahrenheit(mean_temperature) mean_temperature = to_fahrenheit(mean_temperature)
unit = 'F' unit = 'F'
mean_temperature_msg = '{:>3.0f}{}'.format(mean_temperature, unit) mean_temperature_msg = f'{mean_temperature:>3.0f}{unit}'
if len(self.stats) > 1: if len(self.stats) > 1:
msg = '{:13}'.format('temp mean:') msg = '{:13}'.format('temp mean:')
else: else:
@ -283,7 +282,7 @@ class PluginModel(GlancesPluginModel):
mem_msg = '{:>3.0f}%'.format(gpu_stats['mem']) mem_msg = '{:>3.0f}%'.format(gpu_stats['mem'])
except (ValueError, TypeError): except (ValueError, TypeError):
mem_msg = '{:>4}'.format('N/A') mem_msg = '{:>4}'.format('N/A')
msg = '{} {} mem {}'.format(id_msg, proc_msg, mem_msg) msg = f'{id_msg} {proc_msg} mem {mem_msg}'
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
return ret return ret

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -17,7 +16,7 @@ try:
except Exception as e: except Exception as e:
nvidia_gpu_enable = False nvidia_gpu_enable = False
# Display debug message if import KeyError # Display debug message if import KeyError
logger.warning("Missing Python Lib ({}), Nvidia GPU plugin is disabled".format(e)) logger.warning(f"Missing Python Lib ({e}), Nvidia GPU plugin is disabled")
else: else:
nvidia_gpu_enable = True nvidia_gpu_enable = True
@ -43,7 +42,7 @@ class NvidiaGPU:
try: try:
pynvml.nvmlShutdown() pynvml.nvmlShutdown()
except Exception as e: except Exception as e:
logger.debug("pynvml failed to shutdown correctly ({})".format(e)) logger.debug(f"pynvml failed to shutdown correctly ({e})")
def get_device_stats(self): def get_device_stats(self):
"""Get Nvidia GPU stats.""" """Get Nvidia GPU stats."""

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -13,7 +12,6 @@ Help plugin.
Just a stupid plugin to display the help screen. Just a stupid plugin to display the help screen.
""" """
import sys
from itertools import chain from itertools import chain
from glances import __version__, psutil_version from glances import __version__, psutil_version
@ -26,7 +24,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config) super().__init__(args=args, config=config)
# Set the config instance # Set the config instance
self.config = config self.config = config
@ -36,12 +34,7 @@ class PluginModel(GlancesPluginModel):
self.display_curse = True self.display_curse = True
# init data dictionary, to preserve insertion order # init data dictionary, to preserve insertion order
if sys.version_info < (3, 6): self.view_data = {}
from collections import OrderedDict
self.view_data = OrderedDict()
else:
self.view_data = {}
self.generate_view_data() self.generate_view_data()
def reset(self): def reset(self):
@ -53,10 +46,10 @@ class PluginModel(GlancesPluginModel):
def generate_view_data(self): def generate_view_data(self):
"""Generate the views.""" """Generate the views."""
self.view_data['version'] = '{} {}'.format('Glances', __version__) self.view_data['version'] = '{} {}'.format('Glances', __version__)
self.view_data['psutil_version'] = ' with psutil {}'.format(psutil_version) self.view_data['psutil_version'] = f' with psutil {psutil_version}'
try: try:
self.view_data['configuration_file'] = 'Configuration file: {}'.format(self.config.loaded_config_file) self.view_data['configuration_file'] = f'Configuration file: {self.config.loaded_config_file}'
except AttributeError: except AttributeError:
pass pass

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -23,7 +22,7 @@ try:
import netifaces import netifaces
except ImportError as e: except ImportError as e:
import_error_tag = True import_error_tag = True
logger.warning("Missing Python Lib ({}), IP plugin is disabled".format(e)) logger.warning(f"Missing Python Lib ({e}), IP plugin is disabled")
else: else:
import_error_tag = False import_error_tag = False
@ -66,7 +65,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config, fields_description=fields_description) super().__init__(args=args, config=config, fields_description=fields_description)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
self.display_curse = True self.display_curse = True
@ -104,7 +103,7 @@ class PluginModel(GlancesPluginModel):
try: try:
default_gw = netifaces.gateways()['default'][netifaces.AF_INET] default_gw = netifaces.gateways()['default'][netifaces.AF_INET]
except (KeyError, AttributeError) as e: except (KeyError, AttributeError) as e:
logger.debug("Cannot grab default gateway IP address ({})".format(e)) logger.debug(f"Cannot grab default gateway IP address ({e})")
return self.get_init_value() return self.get_init_value()
else: else:
stats['gateway'] = default_gw[0] stats['gateway'] = default_gw[0]
@ -113,7 +112,7 @@ class PluginModel(GlancesPluginModel):
address = netifaces.ifaddresses(default_gw[1])[netifaces.AF_INET][0]['addr'] address = netifaces.ifaddresses(default_gw[1])[netifaces.AF_INET][0]['addr']
mask = netifaces.ifaddresses(default_gw[1])[netifaces.AF_INET][0]['netmask'] mask = netifaces.ifaddresses(default_gw[1])[netifaces.AF_INET][0]['netmask']
except (KeyError, AttributeError) as e: except (KeyError, AttributeError) as e:
logger.debug("Cannot grab private IP address ({})".format(e)) logger.debug(f"Cannot grab private IP address ({e})")
return self.get_init_value() return self.get_init_value()
else: else:
stats['address'] = address stats['address'] = address
@ -129,7 +128,7 @@ class PluginModel(GlancesPluginModel):
self.public_info = PublicIpInfo(self.public_api, self.public_username, self.public_password).get() self.public_info = PublicIpInfo(self.public_api, self.public_username, self.public_password).get()
self.public_address = self.public_info['ip'] self.public_address = self.public_info['ip']
except (KeyError, AttributeError, TypeError) as e: except (KeyError, AttributeError, TypeError) as e:
logger.debug("Cannot grab public IP information ({})".format(e)) logger.debug(f"Cannot grab public IP information ({e})")
else: else:
stats['public_address'] = ( stats['public_address'] = (
self.public_address if not self.args.hide_public_info else self.__hide_ip(self.public_address) self.public_address if not self.args.hide_public_info else self.__hide_ip(self.public_address)
@ -211,7 +210,7 @@ class PluginModel(GlancesPluginModel):
return sum(bin(int(x)).count('1') for x in ip.split('.')) return sum(bin(int(x)).count('1') for x in ip.split('.'))
class PublicIpInfo(object): class PublicIpInfo:
"""Get public IP information from online service.""" """Get public IP information from online service."""
def __init__(self, url, username, password, timeout=2): def __init__(self, url, username, password, timeout=2):
@ -242,11 +241,11 @@ class PublicIpInfo(object):
try: try:
response = urlopen_auth(url, username, password).read() response = urlopen_auth(url, username, password).read()
except Exception as e: except Exception as e:
logger.debug("IP plugin - Cannot get public IP information from {} ({})".format(url, e)) logger.debug(f"IP plugin - Cannot get public IP information from {url} ({e})")
queue_target.put(None) queue_target.put(None)
else: else:
try: try:
queue_target.put(loads(response)) queue_target.put(loads(response))
except (ValueError, KeyError) as e: except (ValueError, KeyError) as e:
logger.debug("IP plugin - Cannot load public IP information from {} ({})".format(url, e)) logger.debug(f"IP plugin - Cannot load public IP information from {url} ({e})")
queue_target.put(None) queue_target.put(None)

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -42,9 +41,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__( super().__init__(args=args, config=config, stats_init_value=[], fields_description=fields_description)
args=args, config=config, stats_init_value=[], fields_description=fields_description
)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
self.display_curse = True self.display_curse = True
@ -86,7 +83,7 @@ class PluginModel(GlancesPluginModel):
def update_views(self): def update_views(self):
"""Update stats views.""" """Update stats views."""
# Call the father's method # Call the father's method
super(PluginModel, self).update_views() super().update_views()
def msg_curse(self, args=None, max_width=None): def msg_curse(self, args=None, max_width=None):
"""Return the dict to display in the curse interface.""" """Return the dict to display in the curse interface."""
@ -103,7 +100,7 @@ class PluginModel(GlancesPluginModel):
name_max_width = max_width - 7 name_max_width = max_width - 7
else: else:
# No max_width defined, return an emptu curse message # No max_width defined, return an emptu curse message
logger.debug("No max_width defined for the {} plugin, it will not be displayed.".format(self.plugin_name)) logger.debug(f"No max_width defined for the {self.plugin_name} plugin, it will not be displayed.")
return ret return ret
# Build the string message # Build the string message
@ -123,7 +120,7 @@ class PluginModel(GlancesPluginModel):
return ret return ret
class GlancesIRQ(object): class GlancesIRQ:
"""This class manages the IRQ file.""" """This class manages the IRQ file."""
IRQ_FILE = '/proc/interrupts' IRQ_FILE = '/proc/interrupts'
@ -169,7 +166,7 @@ class GlancesIRQ(object):
irq_line = splitted_line[0].replace(':', '') irq_line = splitted_line[0].replace(':', '')
if irq_line.isdigit(): if irq_line.isdigit():
# If the first column is a digit, use the alias (last column) # If the first column is a digit, use the alias (last column)
irq_line += '_{}'.format(splitted_line[-1]) irq_line += f'_{splitted_line[-1]}'
return irq_line return irq_line
def __sum(self, line): def __sum(self, line):
@ -216,7 +213,7 @@ class GlancesIRQ(object):
} }
self.stats.append(irq_current) self.stats.append(irq_current)
self.lasts[irq_line] = current_irqs self.lasts[irq_line] = current_irqs
except (OSError, IOError): except OSError:
pass pass
return self.stats return self.stats

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -66,7 +65,7 @@ nb_phys_core = 1
try: try:
core = CorePluginModel().update() core = CorePluginModel().update()
except Exception as e: except Exception as e:
logger.warning('Error: Can not retrieve the CPU core number (set it to 1) ({})'.format(e)) logger.warning(f'Error: Can not retrieve the CPU core number (set it to 1) ({e})')
else: else:
if 'log' in core: if 'log' in core:
nb_log_core = core['log'] nb_log_core = core['log']
@ -82,7 +81,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__( super().__init__(
args=args, config=config, items_history_list=items_history_list, fields_description=fields_description args=args, config=config, items_history_list=items_history_list, fields_description=fields_description
) )
@ -128,7 +127,7 @@ class PluginModel(GlancesPluginModel):
def update_views(self): def update_views(self):
"""Update stats views.""" """Update stats views."""
# Call the father's method # Call the father's method
super(PluginModel, self).update_views() super().update_views()
# Add specifics information # Add specifics information
try: try:
@ -164,17 +163,17 @@ class PluginModel(GlancesPluginModel):
# Loop over 1min, 5min and 15min load # Loop over 1min, 5min and 15min load
for load_time in ['1', '5', '15']: for load_time in ['1', '5', '15']:
ret.append(self.curse_new_line()) ret.append(self.curse_new_line())
msg = '{:7}'.format('{} min'.format(load_time)) msg = '{:7}'.format(f'{load_time} min')
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
if args.disable_irix and get_nb_log_core() != 0: if args.disable_irix and get_nb_log_core() != 0:
# Enable Irix mode for load (see issue #1554) # Enable Irix mode for load (see issue #1554)
load_stat = self.stats['min{}'.format(load_time)] / get_nb_log_core() * 100 load_stat = self.stats[f'min{load_time}'] / get_nb_log_core() * 100
msg = '{:>5.1f}%'.format(load_stat) msg = f'{load_stat:>5.1f}%'
else: else:
# Default mode for load # Default mode for load
load_stat = self.stats['min{}'.format(load_time)] load_stat = self.stats[f'min{load_time}']
msg = '{:>6.2f}'.format(load_stat) msg = f'{load_stat:>6.2f}'
ret.append(self.curse_add_line(msg, self.get_views(key='min{}'.format(load_time), option='decoration'))) ret.append(self.curse_add_line(msg, self.get_views(key=f'min{load_time}', option='decoration')))
return ret return ret

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -113,7 +112,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__( super().__init__(
args=args, config=config, items_history_list=items_history_list, fields_description=fields_description args=args, config=config, items_history_list=items_history_list, fields_description=fields_description
) )
@ -219,7 +218,7 @@ class PluginModel(GlancesPluginModel):
def update_views(self): def update_views(self):
"""Update stats views.""" """Update stats views."""
# Call the father's method # Call the father's method
super(PluginModel, self).update_views() super().update_views()
# Add specifics information # Add specifics information
# Alert and log # Alert and log

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -60,7 +59,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__( super().__init__(
args=args, config=config, items_history_list=items_history_list, fields_description=fields_description args=args, config=config, items_history_list=items_history_list, fields_description=fields_description
) )
@ -145,7 +144,7 @@ class PluginModel(GlancesPluginModel):
def update_views(self): def update_views(self):
"""Update stats views.""" """Update stats views."""
# Call the father's method # Call the father's method
super(PluginModel, self).update_views() super().update_views()
# Add specifics information # Add specifics information
# Alert and log # Alert and log

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -9,8 +8,6 @@
"""Network plugin.""" """Network plugin."""
from __future__ import unicode_literals
import psutil import psutil
from glances.logger import logger from glances.logger import logger
@ -73,7 +70,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__( super().__init__(
args=args, args=args,
config=config, config=config,
items_history_list=items_history_list, items_history_list=items_history_list,
@ -131,7 +128,7 @@ class PluginModel(GlancesPluginModel):
try: try:
net_io_counters = psutil.net_io_counters(pernic=True) net_io_counters = psutil.net_io_counters(pernic=True)
except UnicodeDecodeError as e: except UnicodeDecodeError as e:
logger.debug('Can not get network interface counters ({})'.format(e)) logger.debug(f'Can not get network interface counters ({e})')
return self.stats return self.stats
# Grab interface's status (issue #765) # Grab interface's status (issue #765)
@ -145,7 +142,7 @@ class PluginModel(GlancesPluginModel):
net_status = psutil.net_if_stats() net_status = psutil.net_if_stats()
except OSError as e: except OSError as e:
# see psutil #797/glances #1106 # see psutil #797/glances #1106
logger.debug('Can not get network interface status ({})'.format(e)) logger.debug(f'Can not get network interface status ({e})')
for interface_name, interface_stat in net_io_counters.items(): for interface_name, interface_stat in net_io_counters.items():
# Do not take hidden interface into account # Do not take hidden interface into account
@ -181,7 +178,7 @@ class PluginModel(GlancesPluginModel):
def update_views(self): def update_views(self):
"""Update stats views.""" """Update stats views."""
# Call the father's method # Call the father's method
super(PluginModel, self).update_views() super().update_views()
# Check if the stats should be hidden # Check if the stats should be hidden
self.update_views_hidden() self.update_views_hidden()
@ -227,7 +224,7 @@ class PluginModel(GlancesPluginModel):
name_max_width = max_width - 12 name_max_width = max_width - 12
else: else:
# No max_width defined, return an emptu curse message # No max_width defined, return an emptu curse message
logger.debug("No max_width defined for the {} plugin, it will not be displayed.".format(self.plugin_name)) logger.debug(f"No max_width defined for the {self.plugin_name} plugin, it will not be displayed.")
return ret return ret
# Header # Header
@ -301,16 +298,16 @@ class PluginModel(GlancesPluginModel):
msg = '{:{width}}'.format(if_name, width=name_max_width) msg = '{:{width}}'.format(if_name, width=name_max_width)
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
if args.network_sum: if args.network_sum:
msg = '{:>14}'.format(ax) msg = f'{ax:>14}'
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
else: else:
msg = '{:>7}'.format(rx) msg = f'{rx:>7}'
ret.append( ret.append(
self.curse_add_line( self.curse_add_line(
msg, self.get_views(item=i[self.get_key()], key='bytes_recv', option='decoration') msg, self.get_views(item=i[self.get_key()], key='bytes_recv', option='decoration')
) )
) )
msg = '{:>7}'.format(tx) msg = f'{tx:>7}'
ret.append( ret.append(
self.curse_add_line( self.curse_add_line(
msg, self.get_views(item=i[self.get_key()], key='bytes_sent', option='decoration') msg, self.get_views(item=i[self.get_key()], key='bytes_sent', option='decoration')

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -38,9 +37,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__( super().__init__(args=args, config=config, fields_description=fields_description, stats_init_value={})
args=args, config=config, fields_description=fields_description, stats_init_value={}
)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
self.display_curse = True self.display_curse = True

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -96,7 +95,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__( super().__init__(
args=args, args=args,
config=config, config=config,
items_history_list=items_history_list, items_history_list=items_history_list,
@ -159,7 +158,7 @@ class PluginModel(GlancesPluginModel):
for stat in header: for stat in header:
if stat not in self.stats[0]: if stat not in self.stats[0]:
continue continue
msg = '{:>7}'.format(stat) msg = f'{stat:>7}'
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
# Manage the maximum number of CPU to display (related to enhancement request #2734) # Manage the maximum number of CPU to display (related to enhancement request #2734)
@ -176,9 +175,9 @@ class PluginModel(GlancesPluginModel):
try: try:
cpu_id = cpu[cpu['key']] cpu_id = cpu[cpu['key']]
if cpu_id < 10: if cpu_id < 10:
msg = 'CPU{:1} '.format(cpu_id) msg = f'CPU{cpu_id:1} '
else: else:
msg = '{:4} '.format(cpu_id) msg = f'{cpu_id:4} '
except TypeError: except TypeError:
# TypeError: string indices must be integers (issue #1027) # TypeError: string indices must be integers (issue #1027)
msg = '{:4} '.format('?') msg = '{:4} '.format('?')
@ -187,7 +186,7 @@ class PluginModel(GlancesPluginModel):
if stat not in self.stats[0]: if stat not in self.stats[0]:
continue continue
try: try:
msg = '{:6.1f}%'.format(cpu[stat]) msg = f'{cpu[stat]:6.1f}%'
except TypeError: except TypeError:
msg = '{:>6}%'.format('?') msg = '{:>6}%'.format('?')
ret.append(self.curse_add_line(msg, self.get_alert(cpu[stat], header=stat))) ret.append(self.curse_add_line(msg, self.get_alert(cpu[stat], header=stat)))
@ -204,7 +203,7 @@ class PluginModel(GlancesPluginModel):
[i[stat] for i in percpu_list[0 : self.max_cpu_display]] [i[stat] for i in percpu_list[0 : self.max_cpu_display]]
) )
try: try:
msg = '{:6.1f}%'.format(cpu_stat) msg = f'{cpu_stat:6.1f}%'
except TypeError: except TypeError:
msg = '{:>6}%'.format('?') msg = '{:>6}%'.format('?')
ret.append(self.curse_add_line(msg, self.get_alert(cpu_stat, header=stat))) ret.append(self.curse_add_line(msg, self.get_alert(cpu_stat, header=stat)))

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -43,7 +42,7 @@ fields_unit_type = {
} }
class GlancesPluginModel(object): class GlancesPluginModel:
"""Main class for Glances plugin model.""" """Main class for Glances plugin model."""
def __init__(self, args=None, config=None, items_history_list=None, stats_init_value={}, fields_description=None): def __init__(self, args=None, config=None, items_history_list=None, stats_init_value={}, fields_description=None):
@ -77,7 +76,7 @@ class GlancesPluginModel(object):
if self.plugin_name.startswith('glances_'): if self.plugin_name.startswith('glances_'):
self.plugin_name = self.plugin_name.split('glances_')[1] self.plugin_name = self.plugin_name.split('glances_')[1]
logger.debug("Init {} plugin".format(self.plugin_name)) logger.debug(f"Init {self.plugin_name} plugin")
# Init the args # Init the args
self.args = args self.args = args
@ -96,7 +95,7 @@ class GlancesPluginModel(object):
# Init the limits (configuration keys) dictionary # Init the limits (configuration keys) dictionary
self._limits = dict() self._limits = dict()
if config is not None: if config is not None:
logger.debug('Load section {} in {}'.format(self.plugin_name, config.config_file_paths())) logger.debug(f'Load section {self.plugin_name} in {config.config_file_paths()}')
self.load_limits(config=config) self.load_limits(config=config)
# Init the alias (dictionnary) # Init the alias (dictionnary)
@ -147,7 +146,7 @@ class GlancesPluginModel(object):
def exit(self): def exit(self):
"""Just log an event when Glances exit.""" """Just log an event when Glances exit."""
logger.debug("Stop the {} plugin".format(self.plugin_name)) logger.debug(f"Stop the {self.plugin_name} plugin")
def get_key(self): def get_key(self):
"""Return the key of the list.""" """Return the key of the list."""
@ -174,14 +173,14 @@ class GlancesPluginModel(object):
"""Init the stats history (dict of GlancesAttribute).""" """Init the stats history (dict of GlancesAttribute)."""
if self.history_enable(): if self.history_enable():
init_list = [a['name'] for a in self.get_items_history_list()] init_list = [a['name'] for a in self.get_items_history_list()]
logger.debug("Stats history activated for plugin {} (items: {})".format(self.plugin_name, init_list)) logger.debug(f"Stats history activated for plugin {self.plugin_name} (items: {init_list})")
return GlancesHistory() return GlancesHistory()
def reset_stats_history(self): def reset_stats_history(self):
"""Reset the stats history (dict of GlancesAttribute).""" """Reset the stats history (dict of GlancesAttribute)."""
if self.history_enable(): if self.history_enable():
reset_list = [a['name'] for a in self.get_items_history_list()] reset_list = [a['name'] for a in self.get_items_history_list()]
logger.debug("Reset history for plugin {} (items: {})".format(self.plugin_name, reset_list)) logger.debug(f"Reset history for plugin {self.plugin_name} (items: {reset_list})")
self.stats_history.reset() self.stats_history.reset()
def update_stats_history(self): def update_stats_history(self):
@ -414,7 +413,7 @@ class GlancesPluginModel(object):
try: try:
return {value: [i for i in self.get_raw() if i[item] == value]} return {value: [i for i in self.get_raw() if i[item] == value]}
except (KeyError, ValueError) as e: except (KeyError, ValueError) as e:
logger.error("Cannot get item({})=value({}) ({})".format(item, value, e)) logger.error(f"Cannot get item({item})=value({value}) ({e})")
return None return None
def get_stats_value(self, item, value): def get_stats_value(self, item, value):
@ -582,7 +581,7 @@ class GlancesPluginModel(object):
self._limits[limit] = config.get_float_value(self.plugin_name, level) self._limits[limit] = config.get_float_value(self.plugin_name, level)
except ValueError: except ValueError:
self._limits[limit] = config.get_value(self.plugin_name, level).split(",") self._limits[limit] = config.get_value(self.plugin_name, level).split(",")
logger.debug("Load limit: {} = {}".format(limit, self._limits[limit])) logger.debug(f"Load limit: {limit} = {self._limits[limit]}")
return True return True
@ -613,13 +612,13 @@ class GlancesPluginModel(object):
def set_limits(self, item, value): def set_limits(self, item, value):
"""Set the limits object.""" """Set the limits object."""
self._limits['{}_{}'.format(self.plugin_name, item)] = value self._limits[f'{self.plugin_name}_{item}'] = value
def get_limits(self, item=None): def get_limits(self, item=None):
"""Return the limits object.""" """Return the limits object."""
if item is None: if item is None:
return self._limits return self._limits
return self._limits.get('{}_{}'.format(self.plugin_name, item), None) return self._limits.get(f'{self.plugin_name}_{item}', None)
def get_stats_action(self): def get_stats_action(self):
"""Return stats for the action. """Return stats for the action.
@ -1025,7 +1024,7 @@ class GlancesPluginModel(object):
value = self.stats.get(key, None) value = self.stats.get(key, None)
if width is None: if width is None:
msg_item = header + '{}'.format(key_name) + separator msg_item = header + f'{key_name}' + separator
msg_template_float = '{:.1f}{}' msg_template_float = '{:.1f}{}'
msg_template = '{}{}' msg_template = '{}{}'
else: else:
@ -1124,7 +1123,7 @@ class GlancesPluginModel(object):
elif symbol in 'K': elif symbol in 'K':
decimal_precision = 0 decimal_precision = 0
return '{:.{decimal}f}{symbol}'.format(value, decimal=decimal_precision, symbol=symbol) return '{:.{decimal}f}{symbol}'.format(value, decimal=decimal_precision, symbol=symbol)
return '{!s}'.format(number) return f'{number!s}'
def trend_msg(self, trend, significant=1): def trend_msg(self, trend, significant=1):
"""Return the trend message. """Return the trend message.
@ -1170,11 +1169,9 @@ class GlancesPluginModel(object):
counter = Counter() counter = Counter()
ret = fct(*args, **kw) ret = fct(*args, **kw)
duration = counter.get() duration = counter.get()
logger.debug( class_name = args[0].__class__.__name__
"{} {} {} return {} in {} seconds".format( class_module = args[0].__class__.__module__
args[0].__class__.__name__, args[0].__class__.__module__, fct.__name__, ret, duration logger.debug(f"{class_name} {class_module} {fct.__name__} return {ret} in {duration} seconds")
)
)
return ret return ret
return wrapper return wrapper

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -29,7 +28,7 @@ try:
requests_tag = True requests_tag = True
except ImportError as e: except ImportError as e:
requests_tag = False requests_tag = False
logger.warning("Missing Python Lib ({}), Ports plugin is limited to port scanning".format(e)) logger.warning(f"Missing Python Lib ({e}), Ports plugin is limited to port scanning")
# Fields description # Fields description
# description: human readable description # description: human readable description
@ -72,9 +71,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__( super().__init__(args=args, config=config, stats_init_value=[], fields_description=fields_description)
args=args, config=config, stats_init_value=[], fields_description=fields_description
)
self.args = args self.args = args
self.config = config self.config = config
@ -95,7 +92,7 @@ class PluginModel(GlancesPluginModel):
if self._thread is not None: if self._thread is not None:
self._thread.stop() self._thread.stop()
# Call the father class # Call the father class
super(PluginModel, self).exit() super().exit()
def get_key(self): def get_key(self):
"""Return the key of the list.""" """Return the key of the list."""
@ -183,7 +180,7 @@ class PluginModel(GlancesPluginModel):
name_max_width = max_width - 7 name_max_width = max_width - 7
else: else:
# No max_width defined, return an emptu curse message # No max_width defined, return an emptu curse message
logger.debug("No max_width defined for the {} plugin, it will not be displayed.".format(self.plugin_name)) logger.debug(f"No max_width defined for the {self.plugin_name} plugin, it will not be displayed.")
return ret return ret
# Build the string message # Build the string message
@ -199,11 +196,11 @@ class PluginModel(GlancesPluginModel):
status = 'Timeout' status = 'Timeout'
else: else:
# Convert second to ms # Convert second to ms
status = '{0:.0f}ms'.format(p['status'] * 1000.0) status = '{:.0f}ms'.format(p['status'] * 1000.0)
msg = '{:{width}}'.format(p['description'][0:name_max_width], width=name_max_width) msg = '{:{width}}'.format(p['description'][0:name_max_width], width=name_max_width)
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
msg = '{:>9}'.format(status) msg = f'{status:>9}'
ret.append(self.curse_add_line(msg, self.get_ports_alert(p, header=p['indice'] + '_rtt'))) ret.append(self.curse_add_line(msg, self.get_ports_alert(p, header=p['indice'] + '_rtt')))
ret.append(self.curse_new_line()) ret.append(self.curse_new_line())
elif 'url' in p: elif 'url' in p:
@ -215,7 +212,7 @@ class PluginModel(GlancesPluginModel):
status = 'Scanning' status = 'Scanning'
else: else:
status = p['status'] status = p['status']
msg = '{:>9}'.format(status) msg = f'{status:>9}'
ret.append(self.curse_add_line(msg, self.get_web_alert(p, header=p['indice'] + '_rtt'))) ret.append(self.curse_add_line(msg, self.get_web_alert(p, header=p['indice'] + '_rtt')))
ret.append(self.curse_new_line()) ret.append(self.curse_new_line())
@ -237,8 +234,8 @@ class ThreadScanner(threading.Thread):
def __init__(self, stats): def __init__(self, stats):
"""Init the class.""" """Init the class."""
logger.debug("ports plugin - Create thread for scan list {}".format(stats)) logger.debug(f"ports plugin - Create thread for scan list {stats}")
super(ThreadScanner, self).__init__() super().__init__()
# Event needed to stop properly the thread # Event needed to stop properly the thread
self._stopper = threading.Event() self._stopper = threading.Event()
# The class return the stats as a list of dict # The class return the stats as a list of dict
@ -283,7 +280,7 @@ class ThreadScanner(threading.Thread):
def stop(self, timeout=None): def stop(self, timeout=None):
"""Stop the thread.""" """Stop the thread."""
logger.debug("ports plugin - Close thread for scan list {}".format(self._stats)) logger.debug(f"ports plugin - Close thread for scan list {self._stats}")
self._stopper.set() self._stopper.set()
def stopped(self): def stopped(self):
@ -321,7 +318,7 @@ class ThreadScanner(threading.Thread):
try: try:
ip = socket.gethostbyname(hostname) ip = socket.gethostbyname(hostname)
except Exception as e: except Exception as e:
logger.debug("{}: Cannot convert {} to IP address ({})".format(self.plugin_name, hostname, e)) logger.debug(f"{self.plugin_name}: Cannot convert {hostname} to IP address ({e})")
return ip return ip
def _port_scan_icmp(self, port): def _port_scan_icmp(self, port):
@ -379,7 +376,7 @@ class ThreadScanner(threading.Thread):
socket.setdefaulttimeout(port['timeout']) socket.setdefaulttimeout(port['timeout'])
_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) _socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except Exception as e: except Exception as e:
logger.debug("{}: Error while creating scanning socket ({})".format(self.plugin_name, e)) logger.debug(f"{self.plugin_name}: Error while creating scanning socket ({e})")
# Scan port # Scan port
ip = self._resolv_name(port['host']) ip = self._resolv_name(port['host'])
@ -387,7 +384,7 @@ class ThreadScanner(threading.Thread):
try: try:
ret = _socket.connect_ex((ip, int(port['port']))) ret = _socket.connect_ex((ip, int(port['port'])))
except Exception as e: except Exception as e:
logger.debug("{}: Error while scanning port {} ({})".format(self.plugin_name, port, e)) logger.debug(f"{self.plugin_name}: Error while scanning port {port} ({e})")
else: else:
if ret == 0: if ret == 0:
port['status'] = counter.get() port['status'] = counter.get()

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -58,7 +57,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__( super().__init__(
args=args, config=config, items_history_list=items_history_list, fields_description=fields_description args=args, config=config, items_history_list=items_history_list, fields_description=fields_description
) )
@ -113,9 +112,9 @@ class PluginModel(GlancesPluginModel):
if glances_processes.process_filter is not None: if glances_processes.process_filter is not None:
msg = 'Processes filter:' msg = 'Processes filter:'
ret.append(self.curse_add_line(msg, "TITLE")) ret.append(self.curse_add_line(msg, "TITLE"))
msg = ' {} '.format(glances_processes.process_filter) msg = f' {glances_processes.process_filter} '
if glances_processes.process_filter_key is not None: if glances_processes.process_filter_key is not None:
msg += 'on column {} '.format(glances_processes.process_filter_key) msg += f'on column {glances_processes.process_filter_key} '
ret.append(self.curse_add_line(msg, "FILTER")) ret.append(self.curse_add_line(msg, "FILTER"))
msg = '(\'ENTER\' to edit, \'E\' to reset)' msg = '(\'ENTER\' to edit, \'E\' to reset)'
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
@ -144,7 +143,7 @@ class PluginModel(GlancesPluginModel):
msg = ' {} slp,'.format(self.stats['sleeping']) msg = ' {} slp,'.format(self.stats['sleeping'])
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
msg = ' {} oth '.format(other) msg = f' {other} oth '
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
# Display sort information # Display sort information
@ -156,9 +155,9 @@ class PluginModel(GlancesPluginModel):
if glances_processes.auto_sort: if glances_processes.auto_sort:
msg += ' sorted automatically' msg += ' sorted automatically'
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
msg = ' by {}'.format(sort_human) msg = f' by {sort_human}'
else: else:
msg += ' sorted by {}'.format(sort_human) msg += f' sorted by {sort_human}'
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
# Return the message with decoration # Return the message with decoration

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -155,9 +154,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__( super().__init__(args=args, config=config, fields_description=fields_description, stats_init_value=[])
args=args, config=config, fields_description=fields_description, stats_init_value=[]
)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
self.display_curse = True self.display_curse = True
@ -341,11 +338,11 @@ class PluginModel(GlancesPluginModel):
else: else:
hours, minutes, seconds = seconds_to_hms(user_system_time) hours, minutes, seconds = seconds_to_hms(user_system_time)
if hours > 99: if hours > 99:
msg = '{:<7}h'.format(hours) msg = f'{hours:<7}h'
elif 0 < hours < 100: elif 0 < hours < 100:
msg = '{}h{}:{}'.format(hours, minutes, seconds) msg = f'{hours}h{minutes}:{seconds}'
else: else:
msg = '{}:{}'.format(minutes, seconds) msg = f'{minutes}:{seconds}'
msg = self.layout_stat['time'].format(msg) msg = self.layout_stat['time'].format(msg)
if hours > 0: if hours > 0:
ret = self.curse_add_line(msg, decoration='CPU_TIME', optional=True) ret = self.curse_add_line(msg, decoration='CPU_TIME', optional=True)
@ -502,7 +499,7 @@ class PluginModel(GlancesPluginModel):
ret.append(self.curse_add_line(msg, decoration=process_decoration, splittable=True)) ret.append(self.curse_add_line(msg, decoration=process_decoration, splittable=True))
except (TypeError, UnicodeEncodeError) as e: except (TypeError, UnicodeEncodeError) as e:
# Avoid crash after running fine for several hours #1335 # Avoid crash after running fine for several hours #1335
logger.debug("Can not decode command line '{}' ({})".format(cmdline, e)) logger.debug(f"Can not decode command line '{cmdline}' ({e})")
ret.append(self.curse_add_line('', splittable=True)) ret.append(self.curse_add_line('', splittable=True))
return ret return ret
@ -643,7 +640,7 @@ class PluginModel(GlancesPluginModel):
# value is a number which goes from 0 to 7. # value is a number which goes from 0 to 7.
# The higher the value, the lower the I/O priority of the process. # The higher the value, the lower the I/O priority of the process.
if hasattr(p['ionice'], 'value') and p['ionice'].value != 0: if hasattr(p['ionice'], 'value') and p['ionice'].value != 0:
msg += ' (value %s/7)' % str(p['ionice'].value) msg += ' (value {}/7)'.format(str(p['ionice'].value))
ret.append(self.curse_add_line(msg, splittable=True)) ret.append(self.curse_add_line(msg, splittable=True))
# Second line is memory info # Second line is memory info
@ -826,7 +823,7 @@ class PluginModel(GlancesPluginModel):
msg = ' < {}'.format('current') msg = ' < {}'.format('current')
ret.append(self.curse_add_line(msg, optional=True)) ret.append(self.curse_add_line(msg, optional=True))
else: else:
msg = ' < {}'.format(mmm) msg = f' < {mmm}'
ret.append(self.curse_add_line(msg, optional=True)) ret.append(self.curse_add_line(msg, optional=True))
msg = ' (\'M\' to reset)' msg = ' (\'M\' to reset)'
ret.append(self.curse_add_line(msg, optional=True)) ret.append(self.curse_add_line(msg, optional=True))

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -22,7 +21,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config) super().__init__(args=args, config=config)
self.reset() self.reset()

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -84,7 +83,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the quicklook plugin.""" """Init the quicklook plugin."""
super(PluginModel, self).__init__( super().__init__(
args=args, config=config, items_history_list=items_history_list, fields_description=fields_description args=args, config=config, items_history_list=items_history_list, fields_description=fields_description
) )
@ -97,7 +96,7 @@ class PluginModel(GlancesPluginModel):
# Define the stats list # Define the stats list
self.stats_list = self.get_conf_value('list', default=self.DEFAULT_STATS_LIST) self.stats_list = self.get_conf_value('list', default=self.DEFAULT_STATS_LIST)
if not set(self.stats_list).issubset(self.AVAILABLE_STATS_LIST): if not set(self.stats_list).issubset(self.AVAILABLE_STATS_LIST):
logger.warning('Quicklook plugin: Invalid stats list: {}'.format(self.stats_list)) logger.warning(f'Quicklook plugin: Invalid stats list: {self.stats_list}')
self.stats_list = self.AVAILABLE_STATS_LIST self.stats_list = self.AVAILABLE_STATS_LIST
@GlancesPluginModel._check_decorator @GlancesPluginModel._check_decorator
@ -152,7 +151,7 @@ class PluginModel(GlancesPluginModel):
def update_views(self): def update_views(self):
"""Update stats views.""" """Update stats views."""
# Call the father's method # Call the father's method
super(PluginModel, self).update_views() super().update_views()
# Alert for CPU, MEM and SWAP # Alert for CPU, MEM and SWAP
for key in self.stats_list: for key in self.stats_list:
@ -176,7 +175,7 @@ class PluginModel(GlancesPluginModel):
if not max_width: if not max_width:
# No max_width defined, return an empty message # No max_width defined, return an empty message
logger.debug("No max_width defined for the {} plugin, it will not be displayed.".format(self.plugin_name)) logger.debug(f"No max_width defined for the {self.plugin_name} plugin, it will not be displayed.")
return ret return ret
# Define the data: Bar (default behavior) or Sparkline # Define the data: Bar (default behavior) or Sparkline
@ -221,7 +220,7 @@ class PluginModel(GlancesPluginModel):
else: else:
# Bar only the last value # Bar only the last value
data[key].percent = self.stats[key] data[key].percent = self.stats[key]
msg = '{:4} '.format(key.upper()) msg = f'{key.upper():4} '
ret.extend(self._msg_create_line(msg, data[key], key)) ret.extend(self._msg_create_line(msg, data[key], key))
ret.append(self.curse_new_line()) ret.append(self.curse_new_line())
@ -258,9 +257,9 @@ class PluginModel(GlancesPluginModel):
# Bar will only display the last value # Bar will only display the last value
data[key].percent = cpu['total'] data[key].percent = cpu['total']
if cpu_id < 10: if cpu_id < 10:
msg = '{:3}{} '.format(key.upper(), cpu_id) msg = f'{key.upper():3}{cpu_id} '
else: else:
msg = '{:4} '.format(cpu_id) msg = f'{cpu_id:4} '
ret.extend(self._msg_create_line(msg, data[key], key)) ret.extend(self._msg_create_line(msg, data[key], key))
ret.append(self.curse_new_line()) ret.append(self.curse_new_line())
@ -282,7 +281,7 @@ class PluginModel(GlancesPluginModel):
sum_other.percent = sum([i['total'] for i in percpu_list[self.max_cpu_display :]]) / len( sum_other.percent = sum([i['total'] for i in percpu_list[self.max_cpu_display :]]) / len(
percpu_list[self.max_cpu_display :] percpu_list[self.max_cpu_display :]
) )
msg = msg = '{:3}* '.format(key.upper()) msg = msg = f'{key.upper():3}* '
ret.extend(self._msg_create_line(msg, sum_other, key)) ret.extend(self._msg_create_line(msg, sum_other, key))
ret.append(self.curse_new_line()) ret.append(self.curse_new_line())

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -18,7 +17,7 @@ try:
from pymdstat import MdStat from pymdstat import MdStat
except ImportError as e: except ImportError as e:
import_error_tag = True import_error_tag = True
logger.warning("Missing Python Lib ({}), Raid plugin is disabled".format(e)) logger.warning(f"Missing Python Lib ({e}), Raid plugin is disabled")
else: else:
import_error_tag = False import_error_tag = False
@ -31,7 +30,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config) super().__init__(args=args, config=config)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
self.display_curse = True self.display_curse = True
@ -54,7 +53,7 @@ class PluginModel(GlancesPluginModel):
# mds = MdStat(path='/home/nicolargo/dev/pymdstat/tests/mdstat.10') # mds = MdStat(path='/home/nicolargo/dev/pymdstat/tests/mdstat.10')
stats = mds.get_stats()['arrays'] stats = mds.get_stats()['arrays']
except Exception as e: except Exception as e:
logger.debug("Can not grab RAID stats (%s)" % e) logger.debug(f"Can not grab RAID stats ({e})")
return self.stats return self.stats
elif self.input_method == 'snmp': elif self.input_method == 'snmp':
@ -81,7 +80,7 @@ class PluginModel(GlancesPluginModel):
name_max_width = max_width - 12 name_max_width = max_width - 12
else: else:
# No max_width defined, return an emptu curse message # No max_width defined, return an emptu curse message
logger.debug("No max_width defined for the {} plugin, it will not be displayed.".format(self.plugin_name)) logger.debug(f"No max_width defined for the {self.plugin_name} plugin, it will not be displayed.")
return ret return ret
# Header # Header
@ -108,7 +107,7 @@ class PluginModel(GlancesPluginModel):
# Data: RAID type name | disk used | disk available # Data: RAID type name | disk used | disk available
array_type = self.stats[array]['type'].upper() if self.stats[array]['type'] is not None else 'UNKNOWN' array_type = self.stats[array]['type'].upper() if self.stats[array]['type'] is not None else 'UNKNOWN'
# Build the full name = array type + array name # Build the full name = array type + array name
full_name = '{} {}'.format(array_type, array) full_name = f'{array_type} {array}'
msg = '{:{width}}'.format(full_name, width=name_max_width) msg = '{:{width}}'.format(full_name, width=name_max_width)
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
if self.stats[array]['type'] == 'raid0' and self.stats[array]['status'] == 'active': if self.stats[array]['type'] == 'raid0' and self.stats[array]['status'] == 'active':
@ -134,7 +133,7 @@ class PluginModel(GlancesPluginModel):
ret.append(self.curse_new_line()) ret.append(self.curse_new_line())
msg = ' {} disk {}: '.format(tree_char, self.stats[array]['components'][component]) msg = ' {} disk {}: '.format(tree_char, self.stats[array]['components'][component])
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
msg = '{}'.format(component) msg = f'{component}'
ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(msg))
if self.stats[array]['type'] != 'raid0' and (self.stats[array]['used'] < self.stats[array]['available']): if self.stats[array]['type'] != 'raid0' and (self.stats[array]['used'] < self.stats[array]['available']):
# Display current array configuration # Display current array configuration

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -83,29 +82,27 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__( super().__init__(args=args, config=config, stats_init_value=[], fields_description=fields_description)
args=args, config=config, stats_init_value=[], fields_description=fields_description
)
start_duration = Counter() start_duration = Counter()
# Init the sensor class # Init the sensor class
start_duration.reset() start_duration.reset()
glances_grab_sensors_cpu_temp = GlancesGrabSensors(SensorType.CPU_TEMP) glances_grab_sensors_cpu_temp = GlancesGrabSensors(SensorType.CPU_TEMP)
logger.debug("CPU Temp sensor plugin init duration: {} seconds".format(start_duration.get())) logger.debug(f"CPU Temp sensor plugin init duration: {start_duration.get()} seconds")
start_duration.reset() start_duration.reset()
glances_grab_sensors_fan_speed = GlancesGrabSensors(SensorType.FAN_SPEED) glances_grab_sensors_fan_speed = GlancesGrabSensors(SensorType.FAN_SPEED)
logger.debug("Fan speed sensor plugin init duration: {} seconds".format(start_duration.get())) logger.debug(f"Fan speed sensor plugin init duration: {start_duration.get()} seconds")
# Instance for the HDDTemp Plugin in order to display the hard disks temperatures # Instance for the HDDTemp Plugin in order to display the hard disks temperatures
start_duration.reset() start_duration.reset()
hddtemp_plugin = HddTempPluginModel(args=args, config=config) hddtemp_plugin = HddTempPluginModel(args=args, config=config)
logger.debug("HDDTemp sensor plugin init duration: {} seconds".format(start_duration.get())) logger.debug(f"HDDTemp sensor plugin init duration: {start_duration.get()} seconds")
# Instance for the BatPercent in order to display the batteries capacities # Instance for the BatPercent in order to display the batteries capacities
start_duration.reset() start_duration.reset()
batpercent_plugin = BatPercentPluginModel(args=args, config=config) batpercent_plugin = BatPercentPluginModel(args=args, config=config)
logger.debug("Battery sensor plugin init duration: {} seconds".format(start_duration.get())) logger.debug(f"Battery sensor plugin init duration: {start_duration.get()} seconds")
self.sensors_grab_map: Dict[SensorType, Any] = {} self.sensors_grab_map: Dict[SensorType, Any] = {}
@ -214,7 +211,7 @@ class PluginModel(GlancesPluginModel):
def update_views(self): def update_views(self):
"""Update stats views.""" """Update stats views."""
# Call the father's method # Call the father's method
super(PluginModel, self).update_views() super().update_views()
# Add specifics information # Add specifics information
# Alert # Alert
@ -272,7 +269,7 @@ class PluginModel(GlancesPluginModel):
name_max_width = max_width - 12 name_max_width = max_width - 12
else: else:
# No max_width defined, return an emptu curse message # No max_width defined, return an emptu curse message
logger.debug("No max_width defined for the {} plugin, it will not be displayed.".format(self.plugin_name)) logger.debug(f"No max_width defined for the {self.plugin_name} plugin, it will not be displayed.")
return ret return ret
# Header # Header
@ -303,8 +300,8 @@ class PluginModel(GlancesPluginModel):
value = i['value'] value = i['value']
unit = i['unit'] unit = i['unit']
try: try:
msg = '{:.0f}{}{}'.format(value, unit, trend) msg = f'{value:.0f}{unit}{trend}'
msg = '{:>14}'.format(msg) msg = f'{msg:>14}'
ret.append( ret.append(
self.curse_add_line( self.curse_add_line(
msg, self.get_views(item=i[self.get_key()], key='value', option='decoration') msg, self.get_views(item=i[self.get_key()], key='value', option='decoration')
@ -316,7 +313,7 @@ class PluginModel(GlancesPluginModel):
return ret return ret
class GlancesGrabSensors(object): class GlancesGrabSensors:
"""Get sensors stats.""" """Get sensors stats."""
def __init__(self, sensor_type: Literal[SensorType.FAN_SPEED, SensorType.CPU_TEMP]): def __init__(self, sensor_type: Literal[SensorType.FAN_SPEED, SensorType.CPU_TEMP]):

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -31,7 +30,7 @@ psutil_tag = True
try: try:
psutil.sensors_battery() psutil.sensors_battery()
except Exception as e: except Exception as e:
logger.error("Cannot grab battery status {}.".format(e)) logger.error(f"Cannot grab battery status {e}.")
psutil_tag = False psutil_tag = False
@ -43,13 +42,13 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config, stats_init_value=[]) super().__init__(args=args, config=config, stats_init_value=[])
# Init the sensor class # Init the sensor class
try: try:
self.glances_grab_bat = GlancesGrabBat() self.glances_grab_bat = GlancesGrabBat()
except Exception as e: except Exception as e:
logger.error("Can not init battery class ({})".format(e)) logger.error(f"Can not init battery class ({e})")
global batinfo_tag global batinfo_tag
global psutil_tag global psutil_tag
batinfo_tag = False batinfo_tag = False
@ -82,7 +81,7 @@ class PluginModel(GlancesPluginModel):
return self.stats return self.stats
class GlancesGrabBat(object): class GlancesGrabBat:
"""Get batteries stats using the batinfo library.""" """Get batteries stats using the batinfo library."""
def __init__(self): def __init__(self):

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -25,7 +24,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config, stats_init_value=[]) super().__init__(args=args, config=config, stats_init_value=[])
# Init the sensor class # Init the sensor class
hddtemp_host = self.get_conf_value("host", default=["127.0.0.1"])[0] hddtemp_host = self.get_conf_value("host", default=["127.0.0.1"])[0]
@ -58,7 +57,7 @@ class PluginModel(GlancesPluginModel):
return self.stats return self.stats
class GlancesGrabHDDTemp(object): class GlancesGrabHDDTemp:
"""Get hddtemp stats using a socket connection.""" """Get hddtemp stats using a socket connection."""
def __init__(self, host='127.0.0.1', port=7634, args=None): def __init__(self, host='127.0.0.1', port=7634, args=None):
@ -133,7 +132,7 @@ class GlancesGrabHDDTemp(object):
break break
data += received data += received
except Exception as e: except Exception as e:
logger.debug("Cannot connect to an HDDtemp server ({}:{} => {})".format(self.host, self.port, e)) logger.debug(f"Cannot connect to an HDDtemp server ({self.host}:{self.port} => {e})")
logger.debug("Disable the HDDtemp module. Use the --disable-hddtemp to hide the previous message.") logger.debug("Disable the HDDtemp module. Use the --disable-hddtemp to hide the previous message.")
if self.args is not None: if self.args is not None:
self.args.disable_hddtemp = True self.args.disable_hddtemp = True
@ -141,7 +140,7 @@ class GlancesGrabHDDTemp(object):
finally: finally:
sck.close() sck.close()
if data != "": if data != "":
logger.debug("Received data from the HDDtemp server: {}".format(data)) logger.debug(f"Received data from the HDDtemp server: {data}")
return data return data

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -44,7 +43,7 @@ try:
from pySMART import DeviceList from pySMART import DeviceList
except ImportError as e: except ImportError as e:
import_error_tag = True import_error_tag = True
logger.warning("Missing Python Lib ({}), HDD Smart plugin is disabled".format(e)) logger.warning(f"Missing Python Lib ({e}), HDD Smart plugin is disabled")
else: else:
import_error_tag = False import_error_tag = False
@ -89,7 +88,7 @@ def get_smart_data():
devlist = DeviceList() devlist = DeviceList()
except TypeError as e: except TypeError as e:
# Catch error (see #1806) # Catch error (see #1806)
logger.debug('Smart plugin error - Can not grab device list ({})'.format(e)) logger.debug(f'Smart plugin error - Can not grab device list ({e})')
global import_error_tag global import_error_tag
import_error_tag = True import_error_tag = True
return stats return stats
@ -97,7 +96,7 @@ def get_smart_data():
for dev in devlist.devices: for dev in devlist.devices:
stats.append( stats.append(
{ {
'DeviceName': '{} {}'.format(dev.name, dev.model), 'DeviceName': f'{dev.name} {dev.model}',
} }
) )
for attribute in dev.attributes: for attribute in dev.attributes:
@ -112,7 +111,7 @@ def get_smart_data():
assert num is not None assert num is not None
except Exception as e: except Exception as e:
# we should never get here, but if we do, continue to next iteration and skip this attribute # we should never get here, but if we do, continue to next iteration and skip this attribute
logger.debug('Smart plugin error - Skip the attribute {} ({})'.format(attribute, e)) logger.debug(f'Smart plugin error - Skip the attribute {attribute} ({e})')
continue continue
stats[-1][num] = attrib_dict stats[-1][num] = attrib_dict
@ -129,7 +128,7 @@ class PluginModel(GlancesPluginModel):
disable(args, "smart") disable(args, "smart")
logger.debug("Current user is not admin, HDD SMART plugin disabled.") logger.debug("Current user is not admin, HDD SMART plugin disabled.")
super(PluginModel, self).__init__(args=args, config=config) super().__init__(args=args, config=config)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
self.display_curse = True self.display_curse = True
@ -172,7 +171,7 @@ class PluginModel(GlancesPluginModel):
name_max_width = max_width - 6 name_max_width = max_width - 6
else: else:
# No max_width defined, return an emptu curse message # No max_width defined, return an emptu curse message
logger.debug("No max_width defined for the {} plugin, it will not be displayed.".format(self.plugin_name)) logger.debug(f"No max_width defined for the {self.plugin_name} plugin, it will not be displayed.")
return ret return ret
# Header # Header

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -9,10 +8,10 @@
"""System plugin.""" """System plugin."""
import builtins
import os import os
import platform import platform
import re import re
from io import open
from glances.globals import iteritems from glances.globals import iteritems
from glances.logger import logger from glances.logger import logger
@ -92,12 +91,12 @@ def _linux_os_release():
ashtray = {} ashtray = {}
keys = ['NAME', 'VERSION_ID'] keys = ['NAME', 'VERSION_ID']
try: try:
with open(os.path.join('/etc', 'os-release')) as f: with builtins.open(os.path.join('/etc', 'os-release')) as f:
for line in f: for line in f:
for key in keys: for key in keys:
if line.startswith(key): if line.startswith(key):
ashtray[key] = re.sub(r'^"|"$', '', line.strip().split('=')[1]) ashtray[key] = re.sub(r'^"|"$', '', line.strip().split('=')[1])
except (OSError, IOError): except OSError:
return pretty_name return pretty_name
if ashtray: if ashtray:
@ -117,7 +116,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config, fields_description=fields_description) super().__init__(args=args, config=config, fields_description=fields_description)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
self.display_curse = True self.display_curse = True

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -27,7 +26,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config) super().__init__(args=args, config=config)
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
self.display_curse = True self.display_curse = True
@ -83,4 +82,4 @@ class PluginModel(GlancesPluginModel):
if not self.stats or self.is_disabled(): if not self.stats or self.is_disabled():
return ret return ret
return [self.curse_add_line('Uptime: {}'.format(self.stats))] return [self.curse_add_line(f'Uptime: {self.stats}')]

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -23,7 +22,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config) super().__init__(args=args, config=config)
self.reset() self.reset()

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -29,7 +28,7 @@ WIRELESS_FILE = '/proc/net/wireless'
wireless_file_exists = file_exists(WIRELESS_FILE) wireless_file_exists = file_exists(WIRELESS_FILE)
if not wireless_file_exists: if not wireless_file_exists:
logger.debug("Wifi plugin is disabled (no %s file found)" % (WIRELESS_FILE)) logger.debug(f"Wifi plugin is disabled (no {WIRELESS_FILE} file found)")
# Fields description # Fields description
# description: human readable description # description: human readable description
@ -58,7 +57,7 @@ class PluginModel(GlancesPluginModel):
def __init__(self, args=None, config=None): def __init__(self, args=None, config=None):
"""Init the plugin.""" """Init the plugin."""
super(PluginModel, self).__init__(args=args, config=config, stats_init_value=[]) super().__init__(args=args, config=config, stats_init_value=[])
# We want to display the stat in the curse interface # We want to display the stat in the curse interface
self.display_curse = True self.display_curse = True
@ -71,7 +70,7 @@ class PluginModel(GlancesPluginModel):
if self._thread is not None: if self._thread is not None:
self._thread.stop() self._thread.stop()
# Call the father class # Call the father class
super(PluginModel, self).exit() super().exit()
def get_key(self): def get_key(self):
"""Return the key of the list. """Return the key of the list.
@ -98,7 +97,7 @@ class PluginModel(GlancesPluginModel):
if self.input_method == 'local' and wireless_file_exists: if self.input_method == 'local' and wireless_file_exists:
# As a backup solution, use the /proc/net/wireless file # As a backup solution, use the /proc/net/wireless file
with open(WIRELESS_FILE, 'r') as f: with open(WIRELESS_FILE) as f:
# The first two lines are header # The first two lines are header
f.readline() f.readline()
f.readline() f.readline()
@ -154,7 +153,7 @@ class PluginModel(GlancesPluginModel):
def update_views(self): def update_views(self):
"""Update stats views.""" """Update stats views."""
# Call the father's method # Call the father's method
super(PluginModel, self).update_views() super().update_views()
# Add specifics information # Add specifics information
# Alert on quality_level thresholds # Alert on quality_level thresholds
@ -175,7 +174,7 @@ class PluginModel(GlancesPluginModel):
if_name_max_width = max_width - 5 if_name_max_width = max_width - 5
else: else:
# No max_width defined, return an emptu curse message # No max_width defined, return an emptu curse message
logger.debug("No max_width defined for the {} plugin, it will not be displayed.".format(self.plugin_name)) logger.debug(f"No max_width defined for the {self.plugin_name} plugin, it will not be displayed.")
return ret return ret
# Build the string message # Build the string message

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -26,7 +25,7 @@ else:
netifaces_tag = False netifaces_tag = False
class GlancesPortsList(object): class GlancesPortsList:
"""Manage the ports list for the ports plugin.""" """Manage the ports list for the ports plugin."""
_section = "ports" _section = "ports"
@ -46,9 +45,9 @@ class GlancesPortsList(object):
if config is None: if config is None:
logger.debug("No configuration file available. Cannot load ports list.") logger.debug("No configuration file available. Cannot load ports list.")
elif not config.has_section(self._section): elif not config.has_section(self._section):
logger.debug("No [%s] section in the configuration file. Cannot load ports list." % self._section) logger.debug(f"No [{self._section}] section in the configuration file. Cannot load ports list.")
else: else:
logger.debug("Start reading the [%s] section in the configuration file" % self._section) logger.debug(f"Start reading the [{self._section}] section in the configuration file")
refresh = int(config.get_value(self._section, 'refresh', default=self._default_refresh)) refresh = int(config.get_value(self._section, 'refresh', default=self._default_refresh))
timeout = int(config.get_value(self._section, 'timeout', default=self._default_timeout)) timeout = int(config.get_value(self._section, 'timeout', default=self._default_timeout))
@ -68,26 +67,26 @@ class GlancesPortsList(object):
new_port['timeout'] = timeout new_port['timeout'] = timeout
new_port['status'] = None new_port['status'] = None
new_port['rtt_warning'] = None new_port['rtt_warning'] = None
new_port['indice'] = str('port_0') new_port['indice'] = 'port_0'
logger.debug("Add default gateway %s to the static list" % (new_port['host'])) logger.debug("Add default gateway {} to the static list".format(new_port['host']))
ports_list.append(new_port) ports_list.append(new_port)
# Read the scan list # Read the scan list
for i in range(1, 256): for i in range(1, 256):
new_port = {} new_port = {}
postfix = 'port_%s_' % str(i) postfix = f'port_{str(i)}_'
# Read mandatory configuration key: host # Read mandatory configuration key: host
new_port['host'] = config.get_value(self._section, '%s%s' % (postfix, 'host')) new_port['host'] = config.get_value(self._section, '{}{}'.format(postfix, 'host'))
if new_port['host'] is None: if new_port['host'] is None:
continue continue
# Read optionals configuration keys # Read optionals configuration keys
# Port is set to 0 by default. 0 mean ICMP check instead of TCP check # Port is set to 0 by default. 0 mean ICMP check instead of TCP check
new_port['port'] = config.get_value(self._section, '%s%s' % (postfix, 'port'), 0) new_port['port'] = config.get_value(self._section, '{}{}'.format(postfix, 'port'), 0)
new_port['description'] = config.get_value( new_port['description'] = config.get_value(
self._section, '%sdescription' % postfix, default="%s:%s" % (new_port['host'], new_port['port']) self._section, f'{postfix}description', default="{}:{}".format(new_port['host'], new_port['port'])
) )
# Default status # Default status
@ -97,10 +96,10 @@ class GlancesPortsList(object):
new_port['refresh'] = refresh new_port['refresh'] = refresh
# Timeout in second # Timeout in second
new_port['timeout'] = int(config.get_value(self._section, '%stimeout' % postfix, default=timeout)) new_port['timeout'] = int(config.get_value(self._section, f'{postfix}timeout', default=timeout))
# RTT warning # RTT warning
new_port['rtt_warning'] = config.get_value(self._section, '%srtt_warning' % postfix, default=None) new_port['rtt_warning'] = config.get_value(self._section, f'{postfix}rtt_warning', default=None)
if new_port['rtt_warning'] is not None: if new_port['rtt_warning'] is not None:
# Convert to second # Convert to second
new_port['rtt_warning'] = int(new_port['rtt_warning']) / 1000.0 new_port['rtt_warning'] = int(new_port['rtt_warning']) / 1000.0
@ -109,11 +108,11 @@ class GlancesPortsList(object):
new_port['indice'] = 'port_' + str(i) new_port['indice'] = 'port_' + str(i)
# Add the server to the list # Add the server to the list
logger.debug("Add port %s:%s to the static list" % (new_port['host'], new_port['port'])) logger.debug("Add port {}:{} to the static list".format(new_port['host'], new_port['port']))
ports_list.append(new_port) ports_list.append(new_port)
# Ports list loaded # Ports list loaded
logger.debug("Ports list loaded: %s" % ports_list) logger.debug(f"Ports list loaded: {ports_list}")
return ports_list return ports_list

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# #
# This file is part of Glances. # This file is part of Glances.
# #
@ -34,7 +33,7 @@ sort_for_human = {
} }
class GlancesProcesses(object): class GlancesProcesses:
"""Get processed stats using the psutil library.""" """Get processed stats using the psutil library."""
def __init__(self, cache_timeout=60): def __init__(self, cache_timeout=60):
@ -83,7 +82,7 @@ class GlancesProcesses(object):
p = psutil.Process() p = psutil.Process()
p.io_counters() p.io_counters()
except Exception as e: except Exception as e:
logger.warning('PsUtil can not grab processes io_counters ({})'.format(e)) logger.warning(f'PsUtil can not grab processes io_counters ({e})')
self.disable_io_counters = True self.disable_io_counters = True
else: else:
logger.debug('PsUtil can grab processes io_counters') logger.debug('PsUtil can grab processes io_counters')
@ -94,7 +93,7 @@ class GlancesProcesses(object):
p = psutil.Process() p = psutil.Process()
p.gids() p.gids()
except Exception as e: except Exception as e:
logger.warning('PsUtil can not grab processes gids ({})'.format(e)) logger.warning(f'PsUtil can not grab processes gids ({e})')
self.disable_gids = True self.disable_gids = True
else: else:
logger.debug('PsUtil can grab processes gids') logger.debug('PsUtil can grab processes gids')
@ -183,7 +182,7 @@ class GlancesProcesses(object):
try: try:
with open('/proc/sys/kernel/pid_max', 'rb') as f: with open('/proc/sys/kernel/pid_max', 'rb') as f:
return int(f.read()) return int(f.read())
except (OSError, IOError): except OSError:
return None return None
else: else:
return None return None
@ -310,7 +309,7 @@ class GlancesProcesses(object):
# Get number of TCP and UDP network connections for the selected process # Get number of TCP and UDP network connections for the selected process
ret['tcp'], ret['udp'] = self.__get_extended_connections(selected_process) ret['tcp'], ret['udp'] = self.__get_extended_connections(selected_process)
except (psutil.NoSuchProcess, ValueError, AttributeError) as e: except (psutil.NoSuchProcess, ValueError, AttributeError) as e:
logger.error('Can not grab extended stats ({})'.format(e)) logger.error(f'Can not grab extended stats ({e})')
self.extended_process = None self.extended_process = None
ret['extended_stats'] = False ret['extended_stats'] = False
else: else:
@ -595,11 +594,9 @@ class GlancesProcesses(object):
p = psutil.Process(pid) p = psutil.Process(pid)
try: try:
p.nice(p.nice() - 1) p.nice(p.nice() - 1)
logger.info('Set nice level of process {} to {} (higher the priority)'.format(pid, p.nice())) logger.info(f'Set nice level of process {pid} to {p.nice()} (higher the priority)')
except psutil.AccessDenied: except psutil.AccessDenied:
logger.warning( logger.warning(f'Can not decrease (higher the priority) the nice level of process {pid} (access denied)')
'Can not decrease (higher the priority) the nice level of process {} (access denied)'.format(pid)
)
def nice_increase(self, pid): def nice_increase(self, pid):
"""Increase nice level """Increase nice level
@ -608,17 +605,15 @@ class GlancesProcesses(object):
p = psutil.Process(pid) p = psutil.Process(pid)
try: try:
p.nice(p.nice() + 1) p.nice(p.nice() + 1)
logger.info('Set nice level of process {} to {} (lower the priority)'.format(pid, p.nice())) logger.info(f'Set nice level of process {pid} to {p.nice()} (lower the priority)')
except psutil.AccessDenied: except psutil.AccessDenied:
logger.warning( logger.warning(f'Can not increase (lower the priority) the nice level of process {pid} (access denied)')
'Can not increase (lower the priority) the nice level of process {} (access denied)'.format(pid)
)
def kill(self, pid, timeout=3): def kill(self, pid, timeout=3):
"""Kill process with pid""" """Kill process with pid"""
assert pid != os.getpid(), "Glances can kill itself..." assert pid != os.getpid(), "Glances can kill itself..."
p = psutil.Process(pid) p = psutil.Process(pid)
logger.debug('Send kill signal to process: {}'.format(p)) logger.debug(f'Send kill signal to process: {p}')
p.kill() p.kill()
return p.wait(timeout) return p.wait(timeout)

Some files were not shown because too many files have changed in this diff Show More