Merge from develop branch

This commit is contained in:
Nicolargo 2015-01-31 16:52:58 +01:00
commit 6583a875e8
21 changed files with 292 additions and 67 deletions

View File

@ -21,6 +21,9 @@ https://github.com/jrenner
Maxime Desbrus (aka) desbma
https://github.com/desbma
Nicolas Hart (aka) NclsHart for the UI design
https://github.com/nclsHart
=========
Packagers
=========

View File

@ -3,7 +3,8 @@ include COPYING
include NEWS
include README.rst
include conf/glances.conf
include glances/outputs/static/html/*.html
include glances/outputs/bottle/*.tpl
include glances/outputs/static/*.ico
include glances/outputs/static/css/*.css
include glances/outputs/static/js/*.js
include glances/outputs/static/js/*.js.map

9
NEWS
View File

@ -2,6 +2,11 @@
Glances Version 2.x
==============================================================================
Version 2.4
===========
...
Version 2.3
===========
@ -23,6 +28,10 @@ Bugs corrected:
* R/W error with the glances.log file (issue #474)
Other enhancement:
* Alert < 3 seconds are no longer displayed
Version 2.2.1
=============

View File

@ -13,8 +13,6 @@ Glances - An eye on your system
.. image:: https://pypip.in/d/Glances/badge.png
:target: https://pypi.python.org/pypi/Glances/
:alt: Downloads
.. 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
Follow Glances on Twitter: `@nicolargo`_ or `@glances_system`_
@ -233,6 +231,16 @@ Gateway to other services
Glances can export stats to: ``CSV`` file, ``InfluxDB`` and ``StatsD`` server.
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:
.. 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
Author
======
@ -249,3 +257,4 @@ LGPL. See ``COPYING`` for more details.
.. _@glances_system: https://twitter.com/glances_system
.. _glances-doc: https://github.com/nicolargo/glances/blob/master/docs/glances-doc.rst
.. _forum: https://groups.google.com/forum/?hl=en#!forum/glances-users
.. _Wiki: https://github.com/nicolargo/glances/wiki/How-to-contribute-to-Glances-%3F

View File

@ -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.2.1.</p>
<p>Copyright © 2012-2014 Nicolas Hennion &lt;<a class="reference external" href="mailto:nicolas&#64;nicolargo.com">nicolas&#64;nicolargo.com</a>&gt;</p>
<p>December 2014</p>
<p>This manual describes <em>Glances</em> version 2.3.</p>
<p>Copyright © 2011-2015 Nicolas Hennion &lt;<a class="reference external" href="mailto:nicolas&#64;nicolargo.com">nicolas&#64;nicolargo.com</a>&gt;</p>
<p>January 2015</p>
<div class="contents topic" id="table-of-contents">
<p class="topic-title first">Table of Contents</p>
<ul class="simple">
@ -156,11 +156,13 @@ td.option-group {
<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>
</ul>
</li>
<li><a class="reference internal" href="#other-outputs" id="id28">Other Outputs</a></li>
<li><a class="reference internal" href="#apis-documentations" id="id29">APIs Documentations</a></li>
<li><a class="reference internal" href="#support" id="id30">Support</a></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>
</ul>
</div>
<div class="section" id="introduction">
@ -235,6 +237,7 @@ device with a web browser, just run the server with the <tt class="docutils lite
http://&#64;server:61208
</pre>
<p>where <tt class="docutils literal">&#64;server</tt> is the IP address or hostname of the server.</p>
<p>To change the refresh rate of the page, just add the period in seconds between refreshes at the end of the URL, ie. to refresh every 10s, use <tt class="docutils literal"><span class="pre">http://&#64;server:61208/10</span></tt>.</p>
<p>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" />
@ -308,10 +311,18 @@ http://&#64;server:61208
</tr>
<tr><td>&nbsp;</td><td>Set the export path for graph history</td></tr>
<tr><td class="option-group" colspan="2">
<kbd><span class="option">--output-csv <var>OUTPUT_CSV</var></span></kbd></td>
<kbd><span class="option">--export-csv <var>CSV_FILE</var></span></kbd></td>
</tr>
<tr><td>&nbsp;</td><td>export stats to a CSV file</td></tr>
<tr><td class="option-group" colspan="2">
<kbd><span class="option">--export-influxdb</span></kbd></td>
</tr>
<tr><td>&nbsp;</td><td>export stats to an InfluxDB server</td></tr>
<tr><td class="option-group" colspan="2">
<kbd><span class="option">--export-statsd</span></kbd></td>
</tr>
<tr><td>&nbsp;</td><td>export stats to a Statsd server</td></tr>
<tr><td class="option-group" colspan="2">
<kbd><span class="option">-c <var>CLIENT</var></span>, <span class="option">--client <var>CLIENT</var></span></kbd></td>
</tr>
<tr><td>&nbsp;</td><td>connect to a Glances server by IPv4/IPv6 address or
@ -442,7 +453,7 @@ Filter is a regular expression pattern:</p>
<dt><tt class="docutils literal">F</tt></dt>
<dd>Switch between FS used and free space</dd>
<dt><tt class="docutils literal">g</tt></dt>
<dd>Generate hraphs for current history</dd>
<dd>Generate graphs for current history</dd>
<dt><tt class="docutils literal">h</tt></dt>
<dd>Show/hide the help screen</dd>
<dt><tt class="docutils literal">i</tt></dt>
@ -532,6 +543,28 @@ 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>Each plugin and export module can have a section.</p>
<p>Example for the CPU plugin:</p>
<pre class="code literal-block">
[cpu]
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
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>
<pre class="code literal-block">
steal_log=True
</pre>
</div>
<div class="section" id="logs-and-debug-mode">
<h1><a class="toc-backref" href="#id14">Logs and debug mode</a></h1>
@ -550,6 +583,7 @@ can ben logged using the -d option on the command line.</p>
</tr>
</tbody>
</table>
<p>If glances.log 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>
@ -667,6 +701,8 @@ adapted dynamically.</p>
</div>
<p><em>Note</em>: limit values can be overwritten in the configuration file under
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" />
</div>
<div class="section" id="sensors">
<h2><a class="toc-backref" href="#id24">Sensors</a></h2>
@ -833,30 +869,86 @@ progress</li>
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>
<img alt="images/docker.png" src="images/docker.png" />
</div>
<div class="section" id="other-outputs">
<h1><a class="toc-backref" href="#id28">Other Outputs</a></h1>
<div class="section" id="actions">
<h2><a class="toc-backref" href="#id29">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>
<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>
<pre class="code literal-block">
[fs]
warning=70
warning_action=echo {{mnt_point}} {{used}}/{{size}} &gt; /tmp/fs.alert
</pre>
<p><em>Note</em>: You can use all the stats for the current plugin (see <a class="reference external" href="https://github.com/nicolargo/glances/wiki/The-Glances-2.x-API-How-to">https://github.com/nicolargo/glances/wiki/The-Glances-2.x-API-How-to</a> for the stats list)</p>
</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>
<p>It is possible to export statistics to CSV file.</p>
<pre class="code console literal-block">
<span class="generic prompt">$</span> glances --output-csv /tmp/glances.csv
<span class="generic prompt">$</span> glances --export-csv /tmp/glances.csv
</pre>
<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>
<pre class="code literal-block">
[influxdb]
host=localhost
port=8086
user=root
password=root
db=glances
</pre>
<p>and run Glances with:</p>
<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>
<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>and run Glances with:</p>
<pre class="code console literal-block">
<span class="generic prompt">$</span> glances --export-statsd
</pre>
<p>Glances will generate stats as:</p>
<pre class="code literal-block">
'glances.cpu.user': 12.5,
'glances.cpu.total': 14.9,
'glances.load.cpucore': 4,
'glances.load.min1': 0.19,
...
</pre>
<p>CSV files have two lines per stats:</p>
<ul class="simple">
<li>Stats description</li>
<li>Stats (comma separated)</li>
</ul>
</div>
<div class="section" id="apis-documentations">
<h1><a class="toc-backref" href="#id29">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/">RESTFULL-JSON</a> API which and can be used by another client software.</p>
<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>
<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>RESTFULL-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>
<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="#id30">Support</a></h1>
<h1><a class="toc-backref" href="#id32">Support</a></h1>
<p>To post a question about Glances use case, please post it to the offical Q&amp;A <a class="reference external" href="https://groups.google.com/forum/?hl=en#!forum/glances-users">forum</a>.</p>
<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>

View File

@ -514,6 +514,10 @@ Alerts are set for used disk space.
*Note*: limit values can be overwritten in the configuration file under
the ``[filesystem]`` section.
If a RAID controller is detected on you system, its status will be displayed:
.. image:: images/raid.png
Sensors
-------
@ -715,12 +719,16 @@ 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:
.. code-block::
[load]
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:
.. code-block::
[fs]
warning=70
warning_action=echo {{mnt_point}} {{used}}/{{size}} > /tmp/fs.alert

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 68 KiB

BIN
docs/images/raid.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -20,7 +20,7 @@
"""Init the Glances software."""
__appname__ = 'glances'
__version__ = '2.3_RC1'
__version__ = '2.4beta'
__author__ = 'Nicolas Hennion <nicolas@nicolargo.com>'
__license__ = 'LGPL'

View File

@ -70,6 +70,11 @@ class GlancesActions(object):
# Action already executed => Exit
return False
logger.debug("Run action {0} for {1} ({2}) with stats {3}".format(commands,
stat_name,
criticity,
mustache_dict))
# Ran all actions in background
for cmd in commands:
# Replace {{arg}} by the dict one (Thk to {Mustache})

View File

@ -100,12 +100,15 @@ class GlancesLogs(object):
return process_auto_by
def add(self, item_state, item_type, item_value, proc_list=[], proc_desc=""):
def add(self, item_state, item_type, item_value,
proc_list=[], proc_desc="",
peak_time=3):
"""Add a new item to the logs list.
If 'item' is a 'new one', add the new item at the beginning of the logs
list.
If 'item' is not a 'new one', update the existing item.
If event < peak_time the the alert is not setoff
"""
# Add or update the log
item_index = self.__itemexist__(item_type)
@ -147,9 +150,13 @@ class GlancesLogs(object):
# Reset the automatic process sort key
self.reset_process_sort()
# Close the item
self.logs_list[item_index][1] = time.mktime(
datetime.now().timetuple())
endtime = time.mktime(datetime.now().timetuple())
if endtime - self.logs_list[item_index][0] > peak_time:
# If event is > peak_time seconds
self.logs_list[item_index][1] = endtime
else:
# If event <= peak_time seconds, ignore
self.logs_list.remove(self.logs_list[item_index])
else:
# Update the item
# State

View File

@ -66,7 +66,7 @@ Monitor local machine and export stats to a CSV file (standalone mode):\n\
$ glances --export-csv\n\
\n\
Monitor local machine and export stats to a InfluxDB server with 5s refresh time (standalone mode):\n\
$ glances -t 5 --export-influxdb -t 5\n\
$ glances -t 5 --export-influxdb\n\
\n\
Start a Glances server (server mode):\n\
$ glances -s\n\

View File

@ -0,0 +1,61 @@
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="refresh" content="{{refresh_time}}">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Glances</title>
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<link rel="stylesheet" type="text/css" href="normalize.css" />
<link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
<link rel="stylesheet" type="text/css" href="style.css" />
<script src="modernizr.custom.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-sm-12">
<div class="pull-left">
% include('plugin_text', plugin_name="system", stats=stats['system'])
</div>
<div class="pull-right">
% include('plugin_text', plugin_name="uptime", stats=stats['uptime'])
</div>
</div>
</div>
<div class="row">
<div class="col-sm-3">
% include('plugin_table', plugin_name="cpu", stats=stats['cpu'])
</div>
<div class="col-sm-3 col-lg-2 col-lg-offset-1">
% include('plugin_table', plugin_name="load", stats=stats['load'])
</div>
<div class="col-sm-3 col-lg-3">
% include('plugin_table', plugin_name="mem", stats=stats['mem'])
</div>
<div class="col-sm-3 col-lg-2 col-lg-offset-1">
% include('plugin_table', plugin_name="memswap", stats=stats['memswap'])
</div>
</div>
<div class="row">
<div class="col-sm-3">
% include('plugin_table', plugin_name="network", stats=stats['network'])
% include('plugin_table', plugin_name="diskio", stats=stats['diskio'])
% include('plugin_table', plugin_name="fs", stats=stats['fs'])
% include('plugin_table', plugin_name="sensors", stats=stats['sensors'])
</div>
<div class="col-sm-9">
% include('plugin_table', plugin_name="alert", stats=stats['alert'])
% include('plugin_text', plugin_name="processcount", stats=stats['processcount'])
% include('plugin_table', plugin_name="docker", stats=stats['docker'])
<div class="row">
<div class="col-sm-9">
% include('plugin_table', plugin_name="monitor", stats=stats['monitor'])
</div>
</div>
% include('plugin_table', plugin_name="processlist", stats=stats['processlist'])
</div>
</div>
</div>
</body>
</html>

View File

@ -362,16 +362,6 @@ class GlancesBottle(object):
else:
return pdict
# def display(self, stats, refresh_time=None):
# """Display stats on the web page.
# stats: Stats database to display
# """
# path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "bottle", "index.html")
# f = open(path)
# return f.read()
class EnableCors(object):
name = 'enable_cors'

View File

@ -167,3 +167,26 @@ source : https://github.com/lukehaas/css-loaders
box-shadow: 0 2.5em 0 0 #56CA69;
}
}
#cpu table tr td:nth-child(3),
#mem table tr td:nth-child(3),
#monitor table tr td:nth-child(3) {
text-align: left;
padding-left: 20px;
}
#processlist table tr td {
text-align: right;
}
#processlist table tr td,
#docker table tr td {
padding: 0px 5px 0px 5px;
white-space: nowrap;
}
#processlist table tr td:nth-child(6),
#processlist table tr td:nth-child(12) {
text-align: left;
}
#docker table tr td:nth-child(2),
#docker table tr td:nth-child(6) {
text-align: left;
}

View File

@ -76,17 +76,20 @@ class Plugin(GlancesPlugin):
# Connexion error (Docker not detected)
# Let this message in debug mode
logger.debug("Can't connect to the Docker server (%s)" % e)
ret = None
return None
except docker.errors.APIError as e:
if version is None:
# API error (Version mismatch ?)
logger.debug("Docker API error (%s)" % e)
# Try the connection with the server version
import re
version = re.search('server\:\ (.*)\)\"\)', str(e))
version = re.search('server\:\ (.*)\)\".*\)', str(e))
if version:
logger.debug("Try connection with Docker API version %s" % version.group(1))
ret = self.connect(version=version.group(1))
else:
logger.debug("Can not retreive Docker server version")
ret = None
else:
# API error
logger.error("Docker API error (%s)" % e)
@ -97,6 +100,10 @@ class Plugin(GlancesPlugin):
logger.error("Can't connect to the Docker server (%s)" % e)
ret = None
# Log an info if Docker plugin is disabled
if ret is None:
logger.debug("Docker plugin is disable because an error has been detected")
return ret
def reset(self):
@ -163,11 +170,15 @@ class Plugin(GlancesPlugin):
Output: a dict {'total': 1.49, 'user': 0.65, 'system': 0.84}"""
ret = {}
# Read the stats
try:
with open('/sys/fs/cgroup/cpuacct/docker/' + id + '/cpuacct.stat', 'r') as f:
for line in f:
m = re.search(r"(system|user)\s+(\d+)", line)
if m:
ret[m.group(1)] = int(m.group(2))
except IOError as e:
logger.error("Can not grab container CPU stat ({0})".format(e))
return ret
# Get the user ticks
ticks = self.get_user_ticks()
if isinstance(ret["system"], numbers.Number) and isinstance(ret["user"], numbers.Number):
@ -183,11 +194,15 @@ class Plugin(GlancesPlugin):
Output: a dict {'rss': 1015808, 'cache': 356352}"""
ret = {}
# Read the stats
try:
with open('/sys/fs/cgroup/memory/docker/' + id + '/memory.stat', 'r') as f:
for line in f:
m = re.search(r"(rss|cache)\s+(\d+)", line)
if m:
ret[m.group(1)] = int(m.group(2))
except IOError as e:
logger.error("Can not grab container MEM stat ({0})".format(e))
return ret
# Return the stats
return ret

View File

@ -24,6 +24,7 @@ import operator
import psutil
from glances.plugins.glances_plugin import GlancesPlugin
from glances.core.glances_logging import logger
# SNMP OID
# The snmpd.conf needs to be edited.

View File

@ -413,14 +413,15 @@ class GlancesPlugin(object):
if type(self.stats) is list:
# If the stats are stored in a list of dict (fs plugin for exemple)
# Return the dict for the current header
try:
mustache_dict = (
item for item in self.stats if item[self.get_key()] == header).next()
except StopIteration:
mustache_dict = {}
for item in self.stats:
if item[self.get_key()] == header:
mustache_dict = item
break
else:
# Use the stats dict
mustache_dict = self.stats
# Run the action
self.actions.run(
stat_name, ret.lower(), command, mustache_dict=mustache_dict)

View File

@ -1,4 +1,4 @@
.TH glances 1 "December, 2014" "version 2.2.1" "USER COMMANDS"
.TH glances 1 "January, 2015" "version 2.3" "USER COMMANDS"
.SH NAME
glances \- A cross-platform curses-based system monitoring tool
.SH SYNOPSIS

View File

@ -1 +1 @@
psutil==2.1.3
psutil==2.2.0

View File

@ -52,7 +52,7 @@ def get_requires():
setup(
name='Glances',
version='2.3RC1',
version='2.4beta',
description="A cross-platform curses-based monitoring tool",
long_description=open('README.rst').read(),
author='Nicolas Hennion',