@@ -235,6 +237,7 @@ device with a web browser, just run the server with the @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.
The Glances web interface follows responsive web design principles.
Screenshot from Chrome on Android
@@ -308,10 +311,18 @@ http://@server:61208
Set the export path for graph history
---output-csv OUTPUT_CSV
+--export-csv CSV_FILE
export stats to a CSV file
+--export-influxdb
+
+
export stats to an InfluxDB server
+
+--export-statsd
+
+
export stats to a Statsd server
+
-c CLIENT, --client CLIENT
connect to a Glances server by IPv4/IPv6 address or
@@ -442,7 +453,7 @@ Filter is a regular expression pattern:
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:
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:
diff --git a/docs/glances-doc.rst b/docs/glances-doc.rst
index 60d7fe40..65377b34 100644
--- a/docs/glances-doc.rst
+++ b/docs/glances-doc.rst
@@ -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,15 +719,19 @@ 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:
- [load]
- critical=5.0
- critical_action=python /path/to/foo.py
+.. 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:
- [fs]
- warning=70
- warning_action=echo {{mnt_point}} {{used}}/{{size}} > /tmp/fs.alert
+.. code-block::
+
+ [fs]
+ 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)
diff --git a/docs/images/docker.png b/docs/images/docker.png
index e8115359..4e64168e 100644
Binary files a/docs/images/docker.png and b/docs/images/docker.png differ
diff --git a/docs/images/raid.png b/docs/images/raid.png
new file mode 100644
index 00000000..fc9bd12b
Binary files /dev/null and b/docs/images/raid.png differ
diff --git a/glances/__init__.py b/glances/__init__.py
index 0d29033a..e6374f29 100644
--- a/glances/__init__.py
+++ b/glances/__init__.py
@@ -20,7 +20,7 @@
"""Init the Glances software."""
__appname__ = 'glances'
-__version__ = '2.3_RC1'
+__version__ = '2.4beta'
__author__ = 'Nicolas Hennion '
__license__ = 'LGPL'
diff --git a/glances/core/glances_actions.py b/glances/core/glances_actions.py
index ee29fd61..1a762b70 100644
--- a/glances/core/glances_actions.py
+++ b/glances/core/glances_actions.py
@@ -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})
diff --git a/glances/core/glances_logs.py b/glances/core/glances_logs.py
index 7d6a10b6..f2f9a3d4 100644
--- a/glances/core/glances_logs.py
+++ b/glances/core/glances_logs.py
@@ -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
diff --git a/glances/core/glances_main.py b/glances/core/glances_main.py
index d8627380..fbc17417 100644
--- a/glances/core/glances_main.py
+++ b/glances/core/glances_main.py
@@ -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\
diff --git a/glances/outputs/bottle/base.tpl b/glances/outputs/bottle/base.tpl
new file mode 100644
index 00000000..30d69690
--- /dev/null
+++ b/glances/outputs/bottle/base.tpl
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+ Glances
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/glances/outputs/glances_bottle.py b/glances/outputs/glances_bottle.py
index d757ae6e..0c20c306 100644
--- a/glances/outputs/glances_bottle.py
+++ b/glances/outputs/glances_bottle.py
@@ -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'
diff --git a/glances/outputs/static/css/style.css b/glances/outputs/static/css/style.css
index 2d852eb8..13c3ab2c 100644
--- a/glances/outputs/static/css/style.css
+++ b/glances/outputs/static/css/style.css
@@ -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;
+}
diff --git a/glances/plugins/glances_docker.py b/glances/plugins/glances_docker.py
index da96235e..0aba990a 100644
--- a/glances/plugins/glances_docker.py
+++ b/glances/plugins/glances_docker.py
@@ -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,13 +170,17 @@ class Plugin(GlancesPlugin):
Output: a dict {'total': 1.49, 'user': 0.65, 'system': 0.84}"""
ret = {}
# Read the stats
- 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))
+ 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()
+ ticks = self.get_user_ticks()
if isinstance(ret["system"], numbers.Number) and isinstance(ret["user"], numbers.Number):
ret["total"] = ret["system"] + ret["user"]
for k in ret.keys():
@@ -183,11 +194,15 @@ class Plugin(GlancesPlugin):
Output: a dict {'rss': 1015808, 'cache': 356352}"""
ret = {}
# Read the stats
- 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))
+ 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
diff --git a/glances/plugins/glances_fs.py b/glances/plugins/glances_fs.py
index e4dfbcff..57719ced 100644
--- a/glances/plugins/glances_fs.py
+++ b/glances/plugins/glances_fs.py
@@ -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.
diff --git a/glances/plugins/glances_plugin.py b/glances/plugins/glances_plugin.py
index 9a69a50f..7ff575f6 100644
--- a/glances/plugins/glances_plugin.py
+++ b/glances/plugins/glances_plugin.py
@@ -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 = {}
+ 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)
diff --git a/man/glances.1 b/man/glances.1
index 0b47497a..3a717659 100644
--- a/man/glances.1
+++ b/man/glances.1
@@ -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
diff --git a/requirements.txt b/requirements.txt
index 52546a76..7a795604 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1 +1 @@
-psutil==2.1.3
+psutil==2.2.0
diff --git a/setup.py b/setup.py
index e46c3484..f598e2bf 100755
--- a/setup.py
+++ b/setup.py
@@ -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',