Merge branch 'develop' of https://github.com/nicolargo/glances into develop

This commit is contained in:
nicolargo
2016-12-24 17:00:58 +01:00
21 changed files with 305 additions and 318 deletions

View File

@@ -3,7 +3,7 @@
##############################################################################
[global]
# Does Glances should check if a newer version is available on Pypi ?
# Does Glances should check if a newer version is available on PyPI ?
check_update=true
# History size (maximum number of values)
# Default is 28800: 1 day with 1 point every 3 seconds (default refresh time)
@@ -48,12 +48,12 @@ steal_warning=70
steal_critical=90
#steal_log=True
# I/O wait percentage should be lower than 1/# (of CPU cores)
# Let commented for default config (1/#-20% / 1/#-10% / 1/#)
# Leave commented to just use the default config (1/#-20% / 1/#-10% / 1/#)
#iowait_careful=30
#iowait_warning=40
#iowait_critical=50
# Context switch limit (core / second)
# Let commented for default config (critical is 56000/# (of CPU core))
# Leave commented to just use the default config (critical is 56000/# (of CPU core))
#ctx_switches_careful=10000
#ctx_switches_warning=12000
#ctx_switches_critical=14000
@@ -211,7 +211,7 @@ mem_critical=90
# Ports scanner plugin configuration
# Interval in second between two scans
refresh=30
# Set the default timeout (in second) for a scan (can be overwrite in the scan list)
# Set the default timeout (in second) for a scan (can be overwritten in the scan list)
timeout=3
# If port_default_gateway is True, add the default gateway on top of the scan list
port_default_gateway=True
@@ -365,7 +365,7 @@ prefix=G
# * regex: Regular expression to filter the process(es)
# * refresh: The AMP is executed every refresh seconds
# * one_line: (optional) Force (if true) the AMP to be displayed in one line
* * command: (optional) command to execute when the process is detected (thk to the regex)
# * command: (optional) command to execute when the process is detected (thk to the regex)
# * countmin: (optional) minimal number of processes
# A warning will be displayed if number of process < count
# * countmax: (optional) maximum number of processes

View File

@@ -27,7 +27,7 @@ from glances.timer import Timer
try:
import pystache
except ImportError:
logger.warning("PyStache lib not installed (action script with mustache will not work)")
logger.debug("Pystache library not found (action scripts won't work)")
pystache_tag = False
else:
pystache_tag = True

View File

@@ -133,5 +133,5 @@ class GlancesAttribute(object):
def history_mean(self, nb=5):
"""Return the mean on the <nb> values in the history.
"""
d, v = zip(*self._history)
_, v = zip(*self._history)
return sum(v[-nb:]) / float(v[-1] - v[-nb])

View File

@@ -20,6 +20,7 @@
"""Cassandra/Scylla interface class."""
import sys
from datetime import datetime
from numbers import Number
from glances.compat import NoOptionError, NoSectionError
@@ -29,7 +30,6 @@ from glances.exports.glances_export import GlancesExport
from cassandra.cluster import Cluster
from cassandra.util import uuid_from_time
from cassandra import InvalidRequest
from datetime import datetime
class Export(GlancesExport):
@@ -118,7 +118,7 @@ class Export(GlancesExport):
# Table
try:
session.execute("CREATE TABLE %s (plugin text, time timeuuid, stat map<text,float>, PRIMARY KEY (plugin, time)) WITH CLUSTERING ORDER BY (time DESC)" % self.table)
except:
except Exception:
logger.debug("Cassandra table %s already exist" % self.table)
return cluster, session

View File

@@ -93,7 +93,7 @@ class FolderList(object):
for i in ['careful', 'warning', 'critical']:
try:
value[i] = self.config.get_value(section, key + i)
except:
except Exception:
value[i] = None
logger.debug("No {} threshold for folder {}".format(i, value["path"]))

View File

@@ -19,11 +19,14 @@
"""Custom logger class."""
import logging
import os
import tempfile
import json
from logging.config import dictConfig
import logging
import logging.config
LOG_FILENAME = os.path.join(tempfile.gettempdir(), 'glances.log')
# Define the logging configuration
LOGGING_CFG = {
@@ -48,8 +51,7 @@ LOGGING_CFG = {
"file": {
"level": "DEBUG",
"class": "logging.handlers.RotatingFileHandler",
"formatter": "standard",
'filename': os.path.join(tempfile.gettempdir(), 'glances.log')
"formatter": "standard"
},
"console": {
"level": "CRITICAL",
@@ -88,14 +90,13 @@ LOGGING_CFG = {
def tempfile_name():
"""Return the tempfile name (full path)."""
ret = os.path.join(tempfile.gettempdir(), 'glances.log')
if os.access(ret, os.F_OK) and not os.access(ret, os.W_OK):
print("WARNING: Couldn't write to log file {} (Permission denied)".format(ret))
ret = tempfile.mkstemp(prefix='glances', suffix='.log', text=True)
print("Create a new log file: {}".format(ret[1]))
if os.access(LOG_FILENAME, os.F_OK) and not os.access(LOG_FILENAME, os.W_OK):
print("WARNING: Couldn't write to '{}' (Permission denied)".format(LOG_FILENAME))
ret = tempfile.mkstemp(prefix='glances-', suffix='.log', text=True)
print("Create log file at '{}'".format(ret[1]))
return ret[1]
return ret
return LOG_FILENAME
def glances_logger(env_key='LOG_CFG'):
@@ -111,7 +112,7 @@ def glances_logger(env_key='LOG_CFG'):
# Overwrite the default logger file
LOGGING_CFG['handlers']['file']['filename'] = tempfile_name()
# By default, use the LOGGING_CFG lgger configuration
# By default, use the LOGGING_CFG logger configuration
config = LOGGING_CFG
# Check if a specific configuration is available
@@ -122,8 +123,9 @@ def glances_logger(env_key='LOG_CFG'):
config = json.load(f)
# Load the configuration
dictConfig(config)
logging.config.dictConfig(config)
return _logger
logger = glances_logger()

View File

@@ -27,7 +27,6 @@ from io import open
import webbrowser
from glances.timer import Timer
from glances.globals import WINDOWS
from glances.logger import logger
try:
@@ -134,9 +133,7 @@ class GlancesBottle(object):
# Try to open the Glances Web UI in the default Web browser if:
# 1) --open-web-browser option is used
# 2) Glances standalone mode is running on Windows OS
webbrowser.open(bindurl,
new=2,
autoraise=1)
webbrowser.open(bindurl, new=2, autoraise=1)
self._app.run(host=self.args.bind_address, port=self.args.port, quiet=not self.args.debug)
def end(self):

View File

@@ -36,8 +36,7 @@ if not WINDOWS:
import curses.panel
from curses.textpad import Textbox
except ImportError:
logger.critical(
"Curses module not found. Glances cannot start in standalone mode.")
logger.critical("Curses module not found. Glances cannot start in standalone mode.")
sys.exit(1)
else:
from glances.outputs.glances_colorconsole import WCurseLight
@@ -87,8 +86,7 @@ class _GlancesCurses(object):
'm': {'auto_sort': False, 'sort_key': 'memory_percent'},
'p': {'auto_sort': False, 'sort_key': 'name'},
't': {'auto_sort': False, 'sort_key': 'cpu_times'},
'u': {'auto_sort': False, 'sort_key': 'username'},
'c': {'auto_sort': False, 'sort_key': 'cpu_percent'}
'u': {'auto_sort': False, 'sort_key': 'username'}
}
def __init__(self, config=None, args=None):
@@ -141,7 +139,7 @@ class _GlancesCurses(object):
self._init_history()
def load_config(self, config):
'''Load the outputs section of the configuration file'''
"""Load the outputs section of the configuration file."""
# Load the theme
if config is not None and config.has_section('outputs'):
logger.debug('Read the outputs section in the configuration file')
@@ -149,11 +147,11 @@ class _GlancesCurses(object):
logger.debug('Theme for the curse interface: {}'.format(self.theme['name']))
def is_theme(self, name):
'''Return True if the theme *name* should be used'''
"""Return True if the theme *name* should be used."""
return getattr(self.args, 'theme_' + name) or self.theme['name'] == name
def _init_history(self):
'''Init the history option'''
"""Init the history option."""
self.reset_history_tag = False
self.graph_tag = False
@@ -167,7 +165,7 @@ class _GlancesCurses(object):
logger.error('Export graphs disabled')
def _init_cursor(self):
'''Init cursors'''
"""Init cursors."""
if hasattr(curses, 'noecho'):
curses.noecho()
@@ -176,7 +174,7 @@ class _GlancesCurses(object):
self.set_cursor(0)
def _init_colors(self):
'''Init the Curses color layout'''
"""Init the Curses color layout."""
# Set curses options
if hasattr(curses, 'start_color'):
@@ -776,12 +774,11 @@ class _GlancesCurses(object):
# Only in standalone mode (cs_status is None)
if self.edit_filter and cs_status is None:
new_filter = self.display_popup(
'Process filter pattern: \n' +
'\n' +
'Process filter pattern: \n\n' +
'Examples:\n' +
'- python\n' +
'- .*python.*\n' +
'- \/usr\/lib.*' +
'- \/usr\/lib.*\n' +
'- name:.*nautilus.*\n' +
'- cmdline:.*glances.*\n' +
'- username:nicolargo\n' +
@@ -789,7 +786,7 @@ class _GlancesCurses(object):
is_input=True,
input_value=glances_processes.process_filter_input)
glances_processes.process_filter = new_filter
elif self.edit_filter and cs_status != 'None':
elif self.edit_filter and cs_status is not None:
self.display_popup('Process filter only available in standalone mode')
self.edit_filter = False

View File

@@ -38,7 +38,7 @@ class GlancesPasswordList(GlancesPassword):
def load(self, config):
"""Load the password from the configuration file."""
password_dict = []
password_dict = {}
if config is None:
logger.warning("No configuration file available. Cannot load password list.")
@@ -70,7 +70,6 @@ class GlancesPasswordList(GlancesPassword):
return self._password_dict['default']
except (KeyError, TypeError):
return None
return None
def set_password(self, host, password):
"""Set a password for a specific host."""

View File

@@ -64,8 +64,7 @@ class Plugin(GlancesPlugin):
'timer': v.time_until_refresh(),
'count': v.count(),
'countmin': v.count_min(),
'countmax': v.count_max(),
})
'countmax': v.count_max()})
else:
# Not available in SNMP mode
pass

View File

@@ -158,7 +158,7 @@ class Plugin(GlancesPlugin):
# First time, try to connect to the server
try:
self.docker_client = self.connect()
except:
except Exception:
docker_tag = False
else:
if self.docker_client is None:

View File

@@ -1,239 +1,239 @@
# -*- coding: utf-8 -*-
#
# This file is part of Glances.
#
# Copyright (C) 2016 Kirby Banman <kirby.banman@gmail.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Glances is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""GPU plugin (limited to NVIDIA chipsets)"""
from glances.logger import logger
from glances.plugins.glances_plugin import GlancesPlugin
try:
import pynvml
except ImportError:
logger.debug("Could not import pynvml. NVIDIA stats will not be collected.")
gpu_nvidia_tag = False
else:
gpu_nvidia_tag = True
class Plugin(GlancesPlugin):
"""Glances GPU plugin (limited to NVIDIA chipsets).
stats is a list of dictionaries with one entry per GPU
"""
def __init__(self, args=None):
"""Init the plugin"""
super(Plugin, self).__init__(args=args)
# Init the NVidia API
self.init_nvidia()
# We want to display the stat in the curse interface
self.display_curse = True
# Init the stats
self.reset()
def reset(self):
"""Reset/init the stats."""
self.stats = []
def init_nvidia(self):
"""Init the NVIDIA API"""
if not gpu_nvidia_tag:
self.nvml_ready = False
try:
pynvml.nvmlInit()
self.device_handles = self.get_device_handles()
self.nvml_ready = True
except Exception:
logger.debug("pynvml could not be initialized.")
self.nvml_ready = False
return self.nvml_ready
def get_key(self):
"""Return the key of the list."""
return 'gpu_id'
@GlancesPlugin._check_decorator
@GlancesPlugin._log_result_decorator
def update(self):
"""Update the GPU stats"""
self.reset()
# !!! JUST FOR TEST
# self.stats = [{"key": "gpu_id", "mem": None, "proc": 60, "gpu_id": 0, "name": "GeForce GTX 560 Ti"}]
# self.stats = [{"key": "gpu_id", "mem": 30, "proc": 60, "gpu_id": 0, "name": "GeForce GTX 560 Ti"},
# {"key": "gpu_id", "mem": 70, "proc": 80, "gpu_id": 1, "name": "GeForce GTX 560 Ti"}]
# !!! TO BE REMOVED
if not self.nvml_ready:
return self.stats
if self.input_method == 'local':
self.stats = self.get_device_stats()
elif self.input_method == 'snmp':
# not available
pass
return self.stats
def update_views(self):
"""Update stats views."""
# Call the father's method
super(Plugin, self).update_views()
# Add specifics informations
# Alert
for i in self.stats:
# Init the views for the current GPU
self.views[i[self.get_key()]] = {'proc': {}, 'mem': {}}
# Processor alert
if 'proc' in i:
alert = self.get_alert(i['proc'], header='proc')
self.views[i[self.get_key()]]['proc']['decoration'] = alert
# Memory alert
if 'mem' in i:
alert = self.get_alert(i['mem'], header='mem')
self.views[i[self.get_key()]]['mem']['decoration'] = alert
return True
def msg_curse(self, args=None):
"""Return the dict to display in the curse interface."""
# Init the return message
ret = []
# Only process if stats exist, not empty (issue #871) and plugin not disabled
if not self.stats or (self.stats == []) or self.is_disable():
return ret
# Build the string message
if len(self.stats) == 1:
# Mono GPU
gpu_stats = self.stats[0]
# Header
header = '{} {}'.format('GPU', gpu_stats['name'])
msg = header[:16]
ret.append(self.curse_add_line(msg, "TITLE"))
# New line
ret.append(self.curse_new_line())
# GPU CPU
msg = '{:8}'.format('proc:')
ret.append(self.curse_add_line(msg))
msg = '{:>7d}%'.format(int(gpu_stats['proc']))
ret.append(self.curse_add_line(
msg, self.get_views(item=gpu_stats[self.get_key()],
key='proc',
option='decoration')))
# New line
ret.append(self.curse_new_line())
# GPU MEM
msg = '{:8}'.format('mem:')
ret.append(self.curse_add_line(msg))
if gpu_stats['mem'] is None:
msg = '{:>8}'.format('N/A')
else:
msg = '{:>7d}%'.format(int(gpu_stats['mem']))
ret.append(self.curse_add_line(
msg, self.get_views(item=gpu_stats[self.get_key()],
key='mem',
option='decoration')))
else:
# Multi GPU
# Header
header = '{} {}'.format(len(self.stats), 'GPUs')
msg = header[:16]
ret.append(self.curse_add_line(msg, "TITLE"))
for gpu_stats in self.stats:
# New line
ret.append(self.curse_new_line())
# GPU ID + PROC + MEM
msg = '{}: {:>3}% mem: {:>3}%'.format(gpu_stats['gpu_id'],
gpu_stats['proc'],
gpu_stats['mem'],)
ret.append(self.curse_add_line(msg))
return ret
def get_device_handles(self):
"""
Returns a list of NVML device handles, one per device. Can throw NVMLError.
"""
return [pynvml.nvmlDeviceGetHandleByIndex(i) for i in range(0, pynvml.nvmlDeviceGetCount())]
def get_device_stats(self):
"""Get GPU stats"""
stats = []
for index, device_handle in enumerate(self.device_handles):
device_stats = {}
# Dictionnary key is the GPU_ID
device_stats['key'] = self.get_key()
# GPU id (for multiple GPU, start at 0)
device_stats['gpu_id'] = index
# GPU name
device_stats['name'] = self.get_device_name(device_handle)
# Memory consumption in % (not available on all GPU)
device_stats['mem'] = self.get_mem(device_handle)
# Processor consumption in %
device_stats['proc'] = self.get_proc(device_handle)
stats.append(device_stats)
return stats
def get_device_name(self, device_handle):
"""Get GPU device name"""
try:
return pynvml.nvmlDeviceGetName(device_handle)
except pynvml.NVMlError:
return "NVIDIA GPU"
def get_mem(self, device_handle):
"""Get GPU device memory consumption in percent"""
try:
return pynvml.nvmlDeviceGetUtilizationRates(device_handle).memory
except pynvml.NVMLError:
try:
memory_info = pynvml.nvmlDeviceGetMemoryInfo(device_handle)
return memory_info.used * 100 / memory_info.total
except pynvml.NVMLError:
return None
def get_proc(self, device_handle):
"""Get GPU device CPU consumption in percent"""
try:
return pynvml.nvmlDeviceGetUtilizationRates(device_handle).gpu
except pynvml.NVMLError:
return None
def exit(self):
"""Overwrite the exit method to close the GPU API"""
if self.nvml_ready:
try:
pynvml.nvmlShutdown()
except Exception as e:
logger.debug("pynvml failed to shutdown correctly ({})".format(e))
# Call the father exit method
super(Plugin, self).exit()
#
# This file is part of Glances.
#
# Copyright (C) 2016 Kirby Banman <kirby.banman@gmail.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Glances is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""GPU plugin (limited to NVIDIA chipsets)"""
from glances.logger import logger
from glances.plugins.glances_plugin import GlancesPlugin
try:
import pynvml
except ImportError:
logger.debug("Could not import pynvml. NVIDIA stats will not be collected.")
gpu_nvidia_tag = False
else:
gpu_nvidia_tag = True
class Plugin(GlancesPlugin):
"""Glances GPU plugin (limited to NVIDIA chipsets).
stats is a list of dictionaries with one entry per GPU
"""
def __init__(self, args=None):
"""Init the plugin"""
super(Plugin, self).__init__(args=args)
# Init the NVidia API
self.init_nvidia()
# We want to display the stat in the curse interface
self.display_curse = True
# Init the stats
self.reset()
def reset(self):
"""Reset/init the stats."""
self.stats = []
def init_nvidia(self):
"""Init the NVIDIA API"""
if not gpu_nvidia_tag:
self.nvml_ready = False
try:
pynvml.nvmlInit()
self.device_handles = self.get_device_handles()
self.nvml_ready = True
except Exception:
logger.debug("pynvml could not be initialized.")
self.nvml_ready = False
return self.nvml_ready
def get_key(self):
"""Return the key of the list."""
return 'gpu_id'
@GlancesPlugin._check_decorator
@GlancesPlugin._log_result_decorator
def update(self):
"""Update the GPU stats"""
self.reset()
# !!! JUST FOR TEST
# self.stats = [{"key": "gpu_id", "mem": None, "proc": 60, "gpu_id": 0, "name": "GeForce GTX 560 Ti"}]
# self.stats = [{"key": "gpu_id", "mem": 30, "proc": 60, "gpu_id": 0, "name": "GeForce GTX 560 Ti"},
# {"key": "gpu_id", "mem": 70, "proc": 80, "gpu_id": 1, "name": "GeForce GTX 560 Ti"}]
# !!! TO BE REMOVED
if not self.nvml_ready:
return self.stats
if self.input_method == 'local':
self.stats = self.get_device_stats()
elif self.input_method == 'snmp':
# not available
pass
return self.stats
def update_views(self):
"""Update stats views."""
# Call the father's method
super(Plugin, self).update_views()
# Add specifics informations
# Alert
for i in self.stats:
# Init the views for the current GPU
self.views[i[self.get_key()]] = {'proc': {}, 'mem': {}}
# Processor alert
if 'proc' in i:
alert = self.get_alert(i['proc'], header='proc')
self.views[i[self.get_key()]]['proc']['decoration'] = alert
# Memory alert
if 'mem' in i:
alert = self.get_alert(i['mem'], header='mem')
self.views[i[self.get_key()]]['mem']['decoration'] = alert
return True
def msg_curse(self, args=None):
"""Return the dict to display in the curse interface."""
# Init the return message
ret = []
# Only process if stats exist, not empty (issue #871) and plugin not disabled
if not self.stats or (self.stats == []) or self.is_disable():
return ret
# Build the string message
if len(self.stats) == 1:
# Mono GPU
gpu_stats = self.stats[0]
# Header
header = '{} {}'.format('GPU', gpu_stats['name'])
msg = header[:16]
ret.append(self.curse_add_line(msg, "TITLE"))
# New line
ret.append(self.curse_new_line())
# GPU CPU
msg = '{:8}'.format('proc:')
ret.append(self.curse_add_line(msg))
if gpu_stats['proc'] is None:
msg = '{:>8}'.format('N/A')
else:
msg = '{:>7d}%'.format(int(gpu_stats['proc']))
ret.append(self.curse_add_line(
msg, self.get_views(item=gpu_stats[self.get_key()],
key='proc',
option='decoration')))
# New line
ret.append(self.curse_new_line())
# GPU MEM
msg = '{:8}'.format('mem:')
ret.append(self.curse_add_line(msg))
if gpu_stats['mem'] is None:
msg = '{:>8}'.format('N/A')
else:
msg = '{:>7d}%'.format(int(gpu_stats['mem']))
ret.append(self.curse_add_line(
msg, self.get_views(item=gpu_stats[self.get_key()],
key='mem',
option='decoration')))
else:
# Multi GPU
# Header
header = '{} {}'.format(len(self.stats), 'GPUs')
msg = header[:16]
ret.append(self.curse_add_line(msg, "TITLE"))
for gpu_stats in self.stats:
# New line
ret.append(self.curse_new_line())
# GPU ID + PROC + MEM
msg = '{}: {:>3}% mem: {:>3}%'.format(gpu_stats['gpu_id'],
gpu_stats['proc'],
gpu_stats['mem'],)
ret.append(self.curse_add_line(msg))
return ret
def get_device_handles(self):
"""
Returns a list of NVML device handles, one per device. Can throw NVMLError.
"""
return [pynvml.nvmlDeviceGetHandleByIndex(i) for i in range(pynvml.nvmlDeviceGetCount())]
def get_device_stats(self):
"""Get GPU stats"""
stats = []
for index, device_handle in enumerate(self.device_handles):
device_stats = {}
# Dictionnary key is the GPU_ID
device_stats['key'] = self.get_key()
# GPU id (for multiple GPU, start at 0)
device_stats['gpu_id'] = index
# GPU name
device_stats['name'] = self.get_device_name(device_handle)
# Memory consumption in % (not available on all GPU)
device_stats['mem'] = self.get_mem(device_handle)
# Processor consumption in %
device_stats['proc'] = self.get_proc(device_handle)
stats.append(device_stats)
return stats
def get_device_name(self, device_handle):
"""Get GPU device name"""
try:
return pynvml.nvmlDeviceGetName(device_handle)
except pynvml.NVMlError:
return "NVIDIA GPU"
def get_mem(self, device_handle):
"""Get GPU device memory consumption in percent"""
try:
memory_info = pynvml.nvmlDeviceGetMemoryInfo(device_handle)
return memory_info.used * 100 / memory_info.total
except pynvml.NVMLError:
return None
def get_proc(self, device_handle):
"""Get GPU device CPU consumption in percent"""
try:
return pynvml.nvmlDeviceGetUtilizationRates(device_handle).gpu
except pynvml.NVMLError:
return None
def exit(self):
"""Overwrite the exit method to close the GPU API"""
if self.nvml_ready:
try:
pynvml.nvmlShutdown()
except Exception as e:
logger.debug("pynvml failed to shutdown correctly ({})".format(e))
# Call the father exit method
super(Plugin, self).exit()

View File

@@ -173,9 +173,9 @@ class PublicIpAddress(object):
t.daemon = True
t.start()
t = Timer(self.timeout)
timer = Timer(self.timeout)
ip = None
while not t.finished() and ip is None:
while not timer.finished() and ip is None:
if q.qsize() > 0:
ip = q.get()

View File

@@ -22,7 +22,6 @@
import os
import operator
from glances.logger import logger
from glances.globals import LINUX
from glances.timer import getTimeSinceLastUpdate
from glances.plugins.glances_plugin import GlancesPlugin

View File

@@ -98,7 +98,7 @@ class Plugin(GlancesPlugin):
netstatus = {}
try:
netstatus = psutil.net_if_stats()
except:
except AttributeError:
pass
# Previous network interface stats are stored in the network_old variable

View File

@@ -251,7 +251,7 @@ class ThreadScanner(threading.Thread):
try:
ret = _socket.connect_ex((ip, int(port['port'])))
except Exception as e:
logger.debug("0}: Error while scanning port {} ({})".format(self.plugin_name, port, e))
logger.debug("{}: Error while scanning port {} ({})".format(self.plugin_name, port, e))
else:
if ret == 0:
port['status'] = counter.get()

View File

@@ -28,7 +28,7 @@ import psutil
cpuinfo_tag = False
try:
from cpuinfo import cpuinfo
except:
except ImportError:
# Correct issue #754
# Waiting for a correction on the upstream Cpuinfo lib
pass

View File

@@ -182,7 +182,7 @@ class Plugin(GlancesPlugin):
for i in self.stats:
# Do not display anything if no battery are detected
if (i['type'] == 'battery' and i['value'] == []):
if i['type'] == 'battery' and i['value'] == []:
continue
# New line
ret.append(self.curse_new_line())

View File

@@ -19,11 +19,9 @@
"""Wifi plugin."""
import base64
import operator
from glances.logger import logger
from glances.timer import getTimeSinceLastUpdate
from glances.plugins.glances_plugin import GlancesPlugin
import psutil
@@ -32,7 +30,7 @@ import psutil
try:
from wifi.scan import Cell
from wifi.exceptions import InterfaceError
except ImportError as e:
except ImportError:
logger.debug("Wifi library not found. Glances cannot grab Wifi info.")
wifi_tag = False
else:
@@ -190,7 +188,7 @@ class Plugin(GlancesPlugin):
hotspotname = i['ssid']
# Add the encryption type (if it is available)
if i['encrypted']:
hotspotname = hotspotname + ' {}'.format(i['encryption_type'])
hotspotname += ' {}'.format(i['encryption_type'])
# Cut hotspotname if it is too long
if len(hotspotname) > ifname_max_width:
hotspotname = '_' + hotspotname[-ifname_max_width + 1:]

View File

@@ -475,9 +475,9 @@ class GlancesProcesses(object):
# ignore the 'kernel_task' process on OS X
# waiting for upstream patch from psutil
if (s is None or
BSD and s['name'] == 'idle' or
WINDOWS and s['name'] == 'System Idle Process' or
OSX and s['name'] == 'kernel_task'):
BSD and s['name'] == 'idle' or
WINDOWS and s['name'] == 'System Idle Process' or
OSX and s['name'] == 'kernel_task'):
continue
# Continue to the next process if it has to be filtered
if self._filter.is_filtered(s):

View File

@@ -1,25 +1,30 @@
#!/usr/bin/env python
import glob
import sys
import os
import re
import sys
from io import open
from setuptools import setup, Command
if sys.version_info < (2, 7) or (3, 0) <= sys.version_info < (3, 3):
print('Glances requires at least Python 2.7 or 3.3 to run.')
sys.exit(1)
# Global functions
##################
def get_version():
"""Get version inside the __init__.py file"""
init_file = open("glances/__init__.py").read()
reg_version = r"^__version__ = ['\"]([^'\"]*)['\"]"
find_version = re.search(reg_version, init_file, re.M)
if find_version:
return find_version.group(1)
else:
print("Can not retreive Glances version in the glances/__init__.py file.")
sys.exit(1)
with open(os.path.join('glances', '__init__.py'), encoding='utf-8') as f:
version = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", f.read(), re.M).group(1)
if not version:
raise RuntimeError('Cannot find Glances version information.')
with open('README.rst', encoding='utf-8') as f:
long_description = f.read()
def get_data_files():
@@ -56,23 +61,14 @@ class tests(Command):
raise SystemExit(ret)
raise SystemExit(0)
# Global vars
#############
glances_version = get_version()
if sys.version_info < (2, 7) or (3, 0) <= sys.version_info < (3, 3):
print('Glances {} require at least Python 2.7 or 3.3 to run.'.format(glances_version))
print('Please install Glances 2.6.2 on your system.')
sys.exit(1)
# Setup !
setup(
name='Glances',
version=glances_version,
version=version,
description="A cross-platform curses-based monitoring tool",
long_description=open('README.rst').read(),
long_description=long_description,
author='Nicolas Hennion',
author_email='nicolas@nicolargo.com',
url='https://github.com/nicolargo/glances',