Resolv first conflict

This commit is contained in:
nicolargo 2022-07-26 10:37:44 +02:00
commit dfe0f642ea
38 changed files with 655 additions and 523 deletions

View File

@ -34,6 +34,18 @@ jobs:
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --exclude=.git,./docs,./glances/outputs/static
- name: Static type check
run: |
if [ "${{ matrix.python-version }}" == "2.7" ];
then
echo "Skipping static type check for Python 2.7";
else
echo "Skipping static type check for the moment, too much error...";
# pip install pyright
# pyright glances
fi
- name: Unitary tests
run: |
python ./unitest.py

View File

@ -37,6 +37,7 @@ test: venv ## Run unit tests
./venv/bin/python ./unitest-restful.py
./venv/bin/python ./unitest-xmlrpc.py
./venv/bin/python -m black ./glances --check --exclude outputs/static
./venv/bin/pyright glances
format: venv ## Format the code
./venv/bin/python -m black ./glances --exclude outputs/static

View File

@ -223,16 +223,16 @@ create your own Dockerfile:
CMD python -m glances -C /etc/glances.conf $GLANCES_OPT
Alternatively, you can specify something along the same lines with
docker run options:
docker run options (notice the `GLANCES_OPT` environment
variable setting parameters for the glances startup command):
.. code-block:: console
docker run -v `pwd`/glances.conf:/etc/glances.conf -v /var/run/docker.sock:/var/run/docker.sock:ro --pid host -it nicolargo/glances:latest-full
docker run -v `pwd`/glances.conf:/etc/glances.conf -v /var/run/docker.sock:/var/run/docker.sock:ro --pid host -e GLANCES_OPT="-C /etc/glances.conf" -it nicolargo/glances:latest-full
Where \`pwd\`/glances.conf is a local directory containing your glances.conf file.
Run the container in *Web server mode* (notice the `GLANCES_OPT` environment
variable setting parameters for the glances startup command):
Run the container in *Web server mode*:
.. code-block:: console
@ -446,9 +446,9 @@ There is also a chat dedicated to the Glances developers:
Donation
========
If this project help you, you can give me a tip ;)
If you like this open-source project, you can become a sponsor.
See the sponsors_ page.
See the sponsors_ page (one-time or monthly tier available).
Author
======

View File

@ -524,6 +524,7 @@ port=8125
# Configuration for the --export elasticsearch option
# Data are available via the ES RESTful API. ex: URL/<index>/cpu
# https://www.elastic.co
scheme=http
host=localhost
port=9200
index=glances
@ -547,7 +548,7 @@ queue=glances_queue
# Configuration for the --export mqtt option
host=localhost
port=8883
tls=true
tls=false
user=guest
password=guest
topic=glances

View File

@ -1,2 +1,3 @@
py-spy
black
black
pyright

View File

@ -7,10 +7,8 @@ services:
restart: always
ports:
- "61208:61208"
# - "61209:61209"
environment:
# - GLANCES_OPT="-w"
GLANCES_OPT: "-w"
GLANCES_OPT: "-C /glances/conf/glances.conf -w"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./glances.conf:/glances/conf/glances.conf"

File diff suppressed because it is too large Load Diff

View File

@ -297,8 +297,14 @@ The following commands (key pressed) are supported while in Glances:
``I``
Show/hide IP module
``+``
Increase selected process nice level / Lower the priority (need right) - Only in standalone mode.
``-``
Decrease selected process nice level / Higher the priority (need right) - Only in standalone mode.
``k``
Kill selected process
Kill selected process (need right) - Only in standalone mode.
``K``
Show/hide TCP connections

View File

@ -15,7 +15,13 @@ listening on <host:port> (define in the Glances configuration file).
prefix=glances
labels=src:glances
Note: you can use dynamc fields for the label (ex: labels=system:`uname -s`)
.. note::
When running Glances in a container, set ``host=0.0.0.0`` in the Glances configuration file.
.. note::
You can use dynamic fields for the label (ex: labels=system:`uname -s`)
and run Glances with:

View File

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "GLANCES" "1" "Jul 05, 2022" "3.2.7_beta01" "Glances"
.TH "GLANCES" "1" "Jul 24, 2022" "3.2.7_beta01" "Glances"
.SH NAME
glances \- An eye on your system
.SH SYNOPSIS
@ -400,8 +400,14 @@ Sort processes by I/O rate
.B \fBI\fP
Show/hide IP module
.TP
.B \fB+\fP
Increase selected process nice level / Lower the priority (need right) \- Only in standalone mode.
.TP
.B \fB\-\fP
Decrease selected process nice level / Higher the priority (need right) \- Only in standalone mode.
.TP
.B \fBk\fP
Kill selected process
Kill selected process (need right) \- Only in standalone mode.
.TP
.B \fBK\fP
Show/hide TCP connections

View File

@ -31,7 +31,7 @@ class Export(GlancesExport):
self.index = None
# Load the ES configuration file
self.export_enable = self.load_conf('elasticsearch', mandatories=['host', 'port', 'index'], options=[])
self.export_enable = self.load_conf('elasticsearch', mandatories=['scheme', 'host', 'port', 'index'], options=[])
if not self.export_enable:
sys.exit(2)
@ -44,12 +44,22 @@ class Export(GlancesExport):
return None
try:
es = Elasticsearch(hosts=['{}:{}'.format(self.host, self.port)])
es = Elasticsearch(hosts=['{}://{}:{}'.format(self.scheme, self.host, self.port)])
except Exception as e:
logger.critical("Cannot connect to ElasticSearch server %s:%s (%s)" % (self.host, self.port, e))
logger.critical("Cannot connect to ElasticSearch server %s://%s:%s (%s)" % (self.scheme,
self.host,
self.port, e))
sys.exit(2)
if not es.ping():
logger.critical("Cannot ping the ElasticSearch server %s://%s:%s" % (self.scheme,
self.host,
self.port))
sys.exit(2)
else:
logger.info("Connected to the ElasticSearch server %s:%s" % (self.host, self.port))
logger.info("Connected to the ElasticSearch server %s://%s:%s" % (self.scheme,
self.host,
self.port))
return es

View File

@ -42,7 +42,7 @@ class Export(GlancesExport):
'influxdb', mandatories=['host', 'port', 'user', 'password', 'db'], options=['protocol', 'prefix', 'tags']
)
if not self.export_enable:
sys.exit(2)
exit('Missing INFLUXDB version 1 config')
# The hostname is always add as a tag
self.hostname = node().split('.')[0]

View File

@ -79,7 +79,6 @@ class Export(GlancesExport):
client = None
else:
logger.info("Stats will be exported to Graphite server: {}:{}".format(self.host, self.port))
return client
def export(self, name, columns, points):

View File

@ -43,7 +43,7 @@ class Export(GlancesExport):
options=['protocol', 'prefix', 'tags'],
)
if not self.export_enable:
sys.exit(2)
exit('Missing INFLUXDB version 1 config')
# The hostname is always add as a tag
self.hostname = node().split('.')[0]

View File

@ -40,7 +40,7 @@ class Export(GlancesExport):
'kafka', mandatories=['host', 'port', 'topic'], options=['compression', 'tags']
)
if not self.export_enable:
sys.exit(2)
exit('Missing KAFKA config')
# Init the kafka client
self.client = self.init()

View File

@ -12,6 +12,7 @@
import socket
import string
import json
import sys
from glances.logger import logger
from glances.exports.export import GlancesExport
@ -44,7 +45,6 @@ class Export(GlancesExport):
# Get the current hostname
self.hostname = socket.gethostname()
self.port = int(self.port) or 8883
self.topic = self.topic or 'glances'
self.user = self.user or 'glances'
@ -53,10 +53,12 @@ class Export(GlancesExport):
self.topic_structure = (self.topic_structure or 'per-metric').lower()
if self.topic_structure not in ['per-metric', 'per-plugin']:
logger.critical("topic_structure must be either 'per-metric' or 'per-plugin'.")
return None
sys.exit(2)
# Init the MQTT client
self.client = self.init()
if not self.client:
exit("MQTT client initialization failed")
def init(self):
"""Init the connection to the MQTT server."""
@ -71,7 +73,7 @@ class Export(GlancesExport):
client.loop_start()
return client
except Exception as e:
logger.critical("Connection to MQTT server failed : %s " % e)
logger.critical("Connection to MQTT server %s:%s failed with error: %s " % (self.host, self.port, e))
return None
def export(self, name, columns, points):

View File

@ -36,7 +36,7 @@ class Export(GlancesExport):
# Load the configuration file
self.export_enable = self.load_conf('opentsdb', mandatories=['host', 'port'], options=['prefix', 'tags'])
if not self.export_enable:
sys.exit(2)
exit('Missing OPENTSDB config')
# Default prefix for stats is 'glances'
if self.prefix is None:

View File

@ -32,7 +32,7 @@ class Export(GlancesExport):
# Load the Prometheus configuration file section
self.export_enable = self.load_conf('prometheus', mandatories=['host', 'port', 'labels'], options=['prefix'])
if not self.export_enable:
sys.exit(2)
exit('Missing PROMETHEUS config')
# Optionals configuration keys
if self.prefix is None:

View File

@ -43,7 +43,7 @@ class Export(GlancesExport):
'rabbitmq', mandatories=['host', 'port', 'user', 'password', 'queue'], options=['protocol']
)
if not self.export_enable:
sys.exit(2)
exit('Missing RABBITMQ config')
# Get the current hostname
self.hostname = socket.gethostname()
@ -71,8 +71,8 @@ class Export(GlancesExport):
channel = connection.channel()
return channel
except Exception as e:
logger.critical("Connection to rabbitMQ failed : %s " % e)
return None
logger.critical("Connection to rabbitMQ server %s:%s failed. %s" % (self.host, self.port, e))
sys.exit(2)
def export(self, name, columns, points):
"""Write the points in RabbitMQ."""

View File

@ -34,7 +34,7 @@ class Export(GlancesExport):
# Load the RESTful section in the configuration file
self.export_enable = self.load_conf('restful', mandatories=['host', 'port', 'protocol', 'path'])
if not self.export_enable:
sys.exit(2)
exit('Missing RESTFUL config')
# Init the stats buffer
# It's a dict of stats

View File

@ -37,7 +37,7 @@ class Export(GlancesExport):
# Load the Riemann configuration
self.export_enable = self.load_conf('riemann', mandatories=['host', 'port'], options=[])
if not self.export_enable:
sys.exit(2)
exit('Missing RIEMANN config')
# Get the current hostname
self.hostname = socket.gethostname()

View File

@ -35,7 +35,7 @@ class Export(GlancesExport):
# Load the configuration file
self.export_enable = self.load_conf('statsd', mandatories=['host', 'port'], options=['prefix'])
if not self.export_enable:
sys.exit(2)
exit('Missing STATSD config')
# Default prefix for stats is 'glances'
if self.prefix is None:

View File

@ -37,7 +37,7 @@ class Export(GlancesExport):
# Load the ZeroMQ configuration file section ([export_zeromq])
self.export_enable = self.load_conf('zeromq', mandatories=['host', 'port', 'prefix'], options=[])
if not self.export_enable:
sys.exit(2)
exit('Missing ZEROMQ config')
# Init the ZeroMQ context
self.context = None

View File

@ -81,11 +81,15 @@ Examples of use:
Display CSV stats to stdout (all stats in one line):
$ glances --stdout-csv now,cpu.user,mem.used,load
Enable some plugins disabled by default (comma separated list):
$ glances --enable-plugin sensors
Disable some plugins (comma separated list):
$ glances --disable-plugin network,ports
Enable some plugins (comma separated list):
$ glances --enable-plugin sensors
Disable all plugins except some (comma separated list):
$ glances --disable-plugin all --enable-plugin cpu,mem,load
"""
def __init__(self):
@ -115,10 +119,16 @@ Examples of use:
help='display modules (plugins & exports) list and exit',
)
parser.add_argument(
'--disable-plugin', '--disable-plugins', dest='disable_plugin', help='disable plugin (comma separed list)'
'--disable-plugin',
'--disable-plugins',
dest='disable_plugin',
help='disable plugin (comma separed list or all). If all is used, then you need to configure --enable-plugin.',
)
parser.add_argument(
'--enable-plugin', '--enable-plugins', dest='enable_plugin', help='enable plugin (comma separed list)'
'--enable-plugin',
'--enable-plugins',
dest='enable_plugin',
help='enable plugin (comma separed list)'
)
parser.add_argument(
'--disable-process',
@ -551,6 +561,12 @@ Examples of use:
disable(args, s)
logger.debug('{} disabled by the configuration file'.format(s))
# The configuration key can be overwrite from the command line
if args and args.disable_plugin and 'all' in args.disable_plugin.split(','):
if not args.enable_plugin:
logger.critical("'all' key in --disable-plugin needs to be used with --enable-plugin")
sys.exit(2)
else:
logger.info("'all' key in --disable-plugin, only plugins defined with --enable-plugin will be available")
if args.disable_plugin is not None:
for p in args.disable_plugin.split(','):
disable(args, p)

View File

@ -90,6 +90,8 @@ class _GlancesCurses(object):
'W': {'switch': 'disable_wifi'},
# 'x' > Delete finished warning and critical logs
# 'z' > Enable or disable processes
# '+' > Increase the process nice level
# '-' > Decrease the process nice level
# "<" (left arrow) navigation through process sort
# ">" (right arrow) navigation through process sort
# 'UP' > Up in the server list
@ -161,6 +163,10 @@ class _GlancesCurses(object):
# Init edit filter tag
self.edit_filter = False
# Init nice increase/decrease tag
self.increase_nice_process = False
self.decrease_nice_process = False
# Init kill process tag
self.kill_process = False
@ -414,6 +420,12 @@ class _GlancesCurses(object):
# 'f' > Show/hide fs / folder stats
self.args.disable_fs = not self.args.disable_fs
self.args.disable_folders = not self.args.disable_folders
elif self.pressedkey == ord('+'):
# '+' > Increase process nice level
self.increase_nice_process = not self.increase_nice_process
elif self.pressedkey == ord('-'):
# '+' > Decrease process nice level
self.decrease_nice_process = not self.decrease_nice_process
elif self.pressedkey == ord('k'):
# 'k' > Kill selected process (after confirmation)
self.kill_process = not self.kill_process
@ -682,10 +694,18 @@ class _GlancesCurses(object):
self.display_popup('Process filter only available in standalone mode')
self.edit_filter = False
# Manage increase/decrease nice level of the selected process
# Only in standalone mode (cs_status is None)
if self.increase_nice_process and cs_status is None:
self.nice_increase(stats.get_plugin('processlist').get_raw()[self.args.cursor_position])
self.increase_nice_process = False
if self.decrease_nice_process and cs_status is None:
self.nice_decrease(stats.get_plugin('processlist').get_raw()[self.args.cursor_position])
self.decrease_nice_process = False
# Display kill process confirmation popup
# Only in standalone mode (cs_status is None)
if self.kill_process and cs_status is None:
logger.info(stats.get_plugin('processlist').get_raw()[self.args.cursor_position])
self.kill(stats.get_plugin('processlist').get_raw()[self.args.cursor_position])
elif self.kill_process and cs_status is not None:
self.display_popup('Kill process only available for local processes')
@ -697,6 +717,12 @@ class _GlancesCurses(object):
return True
def nice_increase(self, process):
glances_processes.nice_increase(process['pid'])
def nice_decrease(self, process):
glances_processes.nice_decrease(process['pid'])
def kill(self, process):
"""Kill a process, or a list of process if the process has a childrens field.
@ -1123,6 +1149,11 @@ class _GlancesCurses(object):
# Were asked to refresh
return isexitkey
if pressedkey in (curses.KEY_UP, 65, curses.KEY_DOWN, 66):
# Up of won key pressed, reset the countdown
# Better for user experience
countdown.reset()
if isexitkey and self.args.help_tag:
# Quit from help should return to main screen, not exit #1874
self.args.help_tag = not self.args.help_tag

View File

@ -45,7 +45,7 @@
<div class="divTableCell">{{ vm.help.sort_process_name }}</div>
<div class="divTableCell">{{ vm.help.show_hide_filesystem }}</div>
<div class="divTableCell">{{ vm.help.toggle_separate_combined }}</div>
<div class="divTableCell">{{ vm.help.misc_kill_process }}</div>
<div class="divTableCell">{{ vm.help.misc_kill_process }} - N/A in WebUI</div>
</div>
<div class="divTableRow">
<div class="divTableCell">{{ vm.help.sort_cpu_times }}</div>
@ -81,7 +81,7 @@
<div class="divTableCell">&nbsp;</div>
<div class="divTableCell">{{ vm.help.sort_cpu_times }}</div>
<div class="divTableCell">&nbsp;</div>
<div class="divTableCell">{{ vm.help.misc_edit_process_filter_pattern }}</div>
<div class="divTableCell">{{ vm.help.misc_edit_process_filter_pattern }} - N/A in WebUI</div>
</div>
<div class="divTableRow">
<div class="divTableCell">&nbsp;</div>
@ -139,3 +139,11 @@
</div>
</div>
</div>
<div>
<p>For an exhaustive list of key bindings, <a href="https://glances.readthedocs.io/en/latest/cmds.html#interactive-commands">click here</a>.</p>
</div>
<div>
<p>Press <b>h</b> to came back to Glances.</p>
</div>

View File

@ -7,10 +7,10 @@
<div class="table-cell" ng-show="vm.arguments.diskio_iops">IOW/s</div>
</div>
<div class="table-row" ng-repeat="disk in vm.disks">
<div class="table-cell text-left">{{(disk.alias ? disk.alias : disk.name) | min_size:9}}</div>
<div class="table-cell" ng-show="!vm.arguments.diskio_iops">{{disk.bitrate.txps }}</div>
<div class="table-cell" ng-show="!vm.arguments.diskio_iops">{{disk.bitrate.rxps }}</div>
<div class="table-cell text-left">{{ (disk.alias ? disk.alias : disk.name) | min_size:32 }}</div>
<div class="table-cell" ng-show="!vm.arguments.diskio_iops">{{ disk.bitrate.txps }}</div>
<div class="table-cell" ng-show="!vm.arguments.diskio_iops">{{ disk.bitrate.rxps }}</div>
<div class="table-cell" ng-show="vm.arguments.diskio_iops">{{disk.count.txps }}</div>
<div class="table-cell" ng-show="vm.arguments.diskio_iops">{{disk.count.rxps }}</div>
<div class="table-cell" ng-show="vm.arguments.diskio_iops">{{ disk.count.txps }}</div>
<div class="table-cell" ng-show="vm.arguments.diskio_iops">{{ disk.count.rxps }}</div>
</div>

View File

@ -22,8 +22,8 @@ export default function GlancesPluginFsController($scope, $filter, GlancesStats,
var fsData = stats[i];
var shortMountPoint = fsData['mnt_point'];
if (shortMountPoint.length > 9) {
shortMountPoint = '_' + fsData['mnt_point'].slice(-8);
if (shortMountPoint.length > 22) {
shortMountPoint = '_' + fsData['mnt_point'].slice(-21);
}
vm.fileSystems.push({

View File

@ -7,8 +7,8 @@
<div class="table-cell">Total</div>
</div>
<div class="table-row" ng-repeat="fs in vm.fileSystems">
<div class="table-cell text-left">{{ fs.shortMountPoint }} <span class="visible-lg-inline"
ng-show="fs.name.length <= 20">({{ fs.name }})</span>
<div class="table-cell text-left">{{ fs.shortMountPoint }}
<span class="visible-lg-inline" ng-show="fs.shortMountPoint <= 12">({{ fs.name }})</span>
</div>
<div class="table-cell" ng-class="vm.getDecoration(fs.mountPoint, 'used')">
<span ng-show="!vm.arguments.fs_free_space">{{ fs.used | bytes }}</span>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -187,10 +187,7 @@ class PluginModel(GlancesPluginModel):
if all([self.get_views(item=i[self.get_key()], key=f, option='hidden') for f in self.hide_zero_fields]):
continue
# Is there an alias for the disk name ?
disk_real_name = i['disk_name']
disk_name = self.has_alias(i['disk_name'])
if disk_name is None:
disk_name = disk_real_name
disk_name = self.has_alias(i['disk_name']) if self.has_alias(i['disk_name']) else i['disk_name']
# New line
ret.append(self.curse_new_line())
if len(disk_name) > name_max_width:

View File

@ -106,6 +106,8 @@ class PluginModel(GlancesPluginModel):
self.view_data['misc_generate_history_graphs'] = msg_col.format('g', 'Generate history graphs')
self.view_data['misc_help'] = msg_col.format('h', 'HELP')
self.view_data['misc_accumulate_processes_by_program'] = msg_col.format('j', 'Accumulate processes by program')
self.view_data['misc_increase_nice_process'] = msg_col.format('+', 'Increase nice process (need admin rights)')
self.view_data['misc_decrease_nice_process'] = msg_col.format('-', 'Decrease nice process')
self.view_data['misc_kill_process'] = msg_col.format('k', 'Kill process')
self.view_data['misc_reset_processes_summary_min_max'] = msg_col.format('M', 'Reset processes summary min/max')
self.view_data['misc_quit'] = msg_col.format('q', 'QUIT (or Esc or Ctrl-C)')
@ -214,5 +216,10 @@ class PluginModel(GlancesPluginModel):
ret.append(self.curse_add_line(self.view_data['show_hide_left_sidebar']))
ret.append(self.curse_add_line(self.view_data['misc_edit_process_filter_pattern']))
ret.append(self.curse_new_line())
ret.append(self.curse_new_line())
ret.append(self.curse_add_line('For an exhaustive list of key bindings:'))
ret.append(self.curse_new_line())
ret.append(self.curse_add_line('https://glances.readthedocs.io/en/latest/cmds.html#interactive-commands'))
# Return the message with decoration
return ret

View File

@ -18,7 +18,11 @@ import json
import copy
from operator import itemgetter
<<<<<<< HEAD:glances/plugins/plugin/model.py
from glances.globals import iterkeys, itervalues, listkeys, mean, nativestr
=======
from glances.compat import iterkeys, itervalues, listkeys, map, mean, nativestr
>>>>>>> develop:glances/plugins/glances_plugin.py
from glances.actions import GlancesActions
from glances.history import GlancesHistory
from glances.logger import logger
@ -1177,8 +1181,18 @@ class GlancesPluginModel(object):
ret = fct(*args, **kw)
duration = counter.get()
logger.debug(
<<<<<<< HEAD:glances/plugins/plugin/model.py
"{} {} {} return {} in {} seconds".format(
args[0].__class__.__name__, args[0].__class__.__module__, fct.__name__, ret, duration
=======
"%s %s %s return %s in %s seconds"
% (
args[0].__class__.__name__,
args[0].__class__.__module__[len('glances_'):],
fct.__name__,
ret,
duration,
>>>>>>> develop:glances/plugins/glances_plugin.py
)
)
return ret

View File

@ -114,7 +114,6 @@ class PluginModel(GlancesPluginModel):
# Update stats using SNMP
# No standard:
# http://www.net-snmp.org/wiki/index.php/Net-SNMP_and_lm-sensors_on_Ubuntu_10.04
pass
# Global change on stats
@ -160,17 +159,22 @@ class PluginModel(GlancesPluginModel):
if not i['value']:
continue
# Alert processing
if i['type'] == 'temperature_core' and not self.is_limit('critical', stat_name=i['type']):
if i['critical'] is None:
alert = 'DEFAULT'
elif i['value'] >= i['critical']:
alert = 'CRITICAL'
elif i['warning'] is None:
alert = 'DEFAULT'
elif i['value'] >= i['warning']:
alert = 'WARNING'
if i['type'] == 'temperature_core':
if self.is_limit('critical', stat_name='sensors_temperature_' + i['label']):
# By default use the thresholds confiured in the glances.conf file (see #2058)
alert = self.get_alert(current=i['value'], header='temperature_' + i['label'])
else:
alert = 'OK'
# Else use the system thresholds
if i['critical'] is None:
alert = 'DEFAULT'
elif i['value'] >= i['critical']:
alert = 'CRITICAL'
elif i['warning'] is None:
alert = 'DEFAULT'
elif i['value'] >= i['warning']:
alert = 'WARNING'
else:
alert = 'OK'
elif i['type'] == 'battery':
alert = self.get_alert(current=100 - i['value'], header=i['type'])
else:
@ -322,12 +326,12 @@ class GlancesGrabSensors(object):
else:
sensors_current['label'] = feature.label
# Sensors value, limit and unit
sensors_current['value'] = int(getattr(feature, 'current', 0) if getattr(feature, 'current', 0) else 0)
warning = getattr(feature, 'high', None)
sensors_current['warning'] = int(warning) if warning is not None else None
critical = getattr(feature, 'critical', None)
sensors_current['critical'] = int(critical) if critical is not None else None
sensors_current['unit'] = type
sensors_current['value'] = int(getattr(feature, 'current', 0) if getattr(feature, 'current', 0) else 0)
system_warning = getattr(feature, 'high', None)
system_critical = getattr(feature, 'critical', None)
sensors_current['warning'] = int(system_warning) if system_warning is not None else None
sensors_current['critical'] = int(system_critical) if system_critical is not None else None
# Add sensor to the list
ret.append(sensors_current)
i += 1

View File

@ -76,8 +76,13 @@ class PluginModel(GlancesPluginModel):
def msg_curse(self, args=None, max_width=None):
"""Return the string to display in the curse interface."""
# Init the return message
ret = []
# Only process if stats exist and plugin not disabled
if not self.stats or self.is_disabled():
return []
else:
return [self.curse_add_line('Uptime: {}'.format(self.stats))]
return ret
ret = [self.curse_add_line('Uptime: {}'.format(self.stats))]
return ret

View File

@ -428,6 +428,28 @@ class GlancesProcesses(object):
self.auto_sort = auto
self._sort_key = key
def nice_decrease(self, pid):
""" Decrease nice level
On UNIX this is a number which usually goes from -20 to 20.
The higher the nice value, the lower the priority of the process."""
p = psutil.Process(pid)
try:
p.nice(p.nice() - 1)
logger.info('Set nice level of process {} to {} (higher the priority)'.format(pid, p.nice()))
except psutil.AccessDenied:
logger.warning('Can not decrease (higher the priority) the nice level of process {} (access denied)'.format(pid))
def nice_increase(self, pid):
""" Increase nice level
On UNIX this is a number which usually goes from -20 to 20.
The higher the nice value, the lower the priority of the process."""
p = psutil.Process(pid)
try:
p.nice(p.nice() + 1)
logger.info('Set nice level of process {} to {} (lower the priority)'.format(pid, p.nice()))
except psutil.AccessDenied:
logger.warning('Can not increase (lower the priority) the nice level of process {} (access denied)'.format(pid))
def kill(self, pid, timeout=3):
"""Kill process with pid"""
assert pid != os.getpid(), "Glances can kill itself..."
@ -437,6 +459,8 @@ class GlancesProcesses(object):
return p.wait(timeout)
def weighted(value):
"""Manage None value in dict value."""
return -float('inf') if value is None else value

View File

@ -116,13 +116,18 @@ class GlancesStats(object):
# on the console but do not crash
logger.critical("Error while initializing the {} plugin ({})".format(name, e))
logger.error(traceback.format_exc())
# Disable the plugin
# An error occure, disable the plugin
if args is not None:
setattr(args, 'disable_' + name, False)
else:
# Set the disable_<name> to False by default
# Manage the default status of the plugin (enable or disable)
if args is not None:
setattr(args, 'disable_' + name, getattr(args, 'disable_' + name, False))
# If the all key is set in the disable_plugin option then look in the enable_plugin option
if getattr(args, 'disable_all', False):
logger.info('%s => %s', name, getattr(args, 'enable_' + name, False))
setattr(args, 'disable_' + name, not getattr(args, 'enable_' + name, False))
else:
setattr(args, 'disable_' + name, getattr(args, 'disable_' + name, False))
def load_plugins(self, args=None):
"""Load all plugins in the 'plugins' folder."""