mirror of
https://github.com/nicolargo/glances.git
synced 2024-09-21 09:37:20 +03:00
Merge branch 'develop' into refactor-web-ui
Conflicts: glances/plugins/glances_help.py
This commit is contained in:
commit
518aa7acfe
34
NEWS
34
NEWS
@ -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)
|
||||
|
12
README.rst
12
README.rst
@ -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
|
||||
|
@ -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
|
@ -177,3 +177,10 @@ db=glances
|
||||
host=localhost
|
||||
port=8125
|
||||
#prefix=glances
|
||||
|
||||
[rabbitmq]
|
||||
host=localhost
|
||||
port=5672
|
||||
user=guest
|
||||
password=guest
|
||||
queue=glances_queue
|
||||
|
@ -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 <<a class="reference external" href="mailto:nicolas@nicolargo.com">nicolas@nicolargo.com</a>></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 @server</span>
|
||||
</pre>
|
||||
<p>where <tt class="docutils literal">@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 @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://@server:61208
|
||||
</pre>
|
||||
<p>where <tt class="docutils literal">@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://@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://@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://@server:61208
|
||||
</tr>
|
||||
<tr><td> </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> </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> </td><td>disable left sidebar</td></tr>
|
||||
@ -303,9 +327,9 @@ http://@server:61208
|
||||
</tr>
|
||||
<tr><td> </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> </td><td>enable the history mode</td></tr>
|
||||
<tr><td> </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://@server:61208
|
||||
</tr>
|
||||
<tr><td> </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> </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> </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> </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> </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\<User>\Application Data
|
||||
<p>Since Windows Vista and newer versions:</p>
|
||||
<pre class="literal-block">
|
||||
C:\Users\<User>\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 & WARNING & ERROR &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> </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">"OK"</tt></div>
|
||||
<div class="line"><tt class="docutils literal">BLUE</tt> stat counter is <tt class="docutils literal">"CAREFUL"</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}} > /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}} > /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&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&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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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])
|
||||
|
@ -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'))
|
||||
|
@ -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:
|
||||
|
@ -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()
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
105
glances/exports/glances_rabbitmq.py
Normal file
105
glances/exports/glances_rabbitmq.py
Normal 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)
|
@ -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
|
||||
|
@ -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...
|
||||
|
@ -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"]
|
||||
|
@ -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())
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
23
setup.py
23
setup.py
@ -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'],
|
||||
|
Loading…
Reference in New Issue
Block a user