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

This commit is contained in:
nicolargo 2017-02-28 21:59:16 +01:00
commit ea8a50b3c9
12 changed files with 118 additions and 121 deletions

View File

@ -15,25 +15,33 @@ displayed.
CPU stats description: CPU stats description:
* user: percent time spent in user space - **user**: percent time spent in user space. User CPU time is the time
> User CPU time is time spent on the processor running your program's code (or code in libraries) spent on the processor running your program's code (or code in
* system: percent time spent in kernel space libraries).
> System CPU time is the time spent running code in the operating system kernel - **system**: percent time spent in kernel space. System CPU time is the
* idle: percent of CPU used by any program time spent running code in the Operating System kernel.
> Every program or task that runs on a computer system occupies a certain amount of processing time on the CPU. If the CPU has completed all tasks it is idle. - **idle**: percent of CPU used by any program. Every program or task
* nice: percent time occupied by user level processes with a positive nice value that runs on a computer system occupies a certain amount of processing
> The time the CPU has spent running users' processes that have been "niced" time on the CPU. If the CPU has completed all tasks it is idle.
* irq: percent time spent servicing/handling hardware/software interrupts - **nice** *(\*nix)*: percent time occupied by user level processes with
> Time servicing interrupts (hardware + software) a positive nice value. The time the CPU has spent running users'
* iowait: percent time spent in wait (on disk) processes that have been *niced*.
> Time spent by the CPU waiting for a IO operations to complete - **irq** *(Linux, \*BSD)*: percent time spent servicing/handling
* steal: percent time in involuntary wait by virtual CPU hardware/software interrupts. Time servicing interrupts (hardware +
> Steal time is the percentage of time a virtual CPU waits for a real CPU while the hypervisor is servicing another virtual processor software).
* ctx_sw: number of context switches (voluntary + involuntary) per second - **iowait** *(Linux)*: percent time spent by the CPU waiting for I/O
> A context switch is a procedure that a computer's CPU (central processing unit) follows to change from one task (or process) to another while ensuring that the tasks do not conflict operations to complete.
* inter: number of interrupts per second - **steal** *(Linux)*: percentage of time a virtual CPU waits for a real
* sw_inter: number of software interrupts per second. Always set to 0 on Windows and SunOS. CPU while the hypervisor is servicing another virtual processor.
* syscal: number of system calls per second. Do not displayed on Linux (always 0). - **ctx_sw**: number of context switches (voluntary + involuntary) per
second. A context switch is a procedure that a computer's CPU (central
processing unit) follows to change from one task (or process) to
another while ensuring that the tasks do not conflict.
- **inter**: number of interrupts per second.
- **sw_inter**: number of software interrupts per second. Always set to
0 on Windows and SunOS.
- **syscal**: number of system calls per second. Do not displayed on
Linux (always 0).
To switch to per-CPU stats, just hit the ``1`` key: To switch to per-CPU stats, just hit the ``1`` key:

View File

@ -23,17 +23,8 @@ You can put your own ``glances.conf`` file in the following locations:
``Windows`` %APPDATA%\\glances ``Windows`` %APPDATA%\\glances
==================== ============================================================= ==================== =============================================================
On Windows XP, the ``%APPDATA%`` path is: * On Windows XP, ``%APPDATA%`` is: ``C:\Documents and Settings\<USERNAME>\Application Data``.
* On Windows Vista and later: ``C:\Users\<USERNAME>\AppData\Roaming``.
::
C:\Documents and Settings\<User>\Application Data
Since Windows Vista and newer versions:
::
C:\Users\<User>\AppData\Roaming
User-specific options override system-wide options and options given on User-specific options override system-wide options and options given on
the command line override either. the command line override either.
@ -107,10 +98,13 @@ line.
By default, the ``glances-USERNAME.log`` file is under the temporary directory: By default, the ``glances-USERNAME.log`` file is under the temporary directory:
=========== ====================== =========== ======
``*nix`` /tmp ``*nix`` /tmp
``Windows`` %APPDATA%\\Local\\temp ``Windows`` %TEMP%
=========== ====================== =========== ======
* On Windows XP, ``%TEMP%`` is: ``C:\Documents and Settings\<USERNAME>\Local Settings\Temp``.
* On Windows Vista and later: ``C:\Users\<USERNAME>\AppData\Local\Temp``.
If you want to use another system path or change the log message, you If you want to use another system path or change the log message, you
can use your own logger configuration. First of all, you have to create can use your own logger configuration. First of all, you have to create

View File

@ -26,6 +26,11 @@ OPTIONS
.. include:: cmds.rst .. include:: cmds.rst
CONFIGURATION
-------------
.. include:: config.rst
EXAMPLES EXAMPLES
-------- --------

View File

@ -124,8 +124,8 @@ class GlancesClient(object):
self.stats.set_plugins(json.loads(self.client.getAllPlugins())) self.stats.set_plugins(json.loads(self.client.getAllPlugins()))
logger.debug("Client version: {} / Server version: {}".format(__version__, client_version)) logger.debug("Client version: {} / Server version: {}".format(__version__, client_version))
else: else:
self.log_and_exit("Client and server not compatible: \ self.log_and_exit(('Client and server not compatible: '
Client version: {} / Server version: {}".format(__version__, client_version)) 'Client version: {} / Server version: {}'.format(__version__, client_version)))
return False return False
return True return True

View File

@ -42,6 +42,7 @@ def user_config_dir():
path = os.path.expanduser('~/Library/Application Support') path = os.path.expanduser('~/Library/Application Support')
else: else:
path = os.environ.get('XDG_CONFIG_HOME') or os.path.expanduser('~/.config') path = os.environ.get('XDG_CONFIG_HOME') or os.path.expanduser('~/.config')
path = os.path.join(path, 'glances')
return path return path
@ -51,10 +52,11 @@ def user_cache_dir():
- Linux, *BSD, SunOS: ~/.cache/glances - Linux, *BSD, SunOS: ~/.cache/glances
- macOS: ~/Library/Caches/glances - macOS: ~/Library/Caches/glances
- Windows: %LOCALAPPDATA%\glances\cache - Windows: {%LOCALAPPDATA%,%APPDATA%}\glances\cache
""" """
if WINDOWS and os.environ.get('LOCALAPPDATA') is not None: if WINDOWS:
path = os.path.join(os.environ.get('LOCALAPPDATA'), 'glances', 'cache') path = os.path.join(os.environ.get('LOCALAPPDATA') or os.environ.get('APPDATA'),
'glances', 'cache')
elif MACOS: elif MACOS:
path = os.path.expanduser('~/Library/Caches/glances') path = os.path.expanduser('~/Library/Caches/glances')
else: else:
@ -77,6 +79,7 @@ def system_config_dir():
path = '/usr/local/etc' path = '/usr/local/etc'
else: else:
path = os.environ.get('APPDATA') path = os.environ.get('APPDATA')
path = os.path.join(path, 'glances')
return path return path
@ -118,9 +121,7 @@ class Config(object):
if self.config_dir: if self.config_dir:
paths.append(self.config_dir) paths.append(self.config_dir)
if user_config_dir() is not None:
paths.append(os.path.join(user_config_dir(), self.config_filename)) paths.append(os.path.join(user_config_dir(), self.config_filename))
if system_config_dir() is not None:
paths.append(os.path.join(system_config_dir(), self.config_filename)) paths.append(os.path.join(system_config_dir(), self.config_filename))
return paths return paths

View File

@ -49,35 +49,34 @@ class GlancesMain(object):
username = "glances" username = "glances"
password = "" password = ""
# Exemple of use # Examples of use
example_of_use = "\ example_of_use = """
Examples of use:\n\ Examples of use:
\n\ Monitor local machine (standalone mode):
Monitor local machine (standalone mode):\n\ $ glances
$ glances\n\
\n\ Monitor local machine with the Web interface (Web UI):
Monitor local machine with the Web interface (Web UI):\n\ $ glances -w
$ glances -w\n\ Glances web server started on http://0.0.0.0:61208/
Glances web server started on http://0.0.0.0:61208/\n\
\n\ Monitor local machine and export stats to a CSV file (standalone mode):
Monitor local machine and export stats to a CSV file (standalone mode):\n\ $ glances --export-csv /tmp/glances.csv
$ glances --export-csv /tmp/glances.csv\n\
\n\ Monitor local machine and export stats to a InfluxDB server with 5s refresh time (standalone mode):
Monitor local machine and export stats to a InfluxDB server with 5s refresh time (standalone mode):\n\ $ glances -t 5 --export-influxdb
$ glances -t 5 --export-influxdb\n\
\n\ Start a Glances server (server mode):
Start a Glances server (server mode):\n\ $ glances -s
$ glances -s\n\
\n\ Connect Glances to a Glances server (client mode):
Connect Glances to a Glances server (client mode):\n\ $ glances -c <ip_server>
$ glances -c <ip_server>\n\
\n\ Connect Glances to a Glances server and export stats to a StatsD server (client mode):
Connect Glances to a Glances server and export stats to a StatsD server (client mode):\n\ $ glances -c <ip_server> --export-statsd
$ glances -c <ip_server> --export-statsd\n\
\n\ Start the client browser (browser mode):
Start the client browser (browser mode):\n\ $ glances --browser
$ glances --browser\n\ """
"
def __init__(self): def __init__(self):
"""Manage the command line arguments.""" """Manage the command line arguments."""
@ -363,30 +362,28 @@ Start the client browser (browser mode):\n\
self.args = args self.args = args
# Export is only available in standalone or client mode (issue #614) # Export is only available in standalone or client mode (issue #614)
export_tag = args.export_csv or \ export_tag = (
args.export_elasticsearch or \ args.export_csv or
args.export_statsd or \ args.export_elasticsearch or
args.export_influxdb or \ args.export_statsd or
args.export_cassandra or \ args.export_influxdb or
args.export_opentsdb or \ args.export_cassandra or
args.export_rabbitmq or \ args.export_opentsdb or
args.export_rabbitmq or
args.export_couchdb args.export_couchdb
)
if WINDOWS and export_tag: if WINDOWS and export_tag:
# On Windows, export is possible but only in quiet mode # On Windows, export is possible but only in quiet mode
# See issue #1038 # See issue #1038
logger.info( logger.info("On Windows OS, export disable the Web interface")
"On Windows OS, export disable the Web Interface")
self.args.quiet = True self.args.quiet = True
self.args.webserver = False self.args.webserver = False
elif not (self.is_standalone() or self.is_client()) \ elif not (self.is_standalone() or self.is_client()) and export_tag:
and export_tag: logger.critical("Export is only available in standalone or client mode")
logger.critical(
"Export is only available in standalone or client mode")
sys.exit(2) sys.exit(2)
# Filter is only available in standalone mode # Filter is only available in standalone mode
if args.process_filter is not None \ if args.process_filter is not None and not self.is_standalone():
and not self.is_standalone():
logger.critical( logger.critical(
"Process filter is only available in standalone mode") "Process filter is only available in standalone mode")
sys.exit(2) sys.exit(2)
@ -394,8 +391,7 @@ Start the client browser (browser mode):\n\
# Check graph output path # Check graph output path
if args.export_graph and args.path_graph is not None: if args.export_graph and args.path_graph is not None:
if not os.access(args.path_graph, os.W_OK): if not os.access(args.path_graph, os.W_OK):
logger.critical( logger.critical("Graphs output path {} doesn't exist or is not writable".format(args.path_graph))
"Graphs output path {} doesn't exist or is not writable".format(args.path_graph))
sys.exit(2) sys.exit(2)
logger.debug( logger.debug(
"Graphs output path is set to {}".format(args.path_graph)) "Graphs output path is set to {}".format(args.path_graph))
@ -429,30 +425,26 @@ Start the client browser (browser mode):\n\
def is_standalone(self): def is_standalone(self):
"""Return True if Glances is running in standalone mode.""" """Return True if Glances is running in standalone mode."""
return not self.args.client \ return (not self.args.client and
and not self.args.browser \ not self.args.browser and
and not self.args.server \ not self.args.server and
and not self.args.webserver not self.args.webserver)
def is_client(self): def is_client(self):
"""Return True if Glances is running in client mode.""" """Return True if Glances is running in client mode."""
return (self.args.client or self.args.browser) \ return (self.args.client or self.args.browser) and not self.args.server
and not self.args.server
def is_client_browser(self): def is_client_browser(self):
"""Return True if Glances is running in client browser mode.""" """Return True if Glances is running in client browser mode."""
return self.args.browser \ return self.args.browser and not self.args.server
and not self.args.server
def is_server(self): def is_server(self):
"""Return True if Glances is running in server mode.""" """Return True if Glances is running in server mode."""
return not self.args.client \ return not self.args.client and self.args.server
and self.args.server
def is_webserver(self): def is_webserver(self):
"""Return True if Glances is running in Web server mode.""" """Return True if Glances is running in Web server mode."""
return not self.args.client \ return not self.args.client and self.args.webserver
and self.args.webserver
def get_config(self): def get_config(self):
"""Return configuration file object.""" """Return configuration file object."""

View File

@ -135,8 +135,8 @@ class Outdated(object):
logger.debug("Cannot read the version cache file: {}".format(e)) logger.debug("Cannot read the version cache file: {}".format(e))
else: else:
logger.debug("Read the version cache file") logger.debug("Read the version cache file")
if cached_data['installed_version'] != self.installed_version() or \ if (cached_data['installed_version'] != self.installed_version() or
datetime.now() - cached_data['refresh_date'] > self.max_refresh_date: datetime.now() - cached_data['refresh_date'] > self.max_refresh_date):
# Reset the cache if: # Reset the cache if:
# - the installed version is different # - the installed version is different
# - the refresh_date is > max_refresh_date # - the refresh_date is > max_refresh_date

View File

@ -515,9 +515,11 @@ class _GlancesCurses(object):
__stat_display = self.__get_stat_display(stats, plugin_max_width) __stat_display = self.__get_stat_display(stats, plugin_max_width)
# Adapt number of processes to the available space # Adapt number of processes to the available space
max_processes_displayed = self.screen.getmaxyx()[0] - 11 - \ max_processes_displayed = (
self.get_stats_display_height(__stat_display["alert"]) - \ self.screen.getmaxyx()[0] - 11 -
self.get_stats_display_height(__stat_display["alert"]) -
self.get_stats_display_height(__stat_display["docker"]) self.get_stats_display_height(__stat_display["docker"])
)
try: try:
if self.args.enable_process_extended and not self.args.process_tree: if self.args.enable_process_extended and not self.args.process_tree:
max_processes_displayed -= 4 max_processes_displayed -= 4
@ -618,10 +620,10 @@ class _GlancesCurses(object):
# Space between column # Space between column
self.space_between_column = 0 self.space_between_column = 0
self.new_line() self.new_line()
l_uptime = self.get_stats_display_width(stat_display["system"]) \ l_uptime = (self.get_stats_display_width(stat_display["system"]) +
+ self.space_between_column \ self.space_between_column +
+ self.get_stats_display_width(stat_display["ip"]) + 3 \ self.get_stats_display_width(stat_display["ip"]) + 3 +
+ self.get_stats_display_width(stat_display["uptime"]) self.get_stats_display_width(stat_display["uptime"]))
self.display_plugin( self.display_plugin(
stat_display["system"], stat_display["system"],
display_optional=(self.screen.getmaxyx()[1] >= l_uptime)) display_optional=(self.screen.getmaxyx()[1] >= l_uptime))
@ -722,8 +724,8 @@ class _GlancesCurses(object):
if not self.args.disable_left_sidebar: if not self.args.disable_left_sidebar:
for s in ['network', 'wifi', 'ports', 'diskio', 'fs', 'irq', for s in ['network', 'wifi', 'ports', 'diskio', 'fs', 'irq',
'folders', 'raid', 'sensors', 'now']: 'folders', 'raid', 'sensors', 'now']:
if (hasattr(self.args, 'enable_' + s) or if ((hasattr(self.args, 'enable_' + s) or
hasattr(self.args, 'disable_' + s)) and s in stat_display: hasattr(self.args, 'disable_' + s)) and s in stat_display):
self.new_line() self.new_line()
self.display_plugin(stat_display[s]) self.display_plugin(stat_display[s])

View File

@ -100,9 +100,7 @@ class Plugin(GlancesPlugin):
# Init the return message # Init the return message
ret = [] ret = []
if not self.stats \ if not self.stats or self.stats == {} or self.is_disable():
or self.stats == {} \
or self.is_disable():
return ret return ret
# Generate the output # Generate the output

View File

@ -524,9 +524,7 @@ class Plugin(GlancesPlugin):
ret = [] ret = []
# Only process if stats exist (and non null) and display plugin enable... # Only process if stats exist (and non null) and display plugin enable...
if not self.stats \ if not self.stats or len(self.stats['containers']) == 0 or self.is_disable():
or len(self.stats['containers']) == 0 \
or self.is_disable():
return ret return ret
# Build the string message # Build the string message

View File

@ -229,8 +229,7 @@ class Plugin(GlancesPlugin):
mnt_point = i['mnt_point'][-fsname_max_width + 1:] mnt_point = i['mnt_point'][-fsname_max_width + 1:]
elif len(i['mnt_point']) + len(i['device_name'].split('/')[-1]) <= fsname_max_width - 3: elif len(i['mnt_point']) + len(i['device_name'].split('/')[-1]) <= fsname_max_width - 3:
# If possible concatenate mode info... Glances touch inside :) # If possible concatenate mode info... Glances touch inside :)
mnt_point = i['mnt_point'] + \ mnt_point = i['mnt_point'] + ' (' + i['device_name'].split('/')[-1] + ')'
' (' + i['device_name'].split('/')[-1] + ')'
elif len(i['mnt_point']) > fsname_max_width: elif len(i['mnt_point']) > fsname_max_width:
# Cut mount point name if it is too long # Cut mount point name if it is too long
mnt_point = '_' + i['mnt_point'][-fsname_max_width + 1:] mnt_point = '_' + i['mnt_point'][-fsname_max_width + 1:]

View File

@ -100,9 +100,9 @@ class Plugin(GlancesPlugin):
return 'CAREFUL' return 'CAREFUL'
elif port['status'] == 0: elif port['status'] == 0:
return 'CRITICAL' return 'CRITICAL'
elif isinstance(port['status'], (float, int)) and \ elif (isinstance(port['status'], (float, int)) and
port['rtt_warning'] is not None and \ port['rtt_warning'] is not None and
port['status'] > port['rtt_warning']: port['status'] > port['rtt_warning']):
return 'WARNING' return 'WARNING'
return 'OK' return 'OK'