Merge branch 'develop' into refactor-web-ui

Conflicts:
	glances/plugins/glances_help.py
This commit is contained in:
Nicolas Hart 2015-04-19 23:01:32 +02:00
commit 518aa7acfe
26 changed files with 751 additions and 573 deletions

34
NEWS
View File

@ -5,22 +5,40 @@ Glances Version 2.x
Version 2.4
===========
Enhancements and news features:
Changes:
* Glances doesn't provide a system-wide configuration file by default anymore.
Just copy it in any of the supported locations. See glances-doc.html for
more information.
* The default key bindings have been changed to:
- 'u': sort processes by USER
- 'U': show cumulative network I/O
Enhancements and new features:
* Implement a 'quick look' plugin (issue #505)
* Add sort processes by USER (issue #531)
* Add a new IP information plugin (issue #509)
* Add RabbitMQ export module (issue #540 Thk to @Katyucha)
* Add a quiet mode (-q), can be useful using with export module
* Grab FAN speed in the Glances sensors plugin (issue #501)
* Allow logical mounts points in the FS plugin (issue #448)
* Add a --disable-hddtemp to disable HDD temperature module at startup (issue #515)
* Add a quiet mode (-q). Can be usefull if you need a Statsd or Influxdb provider only.
* Increase alert minimal delay to 6 seconds (issue #522)
* If the Curses application raises an exception, restore the terminal correctly (issue #537)
Bugs corrected:
* Correct monitor list, all processes are take into account (issue #507)
* Correct duplicated --enable-history in the doc (issue #511)
* Monitor list, all processes are take into account (issue #507)
* Duplicated --enable-history in the doc (issue #511)
* Sensors title is displayed if no sensors are detected (issue #510)
* Server mode issue when no network interface is available (issue #528)
* DEBUG mode activated by default with Python 2.6 (issue #512)
Version 2.3
===========
Enhancements and news features:
Enhancements and new features:
* Add the Docker plugin (issue #440) with per container CPU and memory monitoring (issue #490)
* Add the RAID plugin (issue #447)
@ -52,7 +70,7 @@ Version 2.2.1
Version 2.2
===========
Enhancements and news features:
Enhancements and new features:
* Add centralized curse interface with a Glances servers list to monitor (issue #418)
* Add processes tree view (--tree) (issue #444)
@ -157,7 +175,7 @@ Version 2.0
===========
Glances v2.0 is not a simple upgrade of the version 1.x but a complete code refactoring.
Based on a plugins system, it aims at providing an easy way to add news features.
Based on a plugins system, it aims at providing an easy way to add new features.
- Core defines the basics and commons functions.
- all stats are grabbed through plugins (see the glances/plugins source folder).
- also outputs methods (Curse, Web mode, CSV) are managed as plugins.
@ -363,7 +381,7 @@ Version 1.4.2.1
Version 1.4.2
=============
* Use the news virtual_memory() and virtual_swap() fct (PsUtil)
* Use the new virtual_memory() and virtual_swap() fct (PsUtil)
* Display "Top process" in logs
* Minor patch on man page for Debian packaging
* Code optimization (less try and except)

View File

@ -31,7 +31,7 @@ Requirements
- ``psutil >= 2.0.0``
- ``setuptools``
Optionals dependencies:
Optional dependencies:
- ``bottle`` (for Web server mode)
- ``py3sensors`` (for hardware monitoring support) [Linux-only]
@ -51,7 +51,8 @@ Installation
Glances Auto Install script
---------------------------
To install both dependencies and latest Glances production ready version (aka *master* branch), just enter the following command line:
To install both dependencies and latest Glances production ready version
(aka *master* branch), just enter the following command line:
.. code-block:: console
@ -81,7 +82,8 @@ To install, simply use ``pip``:
*Note*: Python headers are required to install psutil. For example,
on Debian/Ubuntu you need to install first the *python-dev* package.
*Note 2*: You can also install the following libs in order to use optionnal features:
You can also install the following libraries in order to use optional
features:
.. code-block:: console
@ -157,7 +159,7 @@ Windows
- Install Python for Windows: http://www.python.org/getit/
- Install the psutil library: https://pypi.python.org/pypi?:action=display&name=psutil#downloads
- Install the colorconsole library: https://pypi.python.org/pypi/colorconsole
- Install Glances Download Glances from here: http://nicolargo.github.io/glances/
- Install Glances: http://nicolargo.github.io/glances/
Source
------
@ -236,7 +238,7 @@ How to contribute ?
If you want to contribute to the Glances project, read this `Wiki`_ page.
There is also a chat dedicated to the Glances' developpers:
There is also a chat dedicated to the Glances developers:
.. image:: https://badges.gitter.im/Join%20Chat.svg
:target: https://gitter.im/nicolargo/glances?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge

View File

@ -1,188 +0,0 @@
[quicklook]
cpu_careful=50
cpu_warning=70
cpu_critical=90
mem_careful=50
mem_warning=70
mem_critical=90
swap_careful=50
swap_warning=70
swap_critical=90
[cpu]
# Default values if not defined: 50/70/90
user_careful=50
user_warning=70
user_critical=90
#user_log=False
user_critical_action=echo {{user}} {{value}} {{max}} > /tmp/cpu.alert
iowait_careful=50
iowait_warning=70
iowait_critical=90
system_careful=50
system_warning=70
system_critical=90
steal_careful=50
steal_warning=70
steal_critical=90
#steal_log=True
[percpu]
# Default values if not defined: 50/70/90
user_careful=50
user_warning=70
user_critical=90
iowait_careful=50
iowait_warning=70
iowait_critical=90
system_careful=50
system_warning=70
system_critical=90
[load]
# Value * number of cores
# Default values if not defined: 0.7/1.0/5.0 per number of cores
# Source: http://blog.scoutapp.com/articles/2009/07/31/understanding-load-averages
# http://www.linuxjournal.com/article/9001
careful=0.7
warning=1.0
critical=5.0
#log=False
[mem]
# Default limits for free RAM memory in %
# Default values if not defined: 50/70/90
careful=50
warning=70
critical=90
[memswap]
# Default limits for free swap memory in %
# Default values if not defined: 50/70/90
careful=50
warning=70
critical=90
[network]
# Define the list of hidden network interfaces (comma separeted)
hide=lo
# WLAN0 alias name
wlan0_alias=Wireless
# WLAN0 Default limits (in bits per second aka bps) for interface bitrate
wlan0_rx_careful=4000000
wlan0_rx_warning=5000000
wlan0_rx_critical=6000000
wlan0_rx_log=True
wlan0_tx_careful=700000
wlan0_tx_warning=900000
wlan0_tx_critical=1000000
wlan0_tx_log=True
[diskio]
# Define the list of hidden disks (comma separeted)
hide=sda5
# Alias for sda1
#sda1_alias=IntDisk
# SDA1 limits (in bytes per second aka Bps) for interface bitrate
sda2_rx_careful=150000000
sda2_rx_warning=180000000
sda2_rx_critical=200000000
#sda2_rx_log=True
sda2_tx_careful=150000000
sda2_tx_warning=180000000
sda2_tx_critical=200000000
#sda2_tx_log=True
[fs]
# Default limits for free filesytem space in %
# Default values if not defined: 50/70/90
careful=50
careful_action=echo {{mnt_point}} {{used}}/{{size}} > /tmp/fs.alert
warning=70
critical=90
# Allow additionnals files types (comma-separated FS type)
allow=zfs
[sensors]
# Sensors core limits
# Default values if not defined: 60/70/80
temperature_core_careful=50
temperature_core_warning=70
temperature_core_critical=80
# Temperatures in °C for hddtemp
# Default values if not defined: 45/52/60
temperature_hdd_careful=45
temperature_hdd_warning=52
temperature_hdd_critical=60
# Battery % limits
battery_careful=80
battery_warning=90
battery_critical=95
# Sensors alias
temp1_alias=Motherboard 0
temp2_alias=Motherboard 1
core 0_alias=CPU Core 0
core 1_alias=CPU Core 1
[processlist]
# Limit values for CPU/MEM per process in %
# Default values if not defined: 50/70/90
cpu_careful=50
cpu_warning=70
cpu_critical=90
mem_careful=50
mem_warning=70
mem_critical=90
[monitor]
# Define the list of processes to monitor
# *** This section is optional ***
# The list is composed of items (list_#nb <= 10)
# An item is defined:
# * description: Description of the processes (max 16 chars)
# * regex: regular expression of the processes to monitor
# * command: (optional) full path to shell command/script for extended stat
# Use with caution. Should return a single line string.
# Only execute when at least one process is running
# By default display CPU and MEM %
# Limitation: Do not use in client / server mode
# * countmin: (optional) minimal number of processes
# A warning will be displayed if number of process < count
# * countmax: (optional) maximum number of processes
# A warning will be displayed if number of process > count
#list_1_description=Dropbox
#list_1_regex=.*dropbox.*
#list_1_countmin=1
#list_1_command=dropbox status | head -1
list_1_description=Python programs
list_1_regex=.*python.*
list_2_description=Famous Xeyes
list_2_regex=.*xeyes.*
list_2_countmin=1
[serverlist]
# Define the static server list
server_1_name=localhost
server_1_alias=My local PC
server_1_port=61209
server_2_name=localhost
server_2_port=61235
server_3_name=192.168.0.17
server_3_alias=Another PC on my network
server_3_port=61209
server_4_name=pasbon
server_4_port=61237
[influxdb]
host=localhost
port=8086
user=root
password=root
db=glances
#prefix=localhost
[statsd]
host=localhost
port=8125
#prefix=glances

View File

@ -177,3 +177,10 @@ db=glances
host=localhost
port=8125
#prefix=glances
[rabbitmq]
host=localhost
port=5672
user=guest
password=guest
queue=glances_queue

View File

@ -3,7 +3,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.11: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils 0.12: http://docutils.sourceforge.net/" />
<title>Glances</title>
<style type="text/css">
@ -123,9 +123,9 @@ td.option-group {
<div class="document" id="glances">
<h1 class="title">Glances</h1>
<p>This manual describes <em>Glances</em> version 2.3.</p>
<p>This manual describes <em>Glances</em> version 2.4.</p>
<p>Copyright © 2011-2015 Nicolas Hennion &lt;<a class="reference external" href="mailto:nicolas&#64;nicolargo.com">nicolas&#64;nicolargo.com</a>&gt;</p>
<p>January 2015</p>
<p>April 2015</p>
<div class="contents topic" id="table-of-contents">
<p class="topic-title first">Table of Contents</p>
<ul class="simple">
@ -141,28 +141,39 @@ td.option-group {
<li><a class="reference internal" href="#interactive-commands" id="id12">Interactive Commands</a></li>
</ul>
</li>
<li><a class="reference internal" href="#configuration" id="id13">Configuration</a></li>
<li><a class="reference internal" href="#logs-and-debug-mode" id="id14">Logs and debug mode</a></li>
<li><a class="reference internal" href="#anatomy-of-the-application" id="id15">Anatomy Of The Application</a><ul>
<li><a class="reference internal" href="#legend" id="id16">Legend</a></li>
<li><a class="reference internal" href="#header" id="id17">Header</a></li>
<li><a class="reference internal" href="#cpu" id="id18">CPU</a></li>
<li><a class="reference internal" href="#load" id="id19">Load</a></li>
<li><a class="reference internal" href="#memory" id="id20">Memory</a></li>
<li><a class="reference internal" href="#network" id="id21">Network</a></li>
<li><a class="reference internal" href="#disk-i-o" id="id22">Disk I/O</a></li>
<li><a class="reference internal" href="#file-system" id="id23">File System</a></li>
<li><a class="reference internal" href="#sensors" id="id24">Sensors</a></li>
<li><a class="reference internal" href="#processes-list" id="id25">Processes List</a></li>
<li><a class="reference internal" href="#monitored-processes-list" id="id26">Monitored Processes List</a></li>
<li><a class="reference internal" href="#logs" id="id27">Logs</a></li>
<li><a class="reference internal" href="#docker" id="id28">Docker</a></li>
<li><a class="reference internal" href="#actions" id="id29">Actions</a></li>
<li><a class="reference internal" href="#configuration" id="id13">Configuration</a><ul>
<li><a class="reference internal" href="#location" id="id14">Location</a></li>
<li><a class="reference internal" href="#syntax" id="id15">Syntax</a></li>
</ul>
</li>
<li><a class="reference internal" href="#gateway-to-others-services" id="id30">Gateway to others services</a></li>
<li><a class="reference internal" href="#apis-documentations" id="id31">APIs Documentations</a></li>
<li><a class="reference internal" href="#support" id="id32">Support</a></li>
<li><a class="reference internal" href="#logs-and-debug-mode" id="id16">Logs and debug mode</a></li>
<li><a class="reference internal" href="#anatomy-of-the-application" id="id17">Anatomy Of The Application</a><ul>
<li><a class="reference internal" href="#legend" id="id18">Legend</a></li>
<li><a class="reference internal" href="#header" id="id19">Header</a></li>
<li><a class="reference internal" href="#quicklook" id="id20">QuickLook</a></li>
<li><a class="reference internal" href="#cpu" id="id21">CPU</a></li>
<li><a class="reference internal" href="#load" id="id22">Load</a></li>
<li><a class="reference internal" href="#memory" id="id23">Memory</a></li>
<li><a class="reference internal" href="#network" id="id24">Network</a></li>
<li><a class="reference internal" href="#disk-i-o" id="id25">Disk I/O</a></li>
<li><a class="reference internal" href="#file-system" id="id26">File System</a></li>
<li><a class="reference internal" href="#sensors" id="id27">Sensors</a></li>
<li><a class="reference internal" href="#processes-list" id="id28">Processes List</a></li>
<li><a class="reference internal" href="#monitored-processes-list" id="id29">Monitored Processes List</a></li>
<li><a class="reference internal" href="#logs" id="id30">Logs</a></li>
<li><a class="reference internal" href="#docker" id="id31">Docker</a></li>
<li><a class="reference internal" href="#actions" id="id32">Actions</a></li>
</ul>
</li>
<li><a class="reference internal" href="#gateway-to-others-services" id="id33">Gateway to others services</a><ul>
<li><a class="reference internal" href="#csv" id="id34">CSV</a></li>
<li><a class="reference internal" href="#influxdb" id="id35">InfluxDB</a></li>
<li><a class="reference internal" href="#statsd" id="id36">Statsd</a></li>
<li><a class="reference internal" href="#rabbitmq" id="id37">RabbitMQ</a></li>
</ul>
</li>
<li><a class="reference internal" href="#apis-documentation" id="id38">APIs documentation</a></li>
<li><a class="reference internal" href="#support" id="id39">Support</a></li>
</ul>
</div>
<div class="section" id="introduction">
@ -204,7 +215,12 @@ another one, called <tt class="docutils literal">client</tt>, just run on the se
<span class="generic output">client$ glances -c &#64;server</span>
</pre>
<p>where <tt class="docutils literal">&#64;server</tt> is the IP address or hostname of the server.</p>
<p>Glances can centralize available Glances servers using the <tt class="docutils literal"><span class="pre">--browser</span></tt> option. The server list can be staticaly defined in the Glances configuration file (section [serverlist]). Glances can also detect and display all Glances servers available on you network (auto discover mode is based on the the Zeroconf protocol only available on GNU/Linux and Mac OS X):</p>
<p>Glances can centralize available Glances servers using the <tt class="docutils literal"><span class="pre">--browser</span></tt>
option. The server list can be statically defined in the Glances
configuration file (section <tt class="docutils literal">[serverlist]</tt>).</p>
<p>Glances can also detect and display all Glances servers available on your
network (auto-discover mode is based on the the <tt class="docutils literal">zeroconf</tt> protocol,
which is only available on GNU/Linux and OS X):</p>
<pre class="code console literal-block">
<span class="generic output">client$ glances --browser</span>
</pre>
@ -223,7 +239,7 @@ client, the latter will try to grab stats using the <tt class="docutils literal"
<pre class="code console literal-block">
<span class="generic output">client$ glances -c &#64;snmpserver</span>
</pre>
<p>Note: Stats grabbed by SNMP request are limited (operating system dependent).</p>
<p><em>Note</em>: stats grabbed by SNMP request are limited (OS dependent).</p>
</div>
<div class="section" id="web-server-mode">
<h2><a class="toc-backref" href="#id9">Web Server Mode</a></h2>
@ -237,7 +253,11 @@ device with a web browser, just run the server with the <tt class="docutils lite
http://&#64;server:61208
</pre>
<p>where <tt class="docutils literal">&#64;server</tt> is the IP address or hostname of the server.</p>
<p>To change the refresh rate of the page, just add the period in seconds between refreshes at the end of the URL, ie. to refresh every 10s, use <tt class="docutils literal"><span class="pre">http://&#64;server:61208/10</span></tt>.</p>
<p>To change the refresh rate of the page, just add the period in seconds
at the end of the URL. For example, to refresh the page every 10s:</p>
<pre class="literal-block">
http://&#64;server:61208/10
</pre>
<p>The Glances web interface follows responsive web design principles.</p>
<p>Screenshot from Chrome on Android</p>
<img alt="images/screenshot-web2.png" src="images/screenshot-web2.png" />
@ -288,6 +308,10 @@ http://&#64;server:61208
</tr>
<tr><td>&nbsp;</td><td>disable sensors module</td></tr>
<tr><td class="option-group" colspan="2">
<kbd><span class="option">--disable-hddtemp</span></kbd></td>
</tr>
<tr><td>&nbsp;</td><td>disable HDDTemp module</td></tr>
<tr><td class="option-group" colspan="2">
<kbd><span class="option">--disable-left-sidebar</span></kbd></td>
</tr>
<tr><td>&nbsp;</td><td>disable left sidebar</td></tr>
@ -303,9 +327,9 @@ http://&#64;server:61208
</tr>
<tr><td>&nbsp;</td><td>enable extended stats on top process</td></tr>
<tr><td class="option-group" colspan="2">
<kbd><span class="option">--enable-history</span></kbd></td>
<kbd><span class="option">--disable-quicklook</span></kbd></td>
</tr>
<tr><td>&nbsp;</td><td>enable the history mode</td></tr>
<tr><td>&nbsp;</td><td>disable the Quicklook module</td></tr>
<tr><td class="option-group" colspan="2">
<kbd><span class="option">--path-history <var>PATH_HISTORY</var></span></kbd></td>
</tr>
@ -323,6 +347,10 @@ http://&#64;server:61208
</tr>
<tr><td>&nbsp;</td><td>export stats to a Statsd server</td></tr>
<tr><td class="option-group" colspan="2">
<kbd><span class="option">--export-rabbitmq</span></kbd></td>
</tr>
<tr><td>&nbsp;</td><td>export stats to a RabbitMQ server</td></tr>
<tr><td class="option-group" colspan="2">
<kbd><span class="option">-c <var>CLIENT</var></span>, <span class="option">--client <var>CLIENT</var></span></kbd></td>
</tr>
<tr><td>&nbsp;</td><td>connect to a Glances server by IPv4/IPv6 address or
@ -388,6 +416,9 @@ file</td></tr>
<kbd><span class="option">-w</span>, <span class="option">--webserver</span></kbd></td>
</tr>
<tr><td>&nbsp;</td><td>run Glances in web server mode</td></tr>
<tr><td class="option-group">
<kbd><span class="option">-q</span>, <span class="option">--quiet</span></kbd></td>
<td>run Glances in quiet mode (nothing is displayed)</td></tr>
<tr><td class="option-group" colspan="2">
<kbd><span class="option">-f <var>PROCESS_FILTER</var></span>, <span class="option">--process-filter <var>PROCESS_FILTER</var></span></kbd></td>
</tr>
@ -415,7 +446,7 @@ file</td></tr>
<tr><td>&nbsp;</td><td>display FS free space instead of used</td></tr>
<tr><td class="option-group">
<kbd><span class="option">--theme-white</span></kbd></td>
<td>optimize display for white background</td></tr>
<td>optimize display colors for white background</td></tr>
</tbody>
</table>
</blockquote>
@ -488,10 +519,13 @@ Filter is a regular expression pattern:</p>
<dd>Switch between global CPU and per-CPU stats</dd>
<dt><tt class="docutils literal">2</tt></dt>
<dd>Enable/disable left sidebar</dd>
<dt><tt class="docutils literal">3</tt></dt>
<dd>Enable/disable the Quicklook module</dd>
<dt><tt class="docutils literal">/</tt></dt>
<dd>Switch between short name / command line (processes name)</dd>
</dl>
<p>In the Glances client browser (accessible through the --browser command line argument):</p>
<p>In the Glances client browser (accessible through the <tt class="docutils literal"><span class="pre">--browser</span></tt>
command line argument):</p>
<dl class="docutils">
<dt><tt class="docutils literal">ENTER</tt></dt>
<dd>Run Glances client to the selected server</dd>
@ -507,19 +541,24 @@ Filter is a regular expression pattern:</p>
<div class="section" id="configuration">
<h1><a class="toc-backref" href="#id13">Configuration</a></h1>
<p>No configuration file is mandatory to use Glances.</p>
<p>Furthermore a configuration file is needed to set up limits, disks or
network interfaces to hide and/or monitored processes list or to define
alias.</p>
<p>By default, the configuration file is under:</p>
<p>Furthermore a configuration file is needed to modify limit alerts, to
set up monitored processes list, to hide disks or network interfaces or
to define alias.</p>
<div class="section" id="location">
<h2><a class="toc-backref" href="#id14">Location</a></h2>
<p>You can put the configuration file <tt class="docutils literal">glances.conf</tt> in the following
locations:</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Linux:</th><td class="field-body"><tt class="docutils literal">/etc/glances/glances.conf</tt></td>
<tr class="field"><th class="field-name">Linux:</th><td class="field-body"><tt class="docutils literal"><span class="pre">~/.config/glances,</span> /etc/glances</tt></td>
</tr>
<tr class="field"><th class="field-name">*BSD and OS X:</th><td class="field-body"><tt class="docutils literal">/usr/local/etc/glances/glances.conf</tt></td>
<tr class="field"><th class="field-name">*BSD:</th><td class="field-body"><tt class="docutils literal"><span class="pre">~/.config/glances,</span> /usr/local/etc/glances</tt></td>
</tr>
<tr class="field"><th class="field-name">Windows:</th><td class="field-body"><tt class="docutils literal"><span class="pre">%APPDATA%\glances\glances.conf</span></tt></td>
<tr class="field"><th class="field-name">OS X:</th><td class="field-body"><tt class="docutils literal">~/Library/Application Support/glances, /usr/local/etc/glances</tt></td>
</tr>
<tr class="field"><th class="field-name">Windows:</th><td class="field-body"><tt class="docutils literal"><span class="pre">%APPDATA%\glances</span></tt></td>
</tr>
</tbody>
</table>
@ -530,20 +569,12 @@ C:\Documents and Settings\&lt;User&gt;\Application Data
<p>Since Windows Vista and newer versions:</p>
<pre class="literal-block">
C:\Users\&lt;User&gt;\AppData\Roaming
or
%userprofile%\AppData\Roaming
</pre>
<p>You can override the default configuration, located in one of the above
directories on your system, except for Windows.</p>
<p>Just copy the <tt class="docutils literal">glances.conf</tt> file to your <tt class="docutils literal">$XDG_CONFIG_HOME</tt> directory,
e.g., on Linux:</p>
<pre class="code console literal-block">
<span class="generic output">mkdir -p $XDG_CONFIG_HOME/glances
cp /usr/share/doc/glances/glances.conf $XDG_CONFIG_HOME/glances/</span>
</pre>
<p>On OS X, you should copy the configuration file to
<tt class="docutils literal">~/Library/Application Support/glances/</tt>.</p>
<p><em>Configuration file description</em></p>
<p>User-specific options override system-wide options and options given on
the command line override either.</p>
</div>
<div class="section" id="syntax">
<h2><a class="toc-backref" href="#id15">Syntax</a></h2>
<p>Each plugin and export module can have a section.</p>
<p>Example for the CPU plugin:</p>
<pre class="code literal-block">
@ -561,13 +592,15 @@ steal_careful=50
steal_warning=70
steal_critical=90
</pre>
<p>By default Steal CPU time alerts aren't logged. If you want to enable log/alert, just add:</p>
<p>By default the <tt class="docutils literal">steal</tt> CPU time alerts aren't logged. If you want to
enable log/alert, just add:</p>
<pre class="code literal-block">
steal_log=True
</pre>
</div>
</div>
<div class="section" id="logs-and-debug-mode">
<h1><a class="toc-backref" href="#id14">Logs and debug mode</a></h1>
<h1><a class="toc-backref" href="#id16">Logs and debug mode</a></h1>
<p>Glances logs all its internal messages to a log file. By default, only
INFO &amp; WARNING &amp; ERROR &amp;CRITICAL levels are logged, but DEBUG messages
can ben logged using the -d option on the command line.</p>
@ -576,19 +609,20 @@ can ben logged using the -d option on the command line.</p>
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name" colspan="2">Linux, *BSD and OS X:</th></tr>
<tr class="field"><th class="field-name" colspan="2">Linux, *BSD, OS X:</th></tr>
<tr class="field"><td>&nbsp;</td><td class="field-body"><tt class="docutils literal">/tmp/glances.log</tt></td>
</tr>
<tr class="field"><th class="field-name">Windows:</th><td class="field-body"><tt class="docutils literal"><span class="pre">%APPDATA%\Local\temp\glances.log</span></tt></td>
</tr>
</tbody>
</table>
<p>If glances.log is not writable, a new file will be created and returned to the user console.</p>
<p>If <tt class="docutils literal">glances.log</tt> is not writable, a new file will be created and
returned to the user console.</p>
</div>
<div class="section" id="anatomy-of-the-application">
<h1><a class="toc-backref" href="#id15">Anatomy Of The Application</a></h1>
<h1><a class="toc-backref" href="#id17">Anatomy Of The Application</a></h1>
<div class="section" id="legend">
<h2><a class="toc-backref" href="#id16">Legend</a></h2>
<h2><a class="toc-backref" href="#id18">Legend</a></h2>
<div class="line-block">
<div class="line"><tt class="docutils literal">GREEN</tt> stat counter is <tt class="docutils literal">&quot;OK&quot;</tt></div>
<div class="line"><tt class="docutils literal">BLUE</tt> stat counter is <tt class="docutils literal">&quot;CAREFUL&quot;</tt></div>
@ -599,7 +633,7 @@ can ben logged using the -d option on the command line.</p>
view.</p>
</div>
<div class="section" id="header">
<h2><a class="toc-backref" href="#id17">Header</a></h2>
<h2><a class="toc-backref" href="#id19">Header</a></h2>
<img alt="images/header.png" src="images/header.png" />
<p>The header shows the hostname, OS name, release version, platform
architecture and system uptime (on the upper right corner).
@ -610,8 +644,16 @@ Additionally, on GNU/Linux, it also shows the kernel version.</p>
<p>Disconnected:</p>
<img alt="images/disconnected.png" src="images/disconnected.png" />
</div>
<div class="section" id="quicklook">
<h2><a class="toc-backref" href="#id20">QuickLook</a></h2>
<p>The <tt class="docutils literal">quicklook</tt> plugin is only displayed on wide screen and propose a
bar view for CPU and memory (virtual and swap).</p>
<img alt="images/quicklook.png" src="images/quicklook.png" />
<p><em>Note</em>: limit values can be overwritten in the configuration file under
the <tt class="docutils literal">[quicklook]</tt> section.</p>
</div>
<div class="section" id="cpu">
<h2><a class="toc-backref" href="#id18">CPU</a></h2>
<h2><a class="toc-backref" href="#id21">CPU</a></h2>
<p>Short view:</p>
<img alt="images/cpu.png" src="images/cpu.png" />
<p>If enough horizontal space is available, extended CPU information are
@ -632,7 +674,7 @@ time. The total CPU usage is displayed on the first line.</p>
the <tt class="docutils literal">[cpu]</tt> and/or <tt class="docutils literal">[percpu]</tt> sections.</p>
</div>
<div class="section" id="load">
<h2><a class="toc-backref" href="#id19">Load</a></h2>
<h2><a class="toc-backref" href="#id22">Load</a></h2>
<img alt="images/load.png" src="images/load.png" />
<p>On the <em>No Sheep</em> blog, <em>Zachary Tirrell</em> defines the load average <a class="footnote-reference" href="#id3" id="id1">[1]</a>:</p>
<blockquote>
@ -652,7 +694,7 @@ The first line also displays the number of CPU core.</p>
the <tt class="docutils literal">[load]</tt> section.</p>
</div>
<div class="section" id="memory">
<h2><a class="toc-backref" href="#id20">Memory</a></h2>
<h2><a class="toc-backref" href="#id23">Memory</a></h2>
<p>Glances uses two columns: one for the <tt class="docutils literal">RAM</tt> and one for the <tt class="docutils literal">SWAP</tt>.</p>
<img alt="images/mem.png" src="images/mem.png" />
<p>If enough space is available, Glances displays extended information for
@ -669,7 +711,7 @@ the <tt class="docutils literal">RAM</tt>:</p>
the <tt class="docutils literal">[memory]</tt> and/or <tt class="docutils literal">[memswap]</tt> sections.</p>
</div>
<div class="section" id="network">
<h2><a class="toc-backref" href="#id21">Network</a></h2>
<h2><a class="toc-backref" href="#id24">Network</a></h2>
<img alt="images/network.png" src="images/network.png" />
<p>Glances displays the network interface bit rate. The unit is adapted
dynamically (bits per second, kbits per second, Mbits per second, etc).</p>
@ -680,7 +722,7 @@ and per-interface limit values in the <tt class="docutils literal">[network]</tt
configuration file and aliases for interface name.</p>
</div>
<div class="section" id="disk-i-o">
<h2><a class="toc-backref" href="#id22">Disk I/O</a></h2>
<h2><a class="toc-backref" href="#id25">Disk I/O</a></h2>
<img alt="images/diskio.png" src="images/diskio.png" />
<p>Glances displays the disk I/O throughput. The unit is adapted dynamically.</p>
<p>There is no alert on this information.</p>
@ -688,7 +730,7 @@ configuration file and aliases for interface name.</p>
<tt class="docutils literal">[diskio]</tt> section in the configuration file and aliases for disk name.</p>
</div>
<div class="section" id="file-system">
<h2><a class="toc-backref" href="#id23">File System</a></h2>
<h2><a class="toc-backref" href="#id26">File System</a></h2>
<img alt="images/fs.png" src="images/fs.png" />
<p>Glances displays the used and total file system disk space. The unit is
adapted dynamically.</p>
@ -703,9 +745,16 @@ adapted dynamically.</p>
the <tt class="docutils literal">[filesystem]</tt> section.</p>
<p>If a RAID controller is detected on you system, its status will be displayed:</p>
<img alt="images/raid.png" src="images/raid.png" />
<p>By default, the plugin only displays physical devices (hard disks, USB
keys) and ignore all others. To allow others FS type, you have to use the
following section in the configuration file:</p>
<pre class="literal-block">
[fs]
allow=zfs,misc
</pre>
</div>
<div class="section" id="sensors">
<h2><a class="toc-backref" href="#id24">Sensors</a></h2>
<h2><a class="toc-backref" href="#id27">Sensors</a></h2>
<p>Glances can displays the sensors information using <cite>lm-sensors</cite>,
<cite>hddtemp</cite> and <cite>batinfo</cite> <a class="footnote-reference" href="#id4" id="id2">[2]</a>.</p>
<p>All of the above libraries are available only on Linux.</p>
@ -713,11 +762,11 @@ the <tt class="docutils literal">[filesystem]</tt> section.</p>
temperature only.</p>
<img alt="images/sensors.png" src="images/sensors.png" />
<p>There is no alert on this information.</p>
<p><em>Note</em>: limit values and sensors alias names can be defined in the configuration
file under the <tt class="docutils literal">[sensors]</tt> section.</p>
<p><em>Note</em>: limit values and sensors alias names can be defined in the
configuration file under the <tt class="docutils literal">[sensors]</tt> section.</p>
</div>
<div class="section" id="processes-list">
<h2><a class="toc-backref" href="#id25">Processes List</a></h2>
<h2><a class="toc-backref" href="#id28">Processes List</a></h2>
<p>Compact view:</p>
<img alt="images/processlist.png" src="images/processlist.png" />
<p>Full view:</p>
@ -786,7 +835,8 @@ User cans switch to the process name by pressing on the <tt class="docutils lite
<dt><tt class="docutils literal">Z</tt></dt>
<dd>Zombie</dd>
</dl>
<p>In standalone mode, additionals informations are provided for the top process:</p>
<p>In standalone mode, additional informations are provided for the top
process:</p>
<img alt="images/processlist-top.png" src="images/processlist-top.png" />
<ul class="simple">
<li>CPU affinity (number of cores used by the process)</li>
@ -794,12 +844,13 @@ User cans switch to the process name by pressing on the <tt class="docutils lite
<li>Open threads, files and network sessions (TCP and UDP)</li>
<li>IO nice level</li>
</ul>
<p>The extended stats feature could be enabled using the --enable-process-extended option (command line) or the <tt class="docutils literal">e</tt> key (curses interface).</p>
<p>The extended stats feature could be enabled using the <tt class="docutils literal"><span class="pre">--enable-process-extended</span></tt>
option (command line) or the <tt class="docutils literal">e</tt> key (curses interface).</p>
<p><em>Note</em>: limit values can be overwritten in the configuration file under
the <tt class="docutils literal">[process]</tt> section.</p>
</div>
<div class="section" id="monitored-processes-list">
<h2><a class="toc-backref" href="#id26">Monitored Processes List</a></h2>
<h2><a class="toc-backref" href="#id29">Monitored Processes List</a></h2>
<p>The monitored processes list allows user, through the configuration file,
to group processes and quickly show if the number of running processes is
not good.</p>
@ -851,7 +902,7 @@ get the JSON representation of the monitored processes list.</p>
</div>
</div>
<div class="section" id="logs">
<h2><a class="toc-backref" href="#id27">Logs</a></h2>
<h2><a class="toc-backref" href="#id30">Logs</a></h2>
<img alt="images/logs.png" src="images/logs.png" />
<p>A log messages list is displayed in the bottom of the screen if (and
only if):</p>
@ -870,31 +921,39 @@ processes list alerts</li>
</ol>
</div>
<div class="section" id="docker">
<h2><a class="toc-backref" href="#id28">Docker</a></h2>
<p>If you use Docker, Glances can help you to monitor your container. Glances uses the Docker API through the Docker-Py library.</p>
<h2><a class="toc-backref" href="#id31">Docker</a></h2>
<p>If you use <tt class="docutils literal">Docker</tt>, Glances can help you to monitor your container.
Glances uses the Docker API through the <tt class="docutils literal"><span class="pre">docker-py</span></tt> library.</p>
<img alt="images/docker.png" src="images/docker.png" />
</div>
<div class="section" id="actions">
<h2><a class="toc-backref" href="#id29">Actions</a></h2>
<h2><a class="toc-backref" href="#id32">Actions</a></h2>
<p>Glances can trigger actions on events.</p>
<p>By action, we mean all shell command line. For example, if you want to execute the foo.py script if the last 5 minutes load are critical then add the action line to the Glances configuration file:</p>
<p>By <tt class="docutils literal">action</tt>, we mean all shell command line. For example, if you want
to execute the <tt class="docutils literal">foo.py</tt> script if the last 5 minutes load are critical
then add the action line to the Glances configuration file:</p>
<pre class="code literal-block">
[load]
critical=5.0
critical_action=python /path/to/foo.py
</pre>
<p>All the stats are available in the command line through the use of the {{mustache}} syntax. Another example to create a log file containing used vs total disk space if a space trigger warning is reached:</p>
<p>All the stats are available in the command line through the use of the
<tt class="docutils literal">{{mustache}}</tt> syntax. Another example would be to create a log file
containing used vs total disk space if a space trigger warning is reached:</p>
<pre class="code literal-block">
[fs]
warning=70
warning_action=echo {{mnt_point}} {{used}}/{{size}} &gt; /tmp/fs.alert
</pre>
<p><em>Note</em>: You can use all the stats for the current plugin (see <a class="reference external" href="https://github.com/nicolargo/glances/wiki/The-Glances-2.x-API-How-to">https://github.com/nicolargo/glances/wiki/The-Glances-2.x-API-How-to</a> for the stats list)</p>
<p><em>Note</em>: you can use all the stats for the current plugin (see
<a class="reference external" href="https://github.com/nicolargo/glances/wiki/The-Glances-2.x-API-How-to">https://github.com/nicolargo/glances/wiki/The-Glances-2.x-API-How-to</a> for
the stats list)</p>
</div>
</div>
<div class="section" id="gateway-to-others-services">
<h1><a class="toc-backref" href="#id30">Gateway to others services</a></h1>
<p><em>CSV</em></p>
<h1><a class="toc-backref" href="#id33">Gateway to others services</a></h1>
<div class="section" id="csv">
<h2><a class="toc-backref" href="#id34">CSV</a></h2>
<p>It is possible to export statistics to CSV file.</p>
<pre class="code console literal-block">
<span class="generic prompt">$</span> glances --export-csv /tmp/glances.csv
@ -902,8 +961,12 @@ warning_action=echo {{mnt_point}} {{used}}/{{size}} &gt; /tmp/fs.alert
<p>CSV file description:
- Stats description (first line)
- Stats (others lines)</p>
<p><em>InfluxDB</em></p>
<p>You can export statistics to an InfluxDB server (time series server). The connection should be defined in the Glances configuration file as following:</p>
</div>
<div class="section" id="influxdb">
<h2><a class="toc-backref" href="#id35">InfluxDB</a></h2>
<p>You can export statistics to an <tt class="docutils literal">InfluxDB</tt> server (time series server).
The connection should be defined in the Glances configuration file as
following:</p>
<pre class="code literal-block">
[influxdb]
host=localhost
@ -916,15 +979,22 @@ db=glances
<pre class="code console literal-block">
<span class="generic prompt">$</span> glances --export-influxdb
</pre>
<p><em>Statsd</em></p>
<p>You can export statistics to a Statsd server (welcome to Graphite !). The connection should be defined in the Glances configuration file as following:</p>
<p>For Grafana users, Glances provides a dedicated <a class="reference external" href="https://github.com/nicolargo/glances/blob/master/conf/glances-grafana.json">dashboard</a>. Just import
the file in your <tt class="docutils literal">Grafana</tt> web interface.</p>
<img alt="images/grafana.png" src="images/grafana.png" />
</div>
<div class="section" id="statsd">
<h2><a class="toc-backref" href="#id36">Statsd</a></h2>
<p>You can export statistics to a <tt class="docutils literal">Statsd</tt> server (welcome to Graphite!).
The connection should be defined in the Glances configuration file as
following:</p>
<pre class="code literal-block">
[statsd]
host=localhost
port=8125
prefix=glances
</pre>
<p>Note: the prefix option is optionnal ('glances by default')</p>
<p><em>Note</em>: the prefix option is optional ('glances by default')</p>
<p>and run Glances with:</p>
<pre class="code console literal-block">
<span class="generic prompt">$</span> glances --export-statsd
@ -938,18 +1008,39 @@ prefix=glances
...
</pre>
</div>
<div class="section" id="apis-documentations">
<h1><a class="toc-backref" href="#id31">APIs Documentations</a></h1>
<p>Glances includes a <a class="reference external" href="http://docs.python.org/2/library/simplexmlrpcserver.html">XML-RPC server</a> and a <a class="reference external" href="http://jsonapi.org/">RESTFUL-JSON</a> API which and can be used by another client software.</p>
<p>APIs documentations are available at:</p>
<div class="section" id="rabbitmq">
<h2><a class="toc-backref" href="#id37">RabbitMQ</a></h2>
<p>You can export statistics to an <tt class="docutils literal">RabbitMQ</tt> server (AMQP Broker).
The connection should be defined in the Glances configuration file as
following:</p>
<pre class="code literal-block">
[rabbitmq]
host=localhost
port=5672
user=glances
password=glances
queue=glances_queue
</pre>
<p>and run Glances with:</p>
<pre class="code console literal-block">
<span class="generic prompt">$</span> glances --export-rabbitmq
</pre>
</div>
</div>
<div class="section" id="apis-documentation">
<h1><a class="toc-backref" href="#id38">APIs documentation</a></h1>
<p>Glances includes a <a class="reference external" href="http://docs.python.org/2/library/simplexmlrpcserver.html">XML-RPC server</a> and a <a class="reference external" href="http://jsonapi.org/">RESTFUL-JSON</a> API which can
be used by another client software.</p>
<p>APIs documentation is available at:</p>
<ul class="simple">
<li>XML-RPC: <a class="reference external" href="https://github.com/nicolargo/glances/wiki/The-Glances-2.x-API-How-to">https://github.com/nicolargo/glances/wiki/The-Glances-2.x-API-How-to</a></li>
<li>RESTFUL-JSON: <a class="reference external" href="https://github.com/nicolargo/glances/wiki/The-Glances-RESTFULL-JSON-API">https://github.com/nicolargo/glances/wiki/The-Glances-RESTFULL-JSON-API</a></li>
</ul>
</div>
<div class="section" id="support">
<h1><a class="toc-backref" href="#id32">Support</a></h1>
<p>To post a question about Glances use case, please post it to the offical Q&amp;A <a class="reference external" href="https://groups.google.com/forum/?hl=en#!forum/glances-users">forum</a>.</p>
<h1><a class="toc-backref" href="#id39">Support</a></h1>
<p>To post a question about Glances use cases, please post it to the
official Q&amp;A <a class="reference external" href="https://groups.google.com/forum/?hl=en#!forum/glances-users">forum</a>.</p>
<p>To report a bug or a feature request use the bug tracking system at
<a class="reference external" href="https://github.com/nicolargo/glances/issues">https://github.com/nicolargo/glances/issues</a>.</p>
<p>Feel free to contribute !</p>

View File

@ -67,7 +67,13 @@ and on the client:
where ``@server`` is the IP address or hostname of the server.
Glances can centralize available Glances servers using the ``--browser`` option. The server list can be staticaly defined in the Glances configuration file (section [serverlist]). Glances can also detect and display all Glances servers available on you network (auto discover mode is based on the the Zeroconf protocol only available on GNU/Linux and Mac OS X):
Glances can centralize available Glances servers using the ``--browser``
option. The server list can be statically defined in the Glances
configuration file (section ``[serverlist]``).
Glances can also detect and display all Glances servers available on your
network (auto-discover mode is based on the the ``zeroconf`` protocol,
which is only available on GNU/Linux and OS X):
.. code-block:: console
@ -97,7 +103,7 @@ client, the latter will try to grab stats using the ``SNMP`` protocol:
client$ glances -c @snmpserver
Note: Stats grabbed by SNMP request are limited (operating system dependent).
*Note*: stats grabbed by SNMP request are limited (OS dependent).
Web Server Mode
---------------
@ -117,7 +123,12 @@ and on the client enter the following URL in your favorite web browser:
where ``@server`` is the IP address or hostname of the server.
To change the refresh rate of the page, just add the period in seconds between refreshes at the end of the URL, ie. to refresh every 10s, use ``http://@server:61208/10``.
To change the refresh rate of the page, just add the period in seconds
at the end of the URL. For example, to refresh the page every 10s:
::
http://@server:61208/10
The Glances web interface follows responsive web design principles.
@ -125,7 +136,6 @@ Screenshot from Chrome on Android
.. image:: images/screenshot-web2.png
Command Reference
=================
@ -159,6 +169,8 @@ Command-Line Options
export stats to an InfluxDB server
--export-statsd
export stats to a Statsd server
--export-rabbitmq
export stats to a RabbitMQ server
-c CLIENT, --client CLIENT
connect to a Glances server by IPv4/IPv6 address or
hostname
@ -254,6 +266,8 @@ The following commands (key pressed) are supported while in Glances:
``T``
View network I/O as combination
``u``
Sort processes by USER
``U``
View cumulative network I/O
``w``
Delete finished warning log messages
@ -270,7 +284,8 @@ The following commands (key pressed) are supported while in Glances:
``/``
Switch between short name / command line (processes name)
In the Glances client browser (accessible through the --browser command line argument):
In the Glances client browser (accessible through the ``--browser``
command line argument):
``ENTER``
Run Glances client to the selected server
@ -286,15 +301,20 @@ Configuration
No configuration file is mandatory to use Glances.
Furthermore a configuration file is needed to set up limits, disks or
network interfaces to hide and/or monitored processes list or to define
alias.
Furthermore a configuration file is needed to modify limit alerts, to
set up monitored processes list, to hide disks or network interfaces or
to define alias.
By default, the configuration file is under:
Location
--------
:Linux: ``/etc/glances/glances.conf``
:\*BSD and OS X: ``/usr/local/etc/glances/glances.conf``
:Windows: ``%APPDATA%\glances\glances.conf``
You can put the configuration file ``glances.conf`` in the following
locations:
:Linux: ``~/.config/glances, /etc/glances``
:\*BSD: ``~/.config/glances, /usr/local/etc/glances``
:OS X: ``~/Library/Application Support/glances, /usr/local/etc/glances``
:Windows: ``%APPDATA%\glances``
On Windows XP, the ``%APPDATA%`` path is:
@ -307,24 +327,12 @@ Since Windows Vista and newer versions:
::
C:\Users\<User>\AppData\Roaming
or
%userprofile%\AppData\Roaming
You can override the default configuration, located in one of the above
directories on your system, except for Windows.
User-specific options override system-wide options and options given on
the command line override either.
Just copy the ``glances.conf`` file to your ``$XDG_CONFIG_HOME`` directory,
e.g., on Linux:
.. code-block:: console
mkdir -p $XDG_CONFIG_HOME/glances
cp /usr/share/doc/glances/glances.conf $XDG_CONFIG_HOME/glances/
On OS X, you should copy the configuration file to
``~/Library/Application Support/glances/``.
*Configuration file description*
Syntax
------
Each plugin and export module can have a section.
@ -346,7 +354,8 @@ Example for the CPU plugin:
steal_warning=70
steal_critical=90
By default Steal CPU time alerts aren't logged. If you want to enable log/alert, just add:
By default the ``steal`` CPU time alerts aren't logged. If you want to
enable log/alert, just add:
.. code-block::
@ -361,10 +370,11 @@ can ben logged using the -d option on the command line.
By default, the log file is under:
:Linux, \*BSD and OS X: ``/tmp/glances.log``
:Linux, \*BSD, OS X: ``/tmp/glances.log``
:Windows: ``%APPDATA%\Local\temp\glances.log``
If glances.log is not writable, a new file will be created and returned to the user console.
If ``glances.log`` is not writable, a new file will be created and
returned to the user console.
Anatomy Of The Application
==========================
@ -402,7 +412,8 @@ Disconnected:
QuickLook
---------
The quicklook plugin is only display on wide screen and propose a bar view for CPU and memory (virtual and swap).
The ``quicklook`` plugin is only displayed on wide screen and propose a
bar view for CPU and memory (virtual and swap).
.. image:: images/quicklook.png
@ -532,7 +543,9 @@ If a RAID controller is detected on you system, its status will be displayed:
.. image:: images/raid.png
By default, the plugin only display physical devices only (hard disks, USB keys) and ignore all others. To allow others FS type, you had to use the following section in the configuration file:
By default, the plugin only displays physical devices (hard disks, USB
keys) and ignore all others. To allow others FS type, you have to use the
following section in the configuration file:
::
@ -554,8 +567,8 @@ temperature only.
There is no alert on this information.
*Note*: limit values and sensors alias names can be defined in the configuration
file under the ``[sensors]`` section.
*Note*: limit values and sensors alias names can be defined in the
configuration file under the ``[sensors]`` section.
Processes List
--------------
@ -632,7 +645,8 @@ Process status legend:
``Z``
Zombie
In standalone mode, additionals informations are provided for the top process:
In standalone mode, additional informations are provided for the top
process:
.. image:: images/processlist-top.png
@ -641,7 +655,8 @@ In standalone mode, additionals informations are provided for the top process:
* Open threads, files and network sessions (TCP and UDP)
* IO nice level
The extended stats feature could be enabled using the --enable-process-extended option (command line) or the ``e`` key (curses interface).
The extended stats feature could be enabled using the ``--enable-process-extended``
option (command line) or the ``e`` key (curses interface).
*Note*: limit values can be overwritten in the configuration file under
the ``[process]`` section.
@ -729,16 +744,19 @@ Each alert message displays the following information:
Docker
------
If you use Docker, Glances can help you to monitor your container. Glances uses the Docker API through the Docker-Py library.
If you use ``Docker``, Glances can help you to monitor your container.
Glances uses the Docker API through the ``docker-py`` library.
.. image:: images/docker.png
Actions
-------
Glances can trigger actions on events.
Glances can trigger actions on events.
By action, we mean all shell command line. For example, if you want to execute the foo.py script if the last 5 minutes load are critical then add the action line to the Glances configuration file:
By ``action``, we mean all shell command line. For example, if you want
to execute the ``foo.py`` script if the last 5 minutes load are critical
then add the action line to the Glances configuration file:
.. code-block::
@ -746,7 +764,9 @@ By action, we mean all shell command line. For example, if you want to execute t
critical=5.0
critical_action=python /path/to/foo.py
All the stats are available in the command line through the use of the {{mustache}} syntax. Another example to create a log file containing used vs total disk space if a space trigger warning is reached:
All the stats are available in the command line through the use of the
``{{mustache}}`` syntax. Another example would be to create a log file
containing used vs total disk space if a space trigger warning is reached:
.. code-block::
@ -754,13 +774,15 @@ All the stats are available in the command line through the use of the {{mustach
warning=70
warning_action=echo {{mnt_point}} {{used}}/{{size}} > /tmp/fs.alert
*Note*: You can use all the stats for the current plugin (see https://github.com/nicolargo/glances/wiki/The-Glances-2.x-API-How-to for the stats list)
*Note*: you can use all the stats for the current plugin (see
https://github.com/nicolargo/glances/wiki/The-Glances-2.x-API-How-to for
the stats list)
Gateway to others services
==========================
*CSV*
CSV
---
It is possible to export statistics to CSV file.
@ -772,9 +794,12 @@ CSV file description:
- Stats description (first line)
- Stats (others lines)
*InfluxDB*
InfluxDB
--------
You can export statistics to an InfluxDB server (time series server). The connection should be defined in the Glances configuration file as following:
You can export statistics to an ``InfluxDB`` server (time series server).
The connection should be defined in the Glances configuration file as
following:
.. code-block::
@ -791,13 +816,17 @@ and run Glances with:
$ glances --export-influxdb
For Grafana users', Glances provides a dedicated `dashboard`_. Just import the file in your Grafana Web interface.
For Grafana users, Glances provides a dedicated `dashboard`_. Just import
the file in your ``Grafana`` web interface.
.. image:: images/grafana.png
*Statsd*
Statsd
------
You can export statistics to a Statsd server (welcome to Graphite !). The connection should be defined in the Glances configuration file as following:
You can export statistics to a ``Statsd`` server (welcome to Graphite!).
The connection should be defined in the Glances configuration file as
following:
.. code-block::
@ -806,7 +835,7 @@ You can export statistics to a Statsd server (welcome to Graphite !). The connec
port=8125
prefix=glances
Note: the prefix option is optionnal ('glances by default')
*Note*: the prefix option is optional ('glances by default')
and run Glances with:
@ -824,13 +853,35 @@ Glances will generate stats as:
'glances.load.min1': 0.19,
...
RabbitMQ
--------
APIs Documentations
===================
You can export statistics to an ``RabbitMQ`` server (AMQP Broker).
The connection should be defined in the Glances configuration file as
following:
Glances includes a `XML-RPC server`_ and a `RESTFUL-JSON`_ API which and can be used by another client software.
.. code-block::
APIs documentations are available at:
[rabbitmq]
host=localhost
port=5672
user=glances
password=glances
queue=glances_queue
and run Glances with:
.. code-block:: console
$ glances --export-rabbitmq
APIs documentation
==================
Glances includes a `XML-RPC server`_ and a `RESTFUL-JSON`_ API which can
be used by another client software.
APIs documentation is available at:
- XML-RPC: https://github.com/nicolargo/glances/wiki/The-Glances-2.x-API-How-to
- RESTFUL-JSON: https://github.com/nicolargo/glances/wiki/The-Glances-RESTFULL-JSON-API
@ -838,7 +889,8 @@ APIs documentations are available at:
Support
=======
To post a question about Glances use case, please post it to the offical Q&A `forum`_.
To post a question about Glances use cases, please post it to the
official Q&A `forum`_.
To report a bug or a feature request use the bug tracking system at
https://github.com/nicolargo/glances/issues.
@ -853,4 +905,4 @@ Feel free to contribute !
.. _XML-RPC server: http://docs.python.org/2/library/simplexmlrpcserver.html
.. _RESTFUL-JSON: http://jsonapi.org/
.. _forum: https://groups.google.com/forum/?hl=en#!forum/glances-users
.. _forum: https://github.com/nicolargo/glances/blob/master/conf/glances-grafana.json
.. _dashboard: https://github.com/nicolargo/glances/blob/master/conf/glances-grafana.json

View File

@ -219,17 +219,20 @@ class GlancesClient(object):
exitkey = False
while True and not exitkey:
# Update the stats
cs_status = self.update()
try:
while True and not exitkey:
# Update the stats
cs_status = self.update()
# Update the screen
exitkey = self.screen.update(self.stats,
cs_status=cs_status,
return_to_browser=self.return_to_browser)
# Update the screen
exitkey = self.screen.update(self.stats,
cs_status=cs_status,
return_to_browser=self.return_to_browser)
# Export stats using export modules
self.stats.export(self.stats)
# Export stats using export modules
self.stats.export(self.stats)
finally:
self.end
return self.client_mode

View File

@ -80,7 +80,7 @@ class GlancesClientBrowser(object):
else:
return 'http://{0}:{1}'.format(server['ip'], server['port'])
def serve_forever(self):
def __serve_forever(self):
"""Main client loop."""
while True:
# No need to update the server list
@ -213,6 +213,15 @@ class GlancesClientBrowser(object):
# Return to the browser (no server selected)
self.screen.active_server = None
def serve_forever(self):
"""Wrapper to the serve_forever function
this function will restore the terminal to a sane state
before re-raising the exception and generating a traceback"""
try:
return self.__serve_forever()
finally:
self.end()
def set_in_selected(self, key, value):
"""Set the (key, value) for the selected server in the list."""
# Static list then dynamic one

View File

@ -23,10 +23,10 @@
import os
import sys
try:
from configparser import RawConfigParser
from configparser import ConfigParser
from configparser import NoOptionError
except ImportError: # Python 2
from ConfigParser import RawConfigParser
from ConfigParser import SafeConfigParser as ConfigParser
from ConfigParser import NoOptionError
# Import Glances lib
@ -37,8 +37,7 @@ from glances.core.glances_globals import (
is_mac,
is_py3,
is_windows,
sys_prefix,
work_path
sys_prefix
)
from glances.core.glances_logging import logger
@ -47,96 +46,177 @@ class Config(object):
"""This class is used to access/read config file, if it exists.
:param location: the custom path to search for config file
:type location: str or None
:param config_dir: the path to search for config file
:type config_dir: str or None
"""
def __init__(self, location=None):
self.location = location
def __init__(self, config_dir=None):
self.config_dir = config_dir
self.config_filename = 'glances.conf'
self.parser = RawConfigParser()
self._loaded_config_file = None
self.load()
def load(self):
"""Load a config file from the list of paths, if it exists."""
for config_file in self.get_config_paths():
if os.path.isfile(config_file) and os.path.getsize(config_file) > 0:
try:
if is_py3:
self.parser.read(config_file, encoding='utf-8')
else:
self.parser.read(config_file)
logger.info("Read configuration file '{0}'".format(config_file))
except UnicodeDecodeError as e:
logger.error("Cannot decode configuration file '{0}': {1}".format(config_file, e))
sys.exit(1)
# Save the loaded configuration file path (issue #374)
self._loaded_config_file = config_file
break
self.parser = ConfigParser()
self.read()
def get_loaded_config_file(self):
"""Return the loaded configuration file"""
return self._loaded_config_file
def get_config_paths(self):
def config_file_paths(self):
r"""Get a list of config file paths.
The list is built taking into account of the OS, priority and location.
* running from source: /path/to/glances/conf
* per-user install: ~/.local/etc/glances (Unix-like only)
* custom path: /path/to/glances
* Linux: ~/.config/glances, /etc/glances
* BSD: ~/.config/glances, /usr/local/etc/glances
* Mac: ~/Library/Application Support/glances, /usr/local/etc/glances
* OS X: ~/Library/Application Support/glances, /usr/local/etc/glances
* Windows: %APPDATA%\glances
The config file will be searched in the following order of priority:
* /path/to/file (via -C flag)
* /path/to/glances/conf
* user's local directory (per-user install settings)
* user's home directory (per-user settings)
* {/usr/local,}/etc directory (system-wide settings)
* system-wide directory (system-wide settings)
"""
paths = []
conf_path = os.path.realpath(
os.path.join(work_path, '..', '..', 'conf'))
if self.location is not None:
paths.append(self.location)
if os.path.exists(conf_path):
paths.append(os.path.join(conf_path, self.config_filename))
if not is_windows:
paths.append(os.path.join(os.path.expanduser('~/.local'), 'etc', appname, self.config_filename))
if self.config_dir:
paths.append(self.config_dir)
if is_linux or is_bsd:
paths.append(os.path.join(
os.environ.get('XDG_CONFIG_HOME') or os.path.expanduser(
'~/.config'),
appname, self.config_filename))
if hasattr(sys, 'real_prefix') or is_bsd:
paths.append(
os.path.join(os.environ.get('XDG_CONFIG_HOME') or
os.path.expanduser('~/.config'),
appname, self.config_filename))
if is_bsd:
paths.append(
os.path.join(sys.prefix, 'etc', appname, self.config_filename))
else:
paths.append(
os.path.join('/etc', appname, self.config_filename))
elif is_mac:
paths.append(os.path.join(
os.path.expanduser('~/Library/Application Support/'),
appname, self.config_filename))
paths.append(os.path.join(
sys_prefix, 'etc', appname, self.config_filename))
paths.append(
os.path.join(os.path.expanduser('~/Library/Application Support/'),
appname, self.config_filename))
paths.append(
os.path.join(sys_prefix, 'etc', appname, self.config_filename))
elif is_windows:
paths.append(os.path.join(
os.environ.get('APPDATA'), appname, self.config_filename))
paths.append(
os.path.join(os.environ.get('APPDATA'), appname, self.config_filename))
return paths
def read(self):
"""Read the config file, if it exists. Using defaults otherwise."""
for config_file in self.config_file_paths():
if os.path.exists(config_file):
try:
if is_py3:
self.parser.read(config_file, encoding='utf-8')
else:
self.parser.read(config_file)
logger.info("Read configuration file '{0}'".format(config_file))
except UnicodeDecodeError as err:
logger.error("Cannot decode configuration file '{0}': {1}".format(config_file, err))
sys.exit(1)
# Save the loaded configuration file path (issue #374)
self._loaded_config_file = config_file
break
# Quicklook
if not self.parser.has_section('quicklook'):
self.parser.add_section('quicklook')
self.parser.set('quicklook', 'cpu_careful', '50')
self.parser.set('quicklook', 'cpu_warning', '70')
self.parser.set('quicklook', 'cpu_critical', '90')
self.parser.set('quicklook', 'mem_careful', '50')
self.parser.set('quicklook', 'mem_warning', '70')
self.parser.set('quicklook', 'mem_critical', '90')
self.parser.set('quicklook', 'swap_careful', '50')
self.parser.set('quicklook', 'swap_warning', '70')
self.parser.set('quicklook', 'swap_critical', '90')
# CPU
if not self.parser.has_section('cpu'):
self.parser.add_section('cpu')
self.parser.set('cpu', 'user_careful', '50')
self.parser.set('cpu', 'user_warning', '70')
self.parser.set('cpu', 'user_critical', '90')
self.parser.set('cpu', 'iowait_careful', '50')
self.parser.set('cpu', 'iowait_warning', '70')
self.parser.set('cpu', 'iowait_critical', '90')
self.parser.set('cpu', 'system_careful', '50')
self.parser.set('cpu', 'system_warning', '70')
self.parser.set('cpu', 'system_critical', '90')
self.parser.set('cpu', 'steal_careful', '50')
self.parser.set('cpu', 'steal_warning', '70')
self.parser.set('cpu', 'steal_critical', '90')
# Per-CPU
if not self.parser.has_section('percpu'):
self.parser.add_section('percpu')
self.parser.set('percpu', 'user_careful', '50')
self.parser.set('percpu', 'user_warning', '70')
self.parser.set('percpu', 'user_critical', '90')
self.parser.set('percpu', 'iowait_careful', '50')
self.parser.set('percpu', 'iowait_warning', '70')
self.parser.set('percpu', 'iowait_critical', '90')
self.parser.set('percpu', 'system_careful', '50')
self.parser.set('percpu', 'system_warning', '70')
self.parser.set('percpu', 'system_critical', '90')
# Load
if not self.parser.has_section('load'):
self.parser.add_section('load')
self.parser.set('load', 'careful', '0.7')
self.parser.set('load', 'warning', '1.0')
self.parser.set('load', 'critical', '5.0')
# Mem
if not self.parser.has_section('mem'):
self.parser.add_section('mem')
self.parser.set('mem', 'careful', '50')
self.parser.set('mem', 'warning', '70')
self.parser.set('mem', 'critical', '90')
# Swap
if not self.parser.has_section('memswap'):
self.parser.add_section('memswap')
self.parser.set('memswap', 'careful', '50')
self.parser.set('memswap', 'warning', '70')
self.parser.set('memswap', 'critical', '90')
# FS
if not self.parser.has_section('fs'):
self.parser.add_section('fs')
self.parser.set('fs', 'careful', '50')
self.parser.set('fs', 'warning', '70')
self.parser.set('fs', 'critical', '90')
# Sensors
if not self.parser.has_section('sensors'):
self.parser.add_section('sensors')
self.parser.set('sensors', 'temperature_core_careful', '60')
self.parser.set('sensors', 'temperature_core_warning', '70')
self.parser.set('sensors', 'temperature_core_critical', '80')
self.parser.set('sensors', 'temperature_hdd_careful', '45')
self.parser.set('sensors', 'temperature_hdd_warning', '52')
self.parser.set('sensors', 'temperature_hdd_critical', '60')
self.parser.set('sensors', 'battery_careful', '80')
self.parser.set('sensors', 'battery_warning', '90')
self.parser.set('sensors', 'battery_critical', '95')
# Process list
if not self.parser.has_section('processlist'):
self.parser.add_section('processlist')
self.parser.set('cpu', 'careful', '50')
self.parser.set('cpu', 'warning', '70')
self.parser.set('cpu', 'critical', '90')
self.parser.set('mem', 'careful', '50')
self.parser.set('mem', 'warning', '70')
self.parser.set('mem', 'critical', '90')
@property
def loaded_config_file(self):
"""Return the loaded configuration file."""
return self._loaded_config_file
def items(self, section):
"""Return the items list of a section."""
return self.parser.items(section)
@ -145,20 +225,16 @@ class Config(object):
"""Return info about the existence of a section."""
return self.parser.has_section(section)
def get_option(self, section, option):
def get_value(self, section, option, default=None):
"""Get the value of an option, if it exists."""
try:
return self.parser.get(section, option)
except NoOptionError:
return default
def get_float_value(self, section, option, default=0.0):
"""Get the float value of an option, if it exists."""
try:
value = self.parser.getfloat(section, option)
return self.parser.getfloat(section, option)
except NoOptionError:
return
else:
return value
def get_raw_option(self, section, option):
"""Get the raw value of an option, if it exists."""
try:
value = self.parser.get(section, option)
except NoOptionError:
return
else:
return value
return float(default)

View File

@ -60,6 +60,5 @@ def get_locale_path(paths):
# i18n
gettext_domain = appname
i18n_path = os.path.realpath(os.path.join(work_path, '..', '..', 'i18n'))
user_i18n_path = os.path.join(os.path.expanduser('~/.local'), 'share', 'locale')
sys_i18n_path = os.path.join(sys_prefix, 'share', 'locale')
locale_dir = get_locale_path([i18n_path, user_i18n_path, sys_i18n_path])
locale_dir = get_locale_path([i18n_path, sys_i18n_path])

View File

@ -139,6 +139,7 @@ Start the client browser (browser mode):\n\
dest='export_influxdb', help=_('export stats to an InfluxDB server (need InfluDB lib)'))
parser.add_argument('--export-statsd', action='store_true', default=False,
dest='export_statsd', help=_('export stats to a Statsd server (need StatsD lib)'))
parser.add_argument('--export-rabbitmq', action='store_true', default=False, dest='export_rabbitmq', help=_('export stats to rabbitmq broker (need pika lib or python3-pika lib)'))
# Client/Server option
parser.add_argument('-c', '--client', dest='client',
help=_('connect to a Glances server by IPv4/IPv6 address or hostname'))

View File

@ -49,11 +49,12 @@ class MonitorList(object):
__monitor_list = []
def __init__(self, config):
"""Init the monitoring list from the configuration file."""
"""Init the monitoring list from the configuration file, if it exists."""
self.config = config
if self.config is not None and self.config.has_section('monitor'):
# Process monitoring list
logger.debug("Monitor list configuration detected")
self.__set_monitor_list('monitor', 'list')
else:
self.__monitor_list = []
@ -67,11 +68,11 @@ class MonitorList(object):
value = {}
key = "list_" + str(l) + "_"
try:
description = self.config.get_raw_option(section, key + "description")
regex = self.config.get_raw_option(section, key + "regex")
command = self.config.get_raw_option(section, key + "command")
countmin = self.config.get_raw_option(section, key + "countmin")
countmax = self.config.get_raw_option(section, key + "countmax")
description = self.config.get_value(section, key + 'description')
regex = self.config.get_value(section, key + 'regex')
command = self.config.get_value(section, key + 'command')
countmin = self.config.get_value(section, key + 'countmin')
countmax = self.config.get_value(section, key + 'countmax')
except Exception as e:
logger.error("Cannot read monitored list: {0}".format(e))
else:

View File

@ -19,7 +19,6 @@
# Import Python lib
import collections
import operator
import os
import re
@ -50,13 +49,13 @@ class ProcessTreeNode(object):
We avoid recursive algorithm to manipulate the tree because function calls are expensive with CPython.
"""
def __init__(self, process=None, stats=None, sort_key=None, root=False):
def __init__(self, process=None, stats=None, sort_key=None, sort_reverse=True, root=False):
self.process = process
self.stats = stats
self.children = []
self.children_sorted = False
self.sort_key = sort_key
self.reverse_sorting = (self.sort_key != "name")
self.sort_reverse = sort_reverse
self.is_root = root
def __str__(self):
@ -87,7 +86,7 @@ class ProcessTreeNode(object):
def set_sorting(self, key, reverse):
""" Set sorting key or func for user with __iter__ (affects the whole tree from this node). """
if self.sort_key != key or self.reverse_sorting != reverse:
if self.sort_key != key or self.sort_reverse != reverse:
nodes_to_flag_unsorted = collections.deque([self])
while nodes_to_flag_unsorted:
current_node = nodes_to_flag_unsorted.pop()
@ -98,7 +97,7 @@ class ProcessTreeNode(object):
def get_weight(self):
""" Return "weight" of a process and all its children for sorting. """
if self.sort_key == "name":
if self.sort_key == 'name' or self.sort_key == 'username':
return self.stats[self.sort_key]
# sum ressource usage for self and children
@ -138,7 +137,7 @@ class ProcessTreeNode(object):
# optimization to avoid sorting twice (once when limiting the maximum processes to grab stats for,
# and once before displaying)
self.children.sort(
key=self.__class__.get_weight, reverse=self.reverse_sorting)
key=self.__class__.get_weight, reverse=self.sort_reverse)
self.children_sorted = True
for child in self.children:
for n in iter(child):
@ -156,7 +155,7 @@ class ProcessTreeNode(object):
# optimization to avoid sorting twice (once when limiting the maximum processes to grab stats for,
# and once before displaying)
self.children.sort(
key=self.__class__.get_weight, reverse=self.reverse_sorting)
key=self.__class__.get_weight, reverse=self.sort_reverse)
self.children_sorted = True
for child in self.children:
if not exclude_incomplete_stats or "time_since_update" in child.stats:
@ -172,14 +171,14 @@ class ProcessTreeNode(object):
nodes_to_search.extend(current_node.children)
@staticmethod
def build_tree(process_dict, sort_key, hide_kernel_threads):
def build_tree(process_dict, sort_key, sort_reverse, hide_kernel_threads):
""" Build a process tree using using parent/child relationships, and return the tree root node. """
tree_root = ProcessTreeNode(root=True)
nodes_to_add_last = collections.deque()
# first pass: add nodes whose parent are in the tree
for process, stats in process_dict.items():
new_node = ProcessTreeNode(process, stats, sort_key)
new_node = ProcessTreeNode(process, stats, sort_key, sort_reverse)
try:
parent_process = process.parent()
except psutil.NoSuchProcess:
@ -347,6 +346,14 @@ class GlancesProcesses(object):
""" Return True if process tree is enabled, False instead. """
return self._enable_tree
@property
def sort_reverse(self):
"""Return True to sort processes in reverse 'key' order, False instead."""
if self.sort_key == 'name' or self.sort_key == 'username':
return False
return True
def __get_mandatory_stats(self, proc, procstat):
"""
Get mandatory_stats: need for the sorting/filter step
@ -355,12 +362,13 @@ class GlancesProcesses(object):
procstat['mandatory_stats'] = True
# Process CPU, MEM percent and name
procstat.update(
proc.as_dict(attrs=['cpu_percent', 'memory_percent', 'name', 'cpu_times'], ad_value=''))
procstat.update(proc.as_dict(
attrs=['username', 'cpu_percent', 'memory_percent',
'name', 'cpu_times'], ad_value=''))
if procstat['cpu_percent'] == '' or procstat['memory_percent'] == '':
# Do not display process if we cannot get the basic
# cpu_percent or memory_percent stats
raise psutil.NoSuchProcess
return None
# Process command line (cached with internal cache)
try:
@ -540,15 +548,12 @@ class GlancesProcesses(object):
procstat = proc.as_dict(attrs=['pid'])
if mandatory_stats:
try:
procstat = self.__get_mandatory_stats(proc, procstat)
except psutil.NoSuchProcess:
return None
procstat = self.__get_mandatory_stats(proc, procstat)
if standard_stats:
if procstat is not None and standard_stats:
procstat = self.__get_standard_stats(proc, procstat)
if extended_stats and not self.disable_extended_tag:
if procstat is not None and extended_stats and not self.disable_extended_tag:
procstat = self.__get_extended_stats(proc, procstat)
return procstat
@ -614,6 +619,7 @@ class GlancesProcesses(object):
if self._enable_tree:
self.process_tree = ProcessTreeNode.build_tree(processdict,
self.sort_key,
self.sort_reverse,
self.no_kernel_threads)
for i, node in enumerate(self.process_tree):
@ -639,8 +645,9 @@ class GlancesProcesses(object):
# Sort the internal dict and cut the top N (Return a list of tuple)
# tuple=key (proc), dict (returned by __get_process_stats)
try:
processiter = sorted(
processdict.items(), key=lambda x: x[1][self.sort_key], reverse=True)
processiter = sorted(processdict.items(),
key=lambda x: x[1][self.sort_key],
reverse=self.sort_reverse)
except (KeyError, TypeError) as e:
logger.error("Cannot sort process list by {0}: {1}".format(self.sort_key, e))
logger.error("%s" % str(processdict.items()[0]))
@ -710,36 +717,5 @@ class GlancesProcesses(object):
def sort_key(self, key):
"""Set the current sort key."""
self._sort_key = key
if not self.auto_sort and self._enable_tree and self.process_tree is not None:
self.process_tree.set_sorting(key, key != "name")
def getsortlist(self, sortedby=None):
"""Get the sorted processlist."""
if sortedby is None:
# No need to sort...
return self.processlist
sortedreverse = True
if sortedby == 'name':
sortedreverse = False
if sortedby == 'io_counters':
# Specific case for io_counters
# Sum of io_r + io_w
try:
# Sort process by IO rate (sum IO read + IO write)
self.processlist.sort(key=lambda process: process[sortedby][0] -
process[sortedby][2] + process[sortedby][1] -
process[sortedby][3],
reverse=sortedreverse)
except Exception:
self.processlist.sort(key=operator.itemgetter('cpu_percent'),
reverse=sortedreverse)
else:
# Others sorts
self.processlist.sort(key=operator.itemgetter(sortedby),
reverse=sortedreverse)
return self.processlist
glances_processes = GlancesProcesses()

View File

@ -79,7 +79,7 @@ class GlancesStandalone(object):
def quiet(self):
return self._quiet
def serve_forever(self):
def __serve_forever(self):
"""Main loop for the CLI."""
while True:
# Update system informations
@ -95,6 +95,15 @@ class GlancesStandalone(object):
# Export stats using export modules
self.stats.export(self.stats)
def serve_forever(self):
"""Wrapper to the serve_forever function
this function will restore the terminal to a sane state
before re-raising the exception and generating a traceback"""
try:
return self.__serve_forever()
finally:
self.end()
def end(self):
"""End of the standalone CLI."""
if not self.quiet:

View File

@ -54,7 +54,7 @@ class GlancesStaticServer(object):
postfix = 'server_%s_' % str(i)
# Read the server name (mandatory)
for s in ['name', 'port', 'alias']:
new_server[s] = config.get_raw_option(self._section, '%s%s' % (postfix, s))
new_server[s] = config.get_value(self._section, '%s%s' % (postfix, s))
if new_server['name'] is not None:
# Manage optionnal information
if new_server['port'] is None:

View File

@ -61,11 +61,11 @@ class Export(GlancesExport):
if self.config is None:
return False
try:
self.host = self.config.get_raw_option(section, "host")
self.port = self.config.get_raw_option(section, "port")
self.user = self.config.get_raw_option(section, "user")
self.password = self.config.get_raw_option(section, "password")
self.db = self.config.get_raw_option(section, "db")
self.host = self.config.get_value(section, 'host')
self.port = self.config.get_value(section, 'port')
self.user = self.config.get_value(section, 'user')
self.password = self.config.get_value(section, 'password')
self.db = self.config.get_value(section, 'db')
except NoSectionError:
logger.critical("No InfluxDB configuration found")
return False
@ -76,7 +76,7 @@ class Export(GlancesExport):
logger.debug("Load InfluxDB from the Glances configuration file")
# Prefix is optional
try:
self.prefix = self.config.get_raw_option(section, "prefix")
self.prefix = self.config.get_value(section, 'prefix')
except NoOptionError as e:
pass
return True

View File

@ -0,0 +1,105 @@
# -*- coding: utf-8 -*-
#
# This file is part of Glances.
#
# Copyright (C) 2015 Nicolargo <nicolas@nicolargo.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/>.
"""JMS interface class."""
# Import sys libs
import sys, socket, datetime
from numbers import Number
# Import Glances lib
from glances.core.glances_logging import logger
try:
from configparser import NoOptionError, NoSectionError
except ImportError: # Python 2
from ConfigParser import NoOptionError, NoSectionError
from glances.exports.glances_export import GlancesExport
# Import pika for RabbitMQ
import pika
class Export(GlancesExport):
"""This class manages the rabbitMQ export module."""
def __init__(self, config=None, args=None):
"""Init the RabbitMQ export IF."""
GlancesExport.__init__(self, config=config, args=args)
# Load the rabbitMQ configuration file
self.rabbitmq_host = None
self.rabbitmq_port = None
self.rabbitmq_user = None
self.rabbitmq_password = None
self.rabbitmq_queue = None
self.hostname = socket.gethostname()
self.export_enable = self.load_conf()
if not self.export_enable:
sys.exit(2)
# Init the rabbitmq client
self.client = self.init()
def load_conf(self, section="rabbitmq"):
"""Load the rabbitmq configuration in the Glances configuration file"""
if self.config is None:
return False
try:
self.rabbitmq_host = self.config.get_value(section, 'host')
self.rabbitmq_port = self.config.get_value(section, 'port')
self.rabbitmq_user = self.config.get_value(section, 'user')
self.rabbitmq_password = self.config.get_value(section, 'password')
self.rabbitmq_queue = self.config.get_value(section, 'queue')
except NoSectionError:
logger.critical("No rabbitmq configuration found")
return False
except NoOptionError as e:
logger.critical("Error in the RabbitM configuration (%s)" % e)
return False
else:
logger.debug("Load RabbitMQ from the Glances configuration file")
return True
def init(self):
"""Init the connection to the rabbitmq server"""
if not self.export_enable:
return None
try:
parameters = pika.URLParameters("amqp://"+self.rabbitmq_user+":"+self.rabbitmq_password+"@"+self.rabbitmq_host+":"+self.rabbitmq_port+"/")
connection = pika.BlockingConnection(parameters)
channel = connection.channel()
return channel
except Exception as e:
logger.critical("Connection to rabbitMQ failed : %s " % e)
return None
def export(self, name, columns, points):
"""Write the points in RabbitMQ"""
data = "hostname="+self.hostname+", name="+name+", dateinfo="+datetime.datetime.utcnow().isoformat()
for i in range(0, len(columns)):
if not isinstance(points[i], Number):
continue
else:
data += ", " + columns[i] + "=" + str(points[i])
logger.debug(data)
try:
self.client.basic_publish(exchange='', routing_key=self.rabbitmq_queue, body=data)
except Exception as e:
logger.error("Can not export stats to RabbitMQ (%s)" % e)

View File

@ -64,8 +64,8 @@ class Export(GlancesExport):
if self.config is None:
return False
try:
self.host = self.config.get_raw_option(section, "host")
self.port = self.config.get_raw_option(section, "port")
self.host = self.config.get_value(section, 'host')
self.port = self.config.get_value(section, 'port')
except NoSectionError:
logger.critical("No Statsd configuration found")
return False
@ -76,7 +76,7 @@ class Export(GlancesExport):
logger.debug("Load Statsd from the Glances configuration file")
# Prefix is optional
try:
self.prefix = self.config.get_raw_option(section, "prefix")
self.prefix = self.config.get_value(section, 'prefix')
except NoOptionError as e:
pass
return True

View File

@ -328,7 +328,11 @@ class _GlancesCurses(object):
# 'T' > View network traffic as sum Rx+Tx
self.args.network_sum = not self.args.network_sum
elif self.pressedkey == ord('u'):
# 'u' > View cumulative network IO (instead of bitrate)
# 'u' > Sort processes by USER
glances_processes.auto_sort = False
glances_processes.sort_key = 'username'
elif self.pressedkey == ord('U'):
# 'U' > View cumulative network I/O (instead of bitrate)
self.args.network_cumul = not self.args.network_cumul
elif self.pressedkey == ord('w'):
# 'w' > Delete finished warning logs
@ -363,10 +367,8 @@ class _GlancesCurses(object):
def init_line_column(self):
"""Init the line and column position for the curses inteface"""
self.line = 0
self.column = 0
self.next_line = 0
self.next_column = 0
self.init_line()
self.init_column()
def init_line(self):
"""Init the line position for the curses inteface"""
@ -687,10 +689,8 @@ class _GlancesCurses(object):
popup.border()
# Add the message
y = 0
for m in message.split('\n'):
for y, m in enumerate(message.split('\n')):
popup.addnstr(2 + y, 2, m, len(m))
y += 1
if is_input and not is_windows:
# Create a subwindow for the text field
@ -793,7 +793,7 @@ class _GlancesCurses(object):
try:
# Python 2: we need to decode to get real screen size because utf-8 special tree chars
# occupy several bytes
offset = len(m['msg'].decode("utf-8"))
offset = len(m['msg'].decode("utf-8", "replace"))
except AttributeError:
# Python 3: strings are strings and bytes are bytes, all is
# good
@ -1087,16 +1087,14 @@ class GlancesCursesBrowser(_GlancesCurses):
y = 2
# Display table header
cpt = 0
xc = x + 2
for c in column_def:
for cpt, c in enumerate(column_def):
if xc < screen_x and y < screen_y and c[1] is not None:
self.term_window.addnstr(y, xc,
c[1],
screen_x - x,
self.colors_list['BOLD'])
xc += c[2] + self.space_between_column
cpt += 1
y += 1
# If a servers has been deleted from the list...

View File

@ -157,6 +157,10 @@ class Plugin(GlancesPlugin):
# Create a dict with all the containers' stats instance
self.docker_stats = {}
# TODO: Find a way to correct this
# The following optimization is not compatible with the network stats
# The self.docker_client.stats method should be call every time in order to have network stats refreshed
# Nevertheless, if we call it every time, Glances is slow...
if c['Id'] not in self.docker_stats:
# Create the stats instance for the current container
try:
@ -167,6 +171,7 @@ class Plugin(GlancesPlugin):
# Get the docker stats
try:
# self.docker_stats[c['Id']] = self.docker_client.stats(c['Id'], decode=True)
all_stats = self.docker_stats[c['Id']].next()
except:
all_stats = {}
@ -209,24 +214,53 @@ class Plugin(GlancesPlugin):
Input: id is the full container id
all_stats is the output of the stats method of the Docker API
Output: a dict {'total': 1.49}"""
ret = {}
cpu_new = {}
ret = {'total': 0.0}
# Read the stats
# try:
# ret['total'] = all_stats['cpu_stats']['cpu_usage']['total_usage']
# except KeyError as e:
# # all_stats do not have CPU information
# logger.error("Can not grab CPU usage for container {0} ({1})".format(container_id, e))
# # Trying fallback to old grab method
# ret = self.get_docker_cpu_old(container_id)
# For each container, you will find a pseudo-file cpuacct.stat,
# containing the CPU usage accumulated by the processes of the container.
# Those times are expressed in ticks of 1/USER_HZ of a second.
# On x86 systems, USER_HZ is 100.
try:
cpu_new['total'] = all_stats['cpu_stats']['cpu_usage']['total_usage']
cpu_new['system'] = all_stats['cpu_stats']['system_cpu_usage']
cpu_new['nb_core'] = len(all_stats['cpu_stats']['cpu_usage']['percpu_usage'])
except KeyError as e:
# all_stats do not have CPU information
logger.debug("Can not grab CPU usage for container {0} ({1}). Trying fallback method.".format(container_id, e))
# Trying fallback to old grab method
ret = self.get_docker_cpu_old(container_id)
# Get the user ticks
ticks = self.get_user_ticks()
for k in ret.keys():
ret[k] = float(ret[k]) / ticks
else:
# Previous CPU stats stored in the cpu_old variable
if not hasattr(self, 'cpu_old'):
# First call, we init the cpu_old variable
self.cpu_old = {}
try:
self.cpu_old[container_id] = cpu_new
except (IOError, UnboundLocalError):
pass
# Did not work has expected, replace by the old method...
ret = self.get_docker_cpu_old(container_id)
if container_id not in self.cpu_old:
try:
self.cpu_old[container_id] = cpu_new
except (IOError, UnboundLocalError):
pass
else:
#
cpu_delta = float(cpu_new['total'] - self.cpu_old[container_id]['total'])
system_delta = float(cpu_new['system'] - self.cpu_old[container_id]['system'])
if cpu_delta > 0.0 and system_delta > 0.0:
ret['total'] = (cpu_delta / system_delta) * float(cpu_new['nb_core']) * 100
# Save stats to compute next stats
self.cpu_old[container_id] = cpu_new
# Get the user ticks
ticks = self.get_user_ticks()
for k in ret.keys():
ret[k] = float(ret[k]) / ticks
# Return the stats
return ret
@ -262,7 +296,7 @@ class Plugin(GlancesPlugin):
ret['max_usage'] = all_stats['memory_stats']['max_usage']
except KeyError as e:
# all_stats do not have MEM information
logger.error("Can not grab MEM usage for container {0} ({1})".format(container_id, e))
logger.debug("Can not grab MEM usage for container {0} ({1}). Trying fallback method.".format(container_id, e))
# Trying fallback to old grab method
ret = self.get_docker_memory_old(container_id)
# Return the stats
@ -303,7 +337,7 @@ class Plugin(GlancesPlugin):
# By storing time data we enable Rx/s and Tx/s calculations in the
# XML/RPC API, which would otherwise be overly difficult work
# for users of the API
network_new['time_since_update'] = getTimeSinceLastUpdate('docker_net')
network_new['time_since_update'] = getTimeSinceLastUpdate('docker_net_{}'.format(container_id))
network_new['rx'] = netiocounters["rx_bytes"] - self.netiocounters_old[container_id]["rx_bytes"]
network_new['tx'] = netiocounters["tx_bytes"] - self.netiocounters_old[container_id]["tx_bytes"]
network_new['cumulative_rx'] = netiocounters["rx_bytes"]

View File

@ -55,7 +55,7 @@ class Plugin(GlancesPlugin):
self.view_data['psutil_version'] = _(" with PSutil {0}").format(psutil_version)
try:
self.view_data['configuration_file'] = '{0}: {1}'.format(_("Configuration file"), self.config.get_loaded_config_file())
self.view_data['configuration_file'] = '{0}: {1}'.format(_("Configuration file"), self.config.loaded_config_file())
except AttributeError:
pass
@ -123,7 +123,6 @@ class Plugin(GlancesPlugin):
ret.append(self.curse_new_line())
ret.append(self.curse_add_line(self.view_data['show_mem']))
ret.append(self.curse_add_line(self.view_data['delete_warning_alerts']))
ret.append(self.curse_new_line())

View File

@ -41,8 +41,7 @@ class Plugin(GlancesPlugin):
self.stats = []
def load_limits(self, config):
"""Load the monitored list from the conf file."""
logger.debug("Monitor plugin configuration detected in the configuration file")
"""Load the monitored list from the config file, if it exists."""
self.glances_monitors = glancesMonitorList(config)
def update(self):

View File

@ -327,16 +327,16 @@ class GlancesPlugin(object):
return item_views[key][option]
def load_limits(self, config):
"""Load the limits from the configuration file."""
"""Load limits from the configuration file, if it exists."""
if (hasattr(config, 'has_section') and
config.has_section(self.plugin_name)):
for level, v in config.items(self.plugin_name):
# Read limits
limit = '_'.join([self.plugin_name, level])
try:
self._limits[limit] = config.get_option(self.plugin_name, level)
self._limits[limit] = config.get_float_value(self.plugin_name, level)
except ValueError:
self._limits[limit] = config.get_raw_option(self.plugin_name, level).split(",")
self._limits[limit] = config.get_value(self.plugin_name, level).split(",")
logger.debug("Load limit: {0} = {1}".format(limit, self._limits[limit]))
@property

View File

@ -379,7 +379,7 @@ class Plugin(GlancesPlugin):
msg = '{0:>6}'.format(_("PID"))
ret.append(self.curse_add_line(msg))
msg = ' {0:10}'.format(_("USER"))
ret.append(self.curse_add_line(msg))
ret.append(self.curse_add_line(msg, sort_style if process_sort_key == 'username' else 'DEFAULT'))
msg = '{0:>4}'.format(_("NI"))
ret.append(self.curse_add_line(msg))
msg = '{0:>2}'.format(_("S"))
@ -397,14 +397,13 @@ class Plugin(GlancesPlugin):
self.tag_proc_time = True
if glances_processes.is_tree_enabled():
ret.extend(self.get_process_tree_curses_data(self.sortstats(process_sort_key),
args,
first_level=True,
max_node_count=glances_processes.max_processes))
ret.extend(self.get_process_tree_curses_data(
self.sort_stats(process_sort_key), args, first_level=True,
max_node_count=glances_processes.max_processes))
else:
# Loop over processes (sorted by the sort key previously compute)
first = True
for p in self.sortstats(process_sort_key):
for p in self.sort_stats(process_sort_key):
ret.extend(self.get_process_curses_data(p, first, args))
# End of extended stats
first = False
@ -412,16 +411,12 @@ class Plugin(GlancesPlugin):
# Return the message with decoration
return ret
def sortstats(self, sortedby=None):
def sort_stats(self, sortedby=None):
"""Return the stats sorted by sortedby variable."""
if sortedby is None:
# No need to sort...
return self.stats
sortedreverse = True
if sortedby == 'name':
sortedreverse = False
tree = glances_processes.is_tree_enabled()
if sortedby == 'io_counters' and not tree:
@ -432,18 +427,18 @@ class Plugin(GlancesPlugin):
self.stats.sort(key=lambda process: process[sortedby][0] -
process[sortedby][2] + process[sortedby][1] -
process[sortedby][3],
reverse=sortedreverse)
reverse=glances_processes.sort_reverse)
except Exception:
self.stats.sort(key=operator.itemgetter('cpu_percent'),
reverse=sortedreverse)
reverse=glances_processes.sort_reverse)
else:
# Others sorts
if tree:
self.stats.set_sorting(sortedby, sortedreverse)
self.stats.set_sorting(sortedby, glances_processes.sort_reverse)
else:
try:
self.stats.sort(key=operator.itemgetter(sortedby),
reverse=sortedreverse)
reverse=glances_processes.sort_reverse)
except (KeyError, TypeError):
self.stats.sort(key=operator.itemgetter('name'),
reverse=False)

View File

@ -80,6 +80,9 @@ export stats to an InfluxDB server
.B \-\-export-statsd
export stats to a Statsd server
.TP
.B \-\-export-rabbitmq
export stats to a RabbitMQ server
.TP
.B \-s, \-\-server
run Glances in server mode
.TP
@ -202,6 +205,9 @@ Sort process by CPU times (TIME+)
View network I/O as combination
.TP
.B u
Sort processes by USER
.TP
.B U
View cumulative network I/O
.TP
.B w
@ -234,6 +240,9 @@ Monitor local machine and export stats to a CSV file (standalone mode):
Monitor local machine and export stats to a InfluxDB server with 5s refresh time (standalone mode):
.B $ glances -t 5 --export-influxdb
.PP
Monitor local machine and export stats to a RabbitMQ server with 5s refresh time (standalone mode):
.B $ glances -t 5 --export-rabbitmq
.PP
Start a Glances server (server mode):
.B $ glances -s
.PP

View File

@ -6,12 +6,12 @@ import sys
from setuptools import setup
is_chroot = os.stat('/').st_ino != 2
if sys.version_info < (2, 6) or (3, 0) <= sys.version_info < (3, 3):
print('Glances requires at least Python 2.6 or 3.3 to run.')
sys.exit(1)
def get_data_files():
data_files = [
('share/doc/glances', ['AUTHORS', 'COPYING', 'NEWS', 'README.rst',
@ -20,25 +20,8 @@ def get_data_files():
('share/man/man1', ['man/glances.1'])
]
if hasattr(sys, 'real_prefix'): # virtualenv
conf_path = os.path.join(sys.prefix, 'etc', 'glances')
elif os.name == 'posix' and (os.getuid() == 0 or is_chroot):
# Unix-like + root privileges/chroot environment
if 'bsd' in sys.platform:
conf_path = os.path.join(sys.prefix, 'etc', 'glances')
elif 'linux' in sys.platform:
conf_path = os.path.join('/etc', 'glances')
elif 'darwin' in sys.platform:
conf_path = os.path.join('/usr/local', 'etc', 'glances')
elif 'win32' in sys.platform: # windows
conf_path = os.path.join(os.environ.get('APPDATA'), 'glances')
else: # Unix-like + per-user install
conf_path = os.path.join('etc', 'glances')
data_files.append((conf_path, ['conf/glances.conf']))
for mo in glob.glob('i18n/*/LC_MESSAGES/*.mo'):
data_files.append(
(os.path.dirname(mo).replace('i18n/', 'share/locale/'), [mo]))
data_files.append((os.path.dirname(mo).replace('i18n/', 'share/locale/'), [mo]))
return data_files
@ -73,7 +56,7 @@ setup(
'BROWSER': ['zeroconf>=0.16', 'netifaces'],
'RAID': ['pymdstat'],
'DOCKER': ['docker-py'],
'EXPORT': ['influxdb>=1.0.0', 'statsd'],
'EXPORT': ['influxdb>=1.0.0', 'statsd', 'pika'],
'ACTION': ['pystache']
},
packages=['glances'],