diff --git a/AUTHORS b/AUTHORS index 528226a5..30859b6e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -5,25 +5,34 @@ Developers Nicolas Hennion (aka) Nicolargo http://blog.nicolargo.com https://twitter.com/nicolargo +https://github.com/nicolargo nicolashennion@gmail.com PGP Fingerprint: 835F C447 3BCD 60E9 9200 2778 ABA4 D1AB 9731 6A3C PGP Public key: gpg --keyserver pgp.mit.edu --recv-keys 0xaba4d1ab97316a3c -Alessio Sergi (aka) al3hex +Alessio Sergi (aka) Al3hex https://twitter.com/al3hex +https://github.com/asergi Brandon Philips (aka) Philips http://ifup.org/ +https://github.com/philips Jon Renner (aka) Jrenner https://github.com/jrenner -Maxime Desbrus (aka) desbma +Maxime Desbrus (aka) Desbma https://github.com/desbma -Nicolas Hart (aka) NclsHart for the UI design +Nicolas Hart (aka) NclsHart (for the Web user interface) https://github.com/nclsHart +Sylvain Mouquet (aka) SylvainMouquet (for the Web user interface) +http://github.com/sylvainmouquet + +Floran Brutel (aka) notFloran (for the Web user interface) +https://github.com/notFloran + ========= Packagers ========= diff --git a/MANIFEST.in b/MANIFEST.in index 98cb6021..37000d2a 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -3,11 +3,16 @@ include COPYING include NEWS include README.rst include conf/glances.conf -include glances/outputs/bottle/*.tpl +include glances/outputs/static/html/*.html +include glances/outputs/static/html/components/*.html +include glances/outputs/static/html/plugins/*.html include glances/outputs/static/*.ico include glances/outputs/static/css/*.css include glances/outputs/static/js/*.js +include glances/outputs/static/js/*.js.map +include glances/outputs/static/js/vendors/*.js +include glances/outputs/static/js/vendors/*.js.map +include glances/outputs/static/images/*.png include man/glances.1 recursive-include docs images/*.png glances-doc.html recursive-include glances *.py -recursive-include i18n *.mo diff --git a/NEWS b/NEWS index 4b4419ef..f31ad161 100644 --- a/NEWS +++ b/NEWS @@ -2,10 +2,47 @@ Glances Version 2.x ============================================================================== +Version 2.4 +=========== + +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. (issue #541) + * The default key bindings have been changed to: + - 'u': sort processes by USER + - 'U': show cumulative network I/O + * No more translations + +Enhancements and new features: + + * The Web user interface is now based on AngularJS (issue #473, #508, #468) + * 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) + * Increase alert minimal delay to 6 seconds (issue #522) + * If the Curses application raises an exception, restore the terminal correctly (issue #537) + +Bugs corrected: + + * 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) + * Glances display of time trims the hours showing only minutes and seconds (issue #543) + * Process list header not decorating when sorting by command (issue #551) + 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) @@ -37,7 +74,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) @@ -142,7 +179,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. @@ -348,7 +385,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) diff --git a/README.rst b/README.rst index afbe90f0..915001b0 100644 --- a/README.rst +++ b/README.rst @@ -6,11 +6,11 @@ Glances - An eye on your system :target: https://flattr.com/thing/484466/nicolargoglances-on-GitHub .. image:: https://scrutinizer-ci.com/g/nicolargo/glances/badges/quality-score.png?b=master :target: https://scrutinizer-ci.com/g/nicolargo/glances/ -.. image:: https://travis-ci.org/nicolargo/glances.png?branch=master +.. image:: https://travis-ci.org/nicolargo/glances.svg?branch=master :target: https://travis-ci.org/nicolargo/glances -.. image:: https://badge.fury.io/py/Glances.png +.. image:: https://badge.fury.io/py/Glances.svg :target: http://badge.fury.io/py/Glances -.. image:: https://pypip.in/d/Glances/badge.png +.. image:: https://pypip.in/d/Glances/badge.svg :target: https://pypi.python.org/pypi/Glances/ :alt: Downloads @@ -20,18 +20,16 @@ Follow Glances on Twitter: `@nicolargo`_ or `@glances_system`_ **Glances** is a cross-platform curses-based system monitoring tool written in Python. -It uses the `psutil`_ library to get information from your system. - .. image:: https://raw.github.com/nicolargo/glances/master/docs/images/screenshot-wide.png Requirements ============ -- ``python >= 2.6`` (tested with version 2.6, 2.7, 3.3, 3.4) +- ``python >= 2.6`` or ``>= 3.3`` (tested with version 2.6, 2.7, 3.3, 3.4) - ``psutil >= 2.0.0`` - ``setuptools`` -Optionals dependencies: +Optional dependencies: - ``bottle`` (for Web server mode) - ``py3sensors`` (for hardware monitoring support) [Linux-only] @@ -39,11 +37,14 @@ Optionals dependencies: - ``batinfo`` (for battery monitoring support) [Linux-only] - ``pymdstat`` (for RAID support) [Linux-only] - ``pysnmp`` (for SNMP support) -- ``zeroconf`` and ``netifaces`` (for the auto discoverer mode) +- ``zeroconf`` (for the autodiscover mode) +- ``netifaces`` (for the IP plugin) - ``influxdb`` (for the InfluxDB export module) - ``statsd`` (for the StatsD export module) - ``pystache`` (for the action script feature) - ``docker-py`` (for the Docker monitoring support) [Linux-only] +- ``matplotlib`` (for graphical/chart support) +- ``pika`` (for the RabbitMQ/ActiveMQ export module) Installation ============ @@ -51,7 +52,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 @@ -76,29 +78,30 @@ To install, simply use ``pip``: .. code-block:: console - pip install Glances + pip install glances *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 - pip install bottle batinfo https://bitbucket.org/gleb_zhulik/py3sensors/get/tip.tar.gz zeroconf netifaces pymdstat influxdb statsd pystache + pip install bottle batinfo https://bitbucket.org/gleb_zhulik/py3sensors/get/tip.tar.gz zeroconf netifaces pymdstat influxdb statsd pystache pika To upgrade Glances to the latest version: .. code-block:: console - pip install --upgrade Glances + pip install --upgrade glances If you need to install Glances in a specific user location, use: .. code-block:: console export PYTHONUSERBASE=~/mylocalpath - pip install --user Glances + pip install --user glances GNU/Linux --------- @@ -106,11 +109,11 @@ GNU/Linux At the moment, packages exist for the following GNU/Linux distributions: - Arch Linux -- Debian (Testing/Sid) +- Debian - Fedora/CentOS/RHEL - Gentoo - Slackware (SlackBuild) -- Ubuntu (13.04+) +- Ubuntu - Void Linux So you should be able to install it using your favorite package manager. @@ -142,7 +145,7 @@ Homebrew .. code-block:: console $ brew install python - $ pip install Glances + $ pip install glances MacPorts ```````` @@ -154,10 +157,15 @@ MacPorts 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 Python for Windows (Python 2.7.9+ ship with Pip): http://www.python.org/getit/ +- Install the `psutil`_ library (latest binary version): https://pypi.python.org/pypi/psutil - Install the colorconsole library: https://pypi.python.org/pypi/colorconsole -- Install Glances Download Glances from here: http://nicolargo.github.io/glances/ +- Install optionnals dependencies (see list bellow) +- Install Glances using pip + +.. code-block:: console + + $ pip install glances Source ------ @@ -229,14 +237,14 @@ If you have any question (after RTFM!), please post it on the official Q&A `foru Gateway to other services ========================= -Glances can export stats to: ``CSV`` file, ``InfluxDB`` and ``StatsD`` server. +Glances can export stats to: ``CSV`` file, ``InfluxDB``, ``StatsD`` and ``RabbitMQ`` 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: +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 diff --git a/conf/glances-grafana.json b/conf/glances-grafana.json new file mode 100644 index 00000000..89152238 --- /dev/null +++ b/conf/glances-grafana.json @@ -0,0 +1,1140 @@ +{ + "id": null, + "title": "Glances", + "originalTitle": "Glances", + "tags": [], + "style": "dark", + "timezone": "browser", + "editable": true, + "hideControls": false, + "sharedCrosshair": false, + "rows": [ + { + "title": "test", + "height": "250px", + "editable": true, + "collapse": false, + "panels": [ + { + "title": "Core", + "error": false, + "span": 1, + "editable": true, + "type": "singlestat", + "id": 5, + "links": [], + "maxDataPoints": 100, + "interval": null, + "targets": [ + { + "function": "mean", + "column": "cpucore", + "series": "load", + "query": "select mean(cpucore) from \"load\" where $timeFilter group by time($interval) order asc" + } + ], + "cacheTimeout": null, + "format": "none", + "prefix": "", + "postfix": "", + "nullText": null, + "valueMaps": [ + { + "value": "null", + "op": "=", + "text": "N/A" + } + ], + "nullPointMode": "connected", + "valueName": "avg", + "prefixFontSize": "50%", + "valueFontSize": "80%", + "postfixFontSize": "50%", + "thresholds": "", + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "sparkline": { + "show": false, + "full": false, + "lineColor": "rgb(31, 120, 193)", + "fillColor": "rgba(31, 118, 189, 0.18)" + }, + "datasource": "glances" + }, + { + "id": 4, + "span": 10, + "type": "graph", + "x-axis": true, + "y-axis": true, + "scale": 1, + "y_formats": [ + "short", + "short" + ], + "grid": { + "max": null, + "min": null, + "leftMax": null, + "rightMax": null, + "leftMin": null, + "rightMin": null, + "threshold1": null, + "threshold2": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2Color": "rgba(234, 112, 112, 0.22)", + "thresholdLine": false + }, + "resolution": 100, + "lines": true, + "fill": 1, + "linewidth": 2, + "points": false, + "pointradius": 5, + "bars": false, + "stack": true, + "spyable": true, + "options": false, + "legend": { + "show": true, + "values": true, + "min": true, + "max": true, + "current": false, + "total": false, + "avg": true, + "rightSide": false, + "alignAsTable": false + }, + "interactive": true, + "legend_counts": true, + "timezone": "browser", + "percentage": false, + "nullPointMode": "connected", + "steppedLine": false, + "tooltip": { + "value_type": "cumulative", + "query_as_alias": true, + "shared": false + }, + "targets": [ + { + "target": "randomWalk('random walk')", + "function": "mean", + "column": "min1", + "series": "load", + "query": "select mean(min1) from \"load\" where $timeFilter group by time($interval) fill(null) order asc", + "alias": "1min", + "fill": "null" + }, + { + "target": "", + "function": "mean", + "column": "min5", + "series": "load", + "query": "select mean(min5) from \"load\" where $timeFilter group by time($interval) fill(null) order asc", + "alias": "5mins", + "fill": "null" + }, + { + "target": "", + "function": "mean", + "column": "min15", + "series": "load", + "query": "select mean(min15) from \"load\" where $timeFilter group by time($interval) fill(null) order asc", + "fill": "null", + "alias": "15mins" + } + ], + "aliasColors": {}, + "aliasYAxis": {}, + "title": "Load", + "datasource": "glances", + "renderer": "flot", + "annotate": { + "enable": false + }, + "seriesOverrides": [], + "links": [] + }, + { + "title": "Processes", + "error": false, + "span": 1, + "editable": true, + "type": "singlestat", + "id": 18, + "links": [], + "maxDataPoints": 100, + "interval": null, + "targets": [ + { + "function": "mean", + "column": "total", + "series": "processcount", + "query": "select mean(total) from \"processcount\" where $timeFilter group by time($interval) order asc" + } + ], + "cacheTimeout": null, + "format": "none", + "prefix": "", + "postfix": "", + "nullText": null, + "valueMaps": [ + { + "value": "null", + "op": "=", + "text": "N/A" + } + ], + "nullPointMode": "connected", + "valueName": "avg", + "prefixFontSize": "50%", + "valueFontSize": "80%", + "postfixFontSize": "50%", + "thresholds": "", + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "sparkline": { + "show": true, + "full": false, + "lineColor": "rgb(31, 120, 193)", + "fillColor": "rgba(31, 118, 189, 0.18)" + } + } + ] + }, + { + "title": "New row", + "height": "250px", + "editable": true, + "collapse": false, + "panels": [ + { + "title": "CPU (%)", + "error": false, + "span": 6, + "editable": true, + "type": "graph", + "id": 6, + "datasource": "glances", + "renderer": "flot", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "percent", + "short" + ], + "grid": { + "leftMax": null, + "rightMax": null, + "leftMin": null, + "rightMin": null, + "threshold1": null, + "threshold2": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "lines": true, + "fill": 0, + "linewidth": 1, + "points": false, + "pointradius": 5, + "bars": false, + "stack": false, + "percentage": false, + "legend": { + "show": true, + "values": false, + "min": true, + "max": true, + "current": false, + "total": false, + "avg": true, + "rightSide": false + }, + "nullPointMode": "connected", + "steppedLine": false, + "tooltip": { + "value_type": "cumulative", + "shared": false + }, + "targets": [ + { + "function": "mean", + "column": "user", + "series": "cpu", + "query": "select mean(user) from \"cpu\" where $timeFilter group by time($interval) fill(null) order asc", + "alias": "User", + "fill": "null" + }, + { + "target": "", + "function": "mean", + "column": "system", + "series": "cpu", + "query": "select mean(system) from \"cpu\" where $timeFilter group by time($interval) fill(null) order asc", + "alias": "System", + "fill": "null" + }, + { + "target": "", + "function": "mean", + "column": "iowait", + "series": "cpu", + "query": "select mean(iowait) from \"cpu\" where $timeFilter group by time($interval) fill(null) order asc", + "alias": "IoWait", + "fill": "null" + } + ], + "aliasColors": {}, + "seriesOverrides": [], + "links": [] + }, + { + "title": "MEM", + "error": false, + "span": 6, + "editable": true, + "type": "graph", + "id": 7, + "datasource": "glances", + "renderer": "flot", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "bytes", + "short" + ], + "grid": { + "leftMax": null, + "rightMax": null, + "leftMin": null, + "rightMin": null, + "threshold1": null, + "threshold2": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "lines": true, + "fill": 0, + "linewidth": 1, + "points": false, + "pointradius": 5, + "bars": false, + "stack": false, + "percentage": false, + "legend": { + "show": true, + "values": false, + "min": false, + "max": false, + "current": false, + "total": false, + "avg": false + }, + "nullPointMode": "connected", + "steppedLine": false, + "tooltip": { + "value_type": "cumulative", + "shared": false + }, + "targets": [ + { + "function": "mean", + "column": "used", + "series": "mem", + "query": "select mean(used) from \"mem\" where $timeFilter group by time($interval) order asc", + "alias": "Used" + }, + { + "target": "", + "function": "mean", + "column": "total", + "series": "mem", + "query": "select mean(total) from \"mem\" where $timeFilter group by time($interval) order asc", + "alias": "Max" + } + ], + "aliasColors": {}, + "seriesOverrides": [], + "links": [] + } + ] + }, + { + "title": "New row", + "height": "250px", + "editable": true, + "collapse": false, + "panels": [ + { + "title": "Net (Enp0s25)", + "error": false, + "span": 6, + "editable": true, + "type": "graph", + "id": 9, + "datasource": "glances", + "renderer": "flot", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "bps", + "short" + ], + "grid": { + "leftMax": null, + "rightMax": null, + "leftMin": null, + "rightMin": null, + "threshold1": null, + "threshold2": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "lines": true, + "fill": 3, + "linewidth": 1, + "points": false, + "pointradius": 5, + "bars": false, + "stack": false, + "percentage": false, + "legend": { + "show": true, + "values": false, + "min": false, + "max": false, + "current": false, + "total": false, + "avg": false + }, + "nullPointMode": "connected", + "steppedLine": false, + "tooltip": { + "value_type": "cumulative", + "shared": false + }, + "targets": [ + { + "function": "mean", + "column": "enp0s25.rx", + "series": "network", + "query": "select mean(enp0s25.rx) from \"network\" where $timeFilter group by time($interval) fill(null) order asc", + "alias": "Rx", + "interval": "", + "fill": "null" + }, + { + "target": "", + "function": "mean", + "column": "enp0s25.tx*-1", + "series": "network", + "query": "select mean(enp0s25.tx*-1) from \"network\" where $timeFilter group by time($interval) fill(null) order asc", + "alias": "Tx", + "fill": "null" + } + ], + "aliasColors": {}, + "seriesOverrides": [], + "links": [] + }, + { + "title": "SWAP", + "error": false, + "span": 6, + "editable": true, + "type": "graph", + "id": 8, + "datasource": "glances", + "renderer": "flot", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "bytes", + "short" + ], + "grid": { + "leftMax": null, + "rightMax": null, + "leftMin": null, + "rightMin": null, + "threshold1": null, + "threshold2": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "lines": true, + "fill": 0, + "linewidth": 1, + "points": false, + "pointradius": 5, + "bars": false, + "stack": false, + "percentage": false, + "legend": { + "show": true, + "values": false, + "min": false, + "max": false, + "current": false, + "total": false, + "avg": false + }, + "nullPointMode": "connected", + "steppedLine": false, + "tooltip": { + "value_type": "cumulative", + "shared": false + }, + "targets": [ + { + "function": "mean", + "column": "used", + "series": "memswap", + "query": "select mean(used) from \"memswap\" where $timeFilter group by time($interval) order asc", + "alias": "Used" + }, + { + "target": "", + "function": "mean", + "column": "total", + "series": "memswap", + "query": "select mean(total) from \"memswap\" where $timeFilter group by time($interval) order asc", + "alias": "Max" + } + ], + "aliasColors": {}, + "seriesOverrides": [], + "links": [] + } + ] + }, + { + "title": "New row", + "height": "250px", + "editable": true, + "collapse": false, + "panels": [ + { + "title": "sda2 disk IO", + "error": false, + "span": 6, + "editable": true, + "type": "graph", + "id": 10, + "datasource": "glances", + "renderer": "flot", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "bytes", + "short" + ], + "grid": { + "leftMax": null, + "rightMax": null, + "leftMin": null, + "rightMin": null, + "threshold1": null, + "threshold2": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "lines": true, + "fill": 0, + "linewidth": 1, + "points": false, + "pointradius": 5, + "bars": false, + "stack": false, + "percentage": false, + "legend": { + "show": true, + "values": false, + "min": false, + "max": false, + "current": false, + "total": false, + "avg": false + }, + "nullPointMode": "connected", + "steppedLine": false, + "tooltip": { + "value_type": "cumulative", + "shared": false + }, + "targets": [ + { + "function": "mean", + "column": "sda2.read_bytes", + "series": "diskio", + "query": "select mean(sda2.read_bytes) from \"diskio\" where $timeFilter group by time($interval) fill(null) order asc", + "alias": "Read", + "fill": "null" + }, + { + "target": "", + "function": "mean", + "column": "sda2.write_bytes", + "series": "diskio", + "query": "select mean(sda2.write_bytes) from \"diskio\" where $timeFilter group by time($interval) fill(null) order asc", + "alias": "Write", + "fill": "null" + } + ], + "aliasColors": {}, + "seriesOverrides": [], + "links": [] + }, + { + "title": "/ Size", + "error": false, + "span": 4, + "editable": true, + "type": "graph", + "id": 11, + "datasource": "glances", + "renderer": "flot", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "bytes", + "short" + ], + "grid": { + "leftMax": null, + "rightMax": null, + "leftMin": null, + "rightMin": null, + "threshold1": null, + "threshold2": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "lines": true, + "fill": 0, + "linewidth": 1, + "points": false, + "pointradius": 5, + "bars": false, + "stack": false, + "percentage": false, + "legend": { + "show": true, + "values": false, + "min": false, + "max": false, + "current": false, + "total": false, + "avg": false + }, + "nullPointMode": "connected", + "steppedLine": false, + "tooltip": { + "value_type": "cumulative", + "shared": false + }, + "targets": [ + { + "function": "mean", + "column": "\"/.used\"", + "series": "fs", + "query": "select mean(\"/.used\") from \"fs\" where $timeFilter group by time($interval) fill(null) order asc", + "alias": "Used", + "fill": "null" + }, + { + "target": "", + "function": "mean", + "column": "\"/.size\"", + "series": "fs", + "query": "select mean(\"/.size\") from \"fs\" where $timeFilter group by time($interval) fill(null) order asc", + "alias": "Max", + "fill": "null" + } + ], + "aliasColors": {}, + "seriesOverrides": [], + "links": [] + }, + { + "title": "/ used", + "error": false, + "span": 1, + "editable": true, + "type": "singlestat", + "id": 16, + "links": [], + "maxDataPoints": 100, + "interval": null, + "targets": [ + { + "function": "mean", + "column": "\"/.percent\"", + "series": "fs", + "query": "select mean(\"/.percent\") from \"fs\" where $timeFilter group by time($interval) order asc" + } + ], + "cacheTimeout": null, + "format": "percent", + "prefix": "", + "postfix": "", + "nullText": null, + "valueMaps": [ + { + "value": "null", + "op": "=", + "text": "N/A" + } + ], + "nullPointMode": "connected", + "valueName": "avg", + "prefixFontSize": "50%", + "valueFontSize": "80%", + "postfixFontSize": "50%", + "thresholds": "0,70,90", + "colorBackground": true, + "colorValue": false, + "colors": [ + "rgba(71, 212, 59, 0.4)", + "rgba(245, 150, 40, 0.73)", + "rgba(225, 40, 40, 0.59)" + ], + "sparkline": { + "show": true, + "full": false, + "lineColor": "rgb(193, 71, 31)", + "fillColor": "rgba(31, 118, 189, 0.18)" + } + }, + { + "title": "/home used", + "error": false, + "span": 1, + "editable": true, + "type": "singlestat", + "id": 17, + "links": [], + "maxDataPoints": 100, + "interval": null, + "targets": [ + { + "function": "mean", + "column": "\"/home.percent\"", + "series": "fs", + "query": "select mean(\"/home.percent\") from \"fs\" where $timeFilter group by time($interval) order asc" + } + ], + "cacheTimeout": null, + "format": "percent", + "prefix": "", + "postfix": "", + "nullText": null, + "valueMaps": [ + { + "value": "null", + "op": "=", + "text": "N/A" + } + ], + "nullPointMode": "connected", + "valueName": "avg", + "prefixFontSize": "50%", + "valueFontSize": "80%", + "postfixFontSize": "50%", + "thresholds": "0,70,90", + "colorBackground": true, + "colorValue": false, + "colors": [ + "rgba(71, 212, 59, 0.4)", + "rgba(245, 150, 40, 0.73)", + "rgba(225, 40, 40, 0.59)" + ], + "sparkline": { + "show": true, + "full": false, + "lineColor": "rgb(193, 71, 31)", + "fillColor": "rgba(31, 118, 189, 0.18)" + } + } + ] + }, + { + "title": "New row", + "height": "25px", + "editable": true, + "collapse": false, + "panels": [ + { + "title": "CPU details", + "error": false, + "span": 12, + "editable": true, + "type": "text", + "id": 13, + "mode": "text", + "content": "", + "style": {}, + "links": [] + } + ] + }, + { + "title": "New row", + "height": "250px", + "editable": true, + "collapse": false, + "panels": [ + { + "title": "CPU user", + "error": false, + "span": 12, + "editable": true, + "type": "graph", + "id": 12, + "datasource": null, + "renderer": "flot", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "short", + "short" + ], + "grid": { + "leftMax": null, + "rightMax": null, + "leftMin": null, + "rightMin": null, + "threshold1": null, + "threshold2": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "lines": true, + "fill": 0, + "linewidth": 1, + "points": false, + "pointradius": 5, + "bars": false, + "stack": false, + "percentage": false, + "legend": { + "show": true, + "values": false, + "min": false, + "max": false, + "current": false, + "total": false, + "avg": false + }, + "nullPointMode": "connected", + "steppedLine": false, + "tooltip": { + "value_type": "cumulative", + "shared": false + }, + "targets": [ + { + "function": "mean", + "column": "user", + "series": "cpu", + "query": "select mean(user) from \"cpu\" where $timeFilter group by time($interval) order asc", + "interval": "60s", + "alias": "mean" + }, + { + "target": "", + "function": "min", + "column": "user", + "series": "cpu", + "query": "select min(user) from \"cpu\" where $timeFilter group by time($interval) order asc", + "interval": "60s", + "alias": "min" + }, + { + "target": "", + "function": "max", + "column": "user", + "series": "cpu", + "query": "select max(user) from \"cpu\" where $timeFilter group by time($interval) order asc", + "interval": "60s", + "alias": "max" + } + ], + "aliasColors": { + "max": "#890F02" + }, + "seriesOverrides": [ + { + "alias": "max", + "fillBelowTo": "min", + "lines": false + }, + { + "alias": "min", + "lines": false + }, + { + "alias": "mean", + "zindex": 3, + "linewidth": 2 + } + ], + "links": [] + }, + { + "title": "CPU system", + "error": false, + "span": 12, + "editable": true, + "type": "graph", + "id": 14, + "datasource": null, + "renderer": "flot", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "short", + "short" + ], + "grid": { + "leftMax": null, + "rightMax": null, + "leftMin": null, + "rightMin": null, + "threshold1": null, + "threshold2": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "lines": true, + "fill": 0, + "linewidth": 1, + "points": false, + "pointradius": 5, + "bars": false, + "stack": false, + "percentage": false, + "legend": { + "show": true, + "values": false, + "min": false, + "max": false, + "current": false, + "total": false, + "avg": false + }, + "nullPointMode": "connected", + "steppedLine": false, + "tooltip": { + "value_type": "cumulative", + "shared": false + }, + "targets": [ + { + "function": "mean", + "column": "system", + "series": "cpu", + "query": "select mean(system) from \"cpu\" where $timeFilter group by time($interval) order asc", + "interval": "60s", + "alias": "mean" + }, + { + "target": "", + "function": "min", + "column": "system", + "series": "cpu", + "query": "select min(system) from \"cpu\" where $timeFilter group by time($interval) order asc", + "interval": "60s", + "alias": "min" + }, + { + "target": "", + "function": "max", + "column": "system", + "series": "cpu", + "query": "select max(system) from \"cpu\" where $timeFilter group by time($interval) order asc", + "interval": "60s", + "alias": "max" + } + ], + "aliasColors": { + "max": "#890F02" + }, + "seriesOverrides": [ + { + "alias": "max", + "fillBelowTo": "min", + "lines": false + }, + { + "alias": "min", + "lines": false + }, + { + "alias": "mean", + "zindex": 3, + "linewidth": 2 + } + ], + "links": [] + }, + { + "title": "CPU iowait", + "error": false, + "span": 12, + "editable": true, + "type": "graph", + "id": 15, + "datasource": null, + "renderer": "flot", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "short", + "short" + ], + "grid": { + "leftMax": null, + "rightMax": null, + "leftMin": null, + "rightMin": null, + "threshold1": null, + "threshold2": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "lines": true, + "fill": 0, + "linewidth": 1, + "points": false, + "pointradius": 5, + "bars": false, + "stack": false, + "percentage": false, + "legend": { + "show": true, + "values": false, + "min": false, + "max": false, + "current": false, + "total": false, + "avg": false + }, + "nullPointMode": "connected", + "steppedLine": false, + "tooltip": { + "value_type": "cumulative", + "shared": false + }, + "targets": [ + { + "function": "mean", + "column": "iowait", + "series": "cpu", + "query": "select mean(iowait) from \"cpu\" where $timeFilter group by time($interval) order asc", + "interval": "60s", + "alias": "mean" + }, + { + "target": "", + "function": "min", + "column": "iowait", + "series": "cpu", + "query": "select min(iowait) from \"cpu\" where $timeFilter group by time($interval) order asc", + "interval": "60s", + "alias": "min" + }, + { + "target": "", + "function": "max", + "column": "iowait", + "series": "cpu", + "query": "select max(iowait) from \"cpu\" where $timeFilter group by time($interval) order asc", + "interval": "60s", + "alias": "max" + } + ], + "aliasColors": { + "max": "#890F02" + }, + "seriesOverrides": [ + { + "alias": "max", + "fillBelowTo": "min", + "lines": false + }, + { + "alias": "min", + "lines": false + }, + { + "alias": "mean", + "zindex": 3, + "linewidth": 2 + } + ], + "links": [] + } + ] + } + ], + "nav": [ + { + "type": "timepicker", + "collapse": false, + "enable": true, + "status": "Stable", + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ], + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "now": true, + "notice": false + } + ], + "time": { + "from": "now-12h", + "to": "now" + }, + "templating": { + "list": [] + }, + "annotations": { + "list": [] + }, + "refresh": false, + "version": 6, + "hideAllLegends": false +} \ No newline at end of file diff --git a/conf/glances-test.conf b/conf/glances-test.conf deleted file mode 100644 index 6e4444bf..00000000 --- a/conf/glances-test.conf +++ /dev/null @@ -1,174 +0,0 @@ -[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 - -[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 - -[statsd] -host=localhost -port=8125 -#prefix=glances diff --git a/conf/glances.conf b/conf/glances.conf index e42123a5..435994f4 100644 --- a/conf/glances.conf +++ b/conf/glances.conf @@ -1,3 +1,14 @@ +[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 @@ -81,6 +92,8 @@ critical=90 careful=50 warning=70 critical=90 +# Allow additionnals files types (comma-separated FS type) +#allow=zfs [sensors] # Sensors core limits @@ -133,11 +146,11 @@ mem_critical=90 #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 +#list_2_description=Python programs +#list_2_regex=.*python.* +#list_3_description=Famous Xeyes +#list_3_regex=.*xeyes.* +#list_3_countmin=1 #[serverlist] # Define the static server list @@ -158,8 +171,16 @@ port=8086 user=root password=root db=glances +#prefix=localhost [statsd] host=localhost port=8125 #prefix=glances + +[rabbitmq] +host=localhost +port=5672 +user=guest +password=guest +queue=glances_queue diff --git a/docs/glances-doc.html b/docs/glances-doc.html index 35f786b0..85b22d7a 100644 --- a/docs/glances-doc.html +++ b/docs/glances-doc.html @@ -123,9 +123,9 @@ td.option-group {

Glances

-

This manual describes Glances version 2.3.

+

This manual describes Glances version 2.4.

Copyright © 2011-2015 Nicolas Hennion <nicolas@nicolargo.com>

-

January 2015

+

May 2015

Table of Contents

-
  • Configuration
  • -
  • Logs and debug mode
  • -
  • Anatomy Of The Application
  • @@ -204,7 +215,12 @@ another one, called client, just run on the se client$ glances -c @server

    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):

     client$ glances --browser
     
    @@ -223,7 +239,7 @@ client, the latter will try to grab stats using the 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

    @@ -237,7 +253,11 @@ 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.

    +

    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.

    Screenshot from Chrome on Android

    images/screenshot-web2.png @@ -260,37 +280,45 @@ http://@server:61208 show program's version number and exit -d, --debug -Enable debug mode +enable debug mode -C CONF_FILE, --config CONF_FILE  path to the configuration file ---enable-history +--disable-network - enable the history mode + disable network module ---disable-bold -disable bold mode in the terminal +--disable-ip +disable IP module --disable-diskio  disable disk I/O module --disable-fs -disable filesystem module - ---disable-network - - disable network module +disable file system module --disable-sensors  disable sensors module +--disable-hddtemp + + disable hddtemp module + +--disable-raid +disable RAID module + +--disable-docker + + disable Docker module + --disable-left-sidebar - disable left sidebar + disable network, disk I/O, file system and +sensors modules (py3sensors needed) --disable-process @@ -299,29 +327,40 @@ http://@server:61208 --disable-log disable log module +--disable-quicklook + + disable quick look module + +--disable-bold +disable bold mode in the terminal + --enable-process-extended  enable extended stats on top process --enable-history - enable the history mode + enable the history mode (matplotlib needed) --path-history PATH_HISTORY - Set the export path for graph history + set the export path for graph history ---export-csv CSV_FILE +--export-csv EXPORT_CSV  export stats to a CSV file --export-influxdb - export stats to an InfluxDB server + export stats to an InfluxDB server (influxdb needed) --export-statsd - export stats to a Statsd server + export stats to a StatsD server (statsd needed) + +--export-rabbitmq + + export stats to a RabbitMQ server (pika needed) -c CLIENT, --client CLIENT @@ -332,7 +371,7 @@ hostname run Glances in server mode --browser -run the Glances client browser (list of Glances server) +start the client browser (list of Glances servers) --disable-autodiscover @@ -345,18 +384,9 @@ hostname -B BIND_ADDRESS, --bind BIND_ADDRESS  bind server to the given IPv4/IPv6 address or hostname - ---password-badidea PASSWORD_ARG - - define password from the command line --password -define a client/server password from the prompt or -file - ---disable-autodiscover - - Hide Glances server from the auto discover feature +define a client/server password --snmp-community SNMP_COMMUNITY @@ -387,11 +417,14 @@ file -w, --webserver - run Glances in web server mode + run Glances in web server mode (bottle needed) + +-q, --quiet +do not display the curses interface -f PROCESS_FILTER, --process-filter PROCESS_FILTER - set the process filter patern (regular expression) + set the process filter pattern (regular expression) --process-short-name @@ -412,10 +445,10 @@ file --fs-free-space - display FS free space instead of used + display file system free space instead of used --theme-white -optimize display for white background +optimize display colors for white background @@ -451,7 +484,7 @@ Filter is a regular expression pattern:

    f
    Show/hide file system stats
    F
    -
    Switch between FS used and free space
    +
    Switch between file system used and free space
    g
    Generate graphs for current history
    h
    @@ -477,6 +510,8 @@ Filter is a regular expression pattern:

    T
    View network I/O as combination
    u
    +
    Sort processes by USER
    +
    U
    View cumulative network I/O
    w
    Delete finished warning log messages
    @@ -488,10 +523,13 @@ Filter is a regular expression pattern:

    Switch between global CPU and per-CPU stats
    2
    Enable/disable left sidebar
    +
    3
    +
    Enable/disable the quick look module
    /
    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
    @@ -507,19 +545,24 @@ Filter is a regular expression pattern:

    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.

    -

    By default, the configuration file is under:

    +

    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.

    +
    +

    Location

    +

    You can put the configuration file glances.conf in the following +locations:

    - + - + - + + +
    Linux:/etc/glances/glances.conf
    Linux:~/.config/glances, /etc/glances
    *BSD and OS X:/usr/local/etc/glances/glances.conf
    *BSD:~/.config/glances, /usr/local/etc/glances
    Windows:%APPDATA%\glances\glances.conf
    OS X:~/Library/Application Support/glances, /usr/local/etc/glances
    Windows:%APPDATA%\glances
    @@ -530,20 +573,12 @@ C:\Documents and Settings\<User>\Application Data

    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.

    -

    Just copy the glances.conf file to your $XDG_CONFIG_HOME directory, -e.g., on Linux:

    -
    -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

    +

    User-specific options override system-wide options and options given on +the command line override either.

    +
    +
    +

    Syntax

    Each plugin and export module can have a section.

    Example for the CPU plugin:

    @@ -561,13 +596,15 @@ steal_careful=50
     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:

     steal_log=True
     
    +
    -

    Logs and debug mode

    +

    Logs and debug mode

    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.

    @@ -576,19 +613,20 @@ can ben logged using the -d option on the command line.

    -Linux, *BSD and OS X: +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

    +

    Anatomy Of The Application

    -

    Legend

    +

    Legend

    GREEN stat counter is "OK"
    BLUE stat counter is "CAREFUL"
    @@ -599,7 +637,7 @@ can ben logged using the -d option on the command line.

    view.

    +
    +

    QuickLook

    +

    The quicklook plugin is only displayed on wide screen and propose a +bar view for CPU and memory (virtual and swap).

    +images/quicklook.png +

    Note: limit values can be overwritten in the configuration file under +the [quicklook] section.

    +
    -

    CPU

    +

    CPU

    Short view:

    images/cpu.png

    If enough horizontal space is available, extended CPU information are @@ -632,7 +678,7 @@ time. The total CPU usage is displayed on the first line.

    the [cpu] and/or [percpu] sections.

    -

    Load

    +

    Load

    images/load.png

    On the No Sheep blog, Zachary Tirrell defines the load average [1]:

    @@ -652,7 +698,7 @@ The first line also displays the number of CPU core.

    the [load] section.

    -

    Memory

    +

    Memory

    Glances uses two columns: one for the RAM and one for the SWAP.

    images/mem.png

    If enough space is available, Glances displays extended information for @@ -669,7 +715,7 @@ the RAM:

    the [memory] and/or [memswap] sections.

    -

    Network

    +

    Network

    images/network.png

    Glances displays the network interface bit rate. The unit is adapted dynamically (bits per second, kbits per second, Mbits per second, etc).

    @@ -680,7 +726,7 @@ and per-interface limit values in the [network]
    -

    Disk I/O

    +

    Disk I/O

    images/diskio.png

    Glances displays the disk I/O throughput. The unit is adapted dynamically.

    There is no alert on this information.

    @@ -688,7 +734,7 @@ configuration file and aliases for interface name.

    [diskio] section in the configuration file and aliases for disk name.

    -

    File System

    +

    File System

    images/fs.png

    Glances displays the used and total file system disk space. The unit is adapted dynamically.

    @@ -703,9 +749,16 @@ adapted dynamically.

    the [filesystem] section.

    If a RAID controller is detected on you system, its status will be displayed:

    images/raid.png +

    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:

    +
    +[fs]
    +allow=zfs,misc
    +
    -

    Sensors

    +

    Sensors

    Glances can displays the sensors information using lm-sensors, hddtemp and batinfo [2].

    All of the above libraries are available only on Linux.

    @@ -713,11 +766,11 @@ the [filesystem] section.

    temperature only.

    images/sensors.png

    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

    +

    Processes List

    Compact view:

    images/processlist.png

    Full view:

    @@ -786,7 +839,8 @@ User cans switch to the process name by pressing on the Z
    Zombie
    -

    In standalone mode, additionals informations are provided for the top process:

    +

    In standalone mode, additional informations are provided for the top +process:

    images/processlist-top.png
    • CPU affinity (number of cores used by the process)
    • @@ -794,12 +848,13 @@ User cans switch to the process name by pressing on 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.

    -

    Monitored Processes List

    +

    Monitored Processes List

    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.

    @@ -835,10 +890,10 @@ list_1_regex=.*nginx.* list_1_command=nginx -v list_1_countmin=1 list_1_countmax=4 -list_1_description=PHP-FPM -list_1_regex=.*php-fpm.* -list_1_countmin=1 -list_1_countmax=20 +list_2_description=PHP-FPM +list_2_regex=.*php-fpm.* +list_2_countmin=1 +list_2_countmax=20

    In client/server mode, the list is defined on the server side. A new method, called getAllMonitored, is available in the APIs and @@ -851,7 +906,7 @@ get the JSON representation of the monitored processes list.

    -

    Logs

    +

    Logs

    images/logs.png

    A log messages list is displayed in the bottom of the screen if (and only if):

    @@ -870,31 +925,39 @@ processes list alerts
    -

    Docker

    -

    If you use Docker, Glances can help you to monitor your container. Glances uses the Docker API through the Docker-Py library.

    +

    Docker

    +

    If you use Docker, Glances can help you to monitor your container. +Glances uses the Docker API through the docker-py library.

    images/docker.png
    -

    Actions

    +

    Actions

    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:

     [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:

    +

    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:

     [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)

    +

    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

    +

    Gateway to others services

    +
    +

    CSV

    It is possible to export statistics to CSV file.

     $ glances --export-csv /tmp/glances.csv
    @@ -902,8 +965,12 @@ warning_action=echo {{mnt_point}} {{used}}/{{size}} > /tmp/fs.alert
     

    CSV file description: - Stats description (first line) - Stats (others lines)

    -

    InfluxDB

    -

    You can export statistics to an InfluxDB server (time series server). The connection should be defined in the Glances configuration file as following:

    +
    +
    +

    InfluxDB

    +

    You can export statistics to an InfluxDB server (time series server). +The connection should be defined in the Glances configuration file as +following:

     [influxdb]
     host=localhost
    @@ -916,15 +983,22 @@ db=glances
     
     $ glances --export-influxdb
     
    -

    Statsd

    -

    You can export statistics to a Statsd server (welcome to Graphite !). The connection should be defined in the Glances configuration file as following:

    +

    For Grafana users, Glances provides a dedicated dashboard. Just import +the file in your Grafana web interface.

    +images/grafana.png +
    +
    +

    Statsd

    +

    You can export statistics to a Statsd server (welcome to Graphite!). +The connection should be defined in the Glances configuration file as +following:

     [statsd]
     host=localhost
     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:

     $ glances --export-statsd
    @@ -938,18 +1012,39 @@ prefix=glances
     ...
     
    -
    -

    APIs Documentations

    -

    Glances includes a XML-RPC server and a RESTFUL-JSON API which and can be used by another client software.

    -

    APIs documentations are available at:

    +
    +

    RabbitMQ

    +

    You can export statistics to an RabbitMQ server (AMQP Broker). +The connection should be defined in the Glances configuration file as +following:

    +
    +[rabbitmq]
    +host=localhost
    +port=5672
    +user=glances
    +password=glances
    +queue=glances_queue
    +
    +

    and run Glances with:

    +
    +$ 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:

    -

    Support

    -

    To post a question about Glances use case, please post it to the offical Q&A forum.

    +

    Support

    +

    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.

    Feel free to contribute !

    diff --git a/docs/glances-doc.rst b/docs/glances-doc.rst index 65377b34..549e9cb8 100644 --- a/docs/glances-doc.rst +++ b/docs/glances-doc.rst @@ -2,11 +2,11 @@ Glances ======= -This manual describes *Glances* version 2.3. +This manual describes *Glances* version 2.4. Copyright © 2011-2015 Nicolas Hennion -January 2015 +May 2015 .. contents:: Table of Contents @@ -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 ================= @@ -134,46 +144,45 @@ Command-Line Options -h, --help show this help message and exit -V, --version show program's version number and exit - -d, --debug Enable debug mode + -d, --debug enable debug mode -C CONF_FILE, --config CONF_FILE path to the configuration file - --enable-history enable the history mode - --disable-bold disable bold mode in the terminal - --disable-diskio disable disk I/O module - --disable-fs disable filesystem module --disable-network disable network module + --disable-ip disable IP module + --disable-diskio disable disk I/O module + --disable-fs disable file system module --disable-sensors disable sensors module + --disable-hddtemp disable hddtemp module + --disable-raid disable RAID module + --disable-docker disable Docker module --disable-left-sidebar - disable left sidebar + disable network, disk I/O, file system and + sensors modules (py3sensors needed) --disable-process disable process module --disable-log disable log module + --disable-quicklook disable quick look module + --disable-bold disable bold mode in the terminal --enable-process-extended enable extended stats on top process - --enable-history enable the history mode + --enable-history enable the history mode (matplotlib needed) --path-history PATH_HISTORY - Set the export path for graph history - --export-csv CSV_FILE + set the export path for graph history + --export-csv EXPORT_CSV export stats to a CSV file - --export-influxdb - export stats to an InfluxDB server - --export-statsd - export stats to a Statsd server + --export-influxdb export stats to an InfluxDB server (influxdb needed) + --export-statsd export stats to a StatsD server (statsd needed) + --export-rabbitmq export stats to a RabbitMQ server (pika needed) -c CLIENT, --client CLIENT connect to a Glances server by IPv4/IPv6 address or hostname -s, --server run Glances in server mode - --browser run the Glances client browser (list of Glances server) + --browser start the client browser (list of Glances servers) --disable-autodiscover disable autodiscover feature -p PORT, --port PORT define the client/server TCP port [default: 61209] -B BIND_ADDRESS, --bind BIND_ADDRESS bind server to the given IPv4/IPv6 address or hostname - --password-badidea PASSWORD_ARG - define password from the command line - --password define a client/server password from the prompt or - file - --disable-autodiscover - Hide Glances server from the auto discover feature + --password define a client/server password --snmp-community SNMP_COMMUNITY SNMP community --snmp-port SNMP_PORT @@ -186,17 +195,18 @@ Command-Line Options SNMP authentication key (only for SNMPv3) --snmp-force force SNMP mode -t TIME, --time TIME set refresh time in seconds [default: 3 sec] - -w, --webserver run Glances in web server mode + -w, --webserver run Glances in web server mode (bottle needed) + -q, --quiet do not display the curses interface -f PROCESS_FILTER, --process-filter PROCESS_FILTER - set the process filter patern (regular expression) + set the process filter pattern (regular expression) --process-short-name force short name for processes name --hide-kernel-threads hide kernel threads in process list --tree display processes as a tree -b, --byte display network rate in byte per second -1, --percpu start Glances in per CPU mode - --fs-free-space display FS free space instead of used - --theme-white optimize display for white background + --fs-free-space display file system free space instead of used + --theme-white optimize display colors for white background Interactive Commands -------------------- @@ -226,7 +236,7 @@ The following commands (key pressed) are supported while in Glances: ``f`` Show/hide file system stats ``F`` - Switch between FS used and free space + Switch between file system used and free space ``g`` Generate graphs for current history ``h`` @@ -252,6 +262,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 @@ -263,10 +275,13 @@ The following commands (key pressed) are supported while in Glances: Switch between global CPU and per-CPU stats ``2`` Enable/disable left sidebar +``3`` + Enable/disable the quick look module ``/`` 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 @@ -282,15 +297,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: @@ -303,24 +323,12 @@ Since Windows Vista and newer versions: :: C:\Users\\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. @@ -342,7 +350,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:: @@ -357,10 +366,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 ========================== @@ -395,6 +405,17 @@ Disconnected: .. image:: images/disconnected.png +QuickLook +--------- + +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 + +*Note*: limit values can be overwritten in the configuration file under +the ``[quicklook]`` section. + CPU --- @@ -518,6 +539,15 @@ If a RAID controller is detected on you system, its status will be displayed: .. image:: images/raid.png +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: + +:: + + [fs] + allow=zfs,misc + Sensors ------- @@ -533,8 +563,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 -------------- @@ -611,7 +641,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 @@ -620,7 +651,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. @@ -670,10 +702,10 @@ another item: list_1_command=nginx -v list_1_countmin=1 list_1_countmax=4 - list_1_description=PHP-FPM - list_1_regex=.*php-fpm.* - list_1_countmin=1 - list_1_countmax=20 + list_2_description=PHP-FPM + list_2_regex=.*php-fpm.* + list_2_countmin=1 + list_2_countmax=20 In client/server mode, the list is defined on the server side. A new method, called `getAllMonitored`, is available in the APIs and @@ -708,16 +740,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:: @@ -725,7 +760,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:: @@ -733,13 +770,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. @@ -751,9 +790,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:: @@ -770,9 +812,17 @@ and run Glances with: $ glances --export-influxdb -*Statsd* +For Grafana users, Glances provides a dedicated `dashboard`_. Just import +the file in your ``Grafana`` web interface. -You can export statistics to a Statsd server (welcome to Graphite !). The connection should be defined in the Glances configuration file as following: +.. image:: images/grafana.png + +Statsd +------ + +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:: @@ -781,7 +831,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: @@ -799,13 +849,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 @@ -813,7 +885,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. @@ -828,3 +901,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 +.. _dashboard: https://github.com/nicolargo/glances/blob/master/conf/glances-grafana.json diff --git a/docs/images/grafana.png b/docs/images/grafana.png new file mode 100644 index 00000000..cd1602e3 Binary files /dev/null and b/docs/images/grafana.png differ diff --git a/docs/images/quicklook.png b/docs/images/quicklook.png new file mode 100644 index 00000000..9606ba18 Binary files /dev/null and b/docs/images/quicklook.png differ diff --git a/docs/images/screenshot-web.png b/docs/images/screenshot-web.png index 12644037..8467f863 100644 Binary files a/docs/images/screenshot-web.png and b/docs/images/screenshot-web.png differ diff --git a/docs/images/screenshot-web2.png b/docs/images/screenshot-web2.png index 30b3c997..786250f4 100644 Binary files a/docs/images/screenshot-web2.png and b/docs/images/screenshot-web2.png differ diff --git a/docs/images/screenshot-wide.png b/docs/images/screenshot-wide.png index 5f0a8221..2acf5340 100644 Binary files a/docs/images/screenshot-wide.png and b/docs/images/screenshot-wide.png differ diff --git a/docs/images/screenshot.png b/docs/images/screenshot.png index 197d34e3..3d34a6d0 100644 Binary files a/docs/images/screenshot.png and b/docs/images/screenshot.png differ diff --git a/glances/README.txt b/glances/README.txt index fe29ae0e..b512e62b 100644 --- a/glances/README.txt +++ b/glances/README.txt @@ -1,6 +1,7 @@ -You are in the main Glances's source folder. This page is **ONLY** for developpers purposes. +You are in the main Glances source folder. This page is **ONLY** for developers. -If you are looking for the user manual, please follow this link: https://github.com/nicolargo/glances/blob/master/docs/glances-doc.rst +If you are looking for the user manual, please follow this link: +https://github.com/nicolargo/glances/blob/master/docs/glances-doc.rst === @@ -9,11 +10,10 @@ __main__.py Entry point for Glances module core/ => Glances core folder glances_config.py Manage configuration file - glances_globals.py Share variables uppon modules + glances_globals.py Share variables upon modules glances_limits.py Manage limits glances_logs.py Manage logs glances_main.py Main script to rule them up... - glances_stats.py Inteface to grab stats glances_client.py Glances client glances_server.py Glances server glances_standalone.py Glances standalone (with curse interface) diff --git a/glances/__init__.py b/glances/__init__.py index 30636edb..68a8803f 100644 --- a/glances/__init__.py +++ b/glances/__init__.py @@ -20,12 +20,11 @@ """Init the Glances software.""" __appname__ = 'glances' -__version__ = '2.3' +__version__ = '2.4' __author__ = 'Nicolas Hennion ' __license__ = 'LGPL' # Import system lib -import gettext import locale import platform import signal @@ -40,23 +39,24 @@ except ImportError: # Import Glances libs # Note: others Glances libs will be imported optionally -from glances.core.glances_globals import gettext_domain, locale_dir from glances.core.glances_logging import logger from glances.core.glances_main import GlancesMain -# Get PSutil version -psutil_min_version = (2, 0, 0) -psutil_version = tuple([int(num) for num in __psutil_version.split('.')]) +try: + locale.setlocale(locale.LC_ALL, '') +except locale.Error: + print("Warning: Unable to set locale. Expect encoding problems.") -# First log with Glances and PSUtil version -logger.info('Start Glances {0}'.format(__version__)) -logger.info('{0} {1} and PSutil {2} detected'.format(platform.python_implementation(), - platform.python_version(), - __psutil_version)) +# Check Python version +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) # Check PSutil version +psutil_min_version = (2, 0, 0) +psutil_version = tuple([int(num) for num in __psutil_version.split('.')]) if psutil_version < psutil_min_version: - logger.critical('PSutil 2.0 or higher is needed. Glances cannot start.') + print('PSutil 2.0 or higher is needed. Glances cannot start.') sys.exit(1) @@ -94,9 +94,12 @@ def main(): Select the mode (standalone, client or server) Run it... """ - # Setup translations - locale.setlocale(locale.LC_ALL, '') - gettext.install(gettext_domain, locale_dir) + # Log Glances and PSutil version + logger.info('Start Glances {0}'.format(__version__)) + logger.info('{0} {1} and PSutil {2} detected'.format( + platform.python_implementation(), + platform.python_version(), + __psutil_version)) # Share global var global core, standalone, client, server, webserver @@ -164,7 +167,7 @@ def main(): server = GlancesServer(cached_time=core.cached_time, config=core.get_config(), args=args) - print(_("Glances server is running on {0}:{1}").format(args.bind_address, args.port)) + print('Glances server is running on {0}:{1}'.format(args.bind_address, args.port)) # Set the server login/password (if -P/--password tag) if args.password != "": diff --git a/glances/core/glances_actions.py b/glances/core/glances_actions.py index 1a762b70..dabcd1ba 100644 --- a/glances/core/glances_actions.py +++ b/glances/core/glances_actions.py @@ -19,11 +19,12 @@ """Manage on alert actions.""" +# Import system lib +from subprocess import Popen + # Import Glances lib from glances.core.glances_logging import logger -# Import system lib -from subprocess import Popen try: import pystache except ImportError: @@ -35,11 +36,10 @@ else: class GlancesActions(object): - """This class manage action if an alert is reached""" + """This class manage action if an alert is reached.""" def __init__(self): - """Init GlancesActions class""" - + """Init GlancesActions class.""" # Dict with the criticity status # - key: stat_name # - value: criticity @@ -47,25 +47,26 @@ class GlancesActions(object): self.status = {} def get(self, stat_name): - """Get the stat_name criticity""" + """Get the stat_name criticity.""" try: return self.status[stat_name] except KeyError: return None def set(self, stat_name, criticity): - """Set the stat_name to criticity""" + """Set the stat_name to criticity.""" self.status[stat_name] = criticity def run(self, stat_name, criticity, commands, mustache_dict=None): - """Run the commands (in background) + """Run the commands (in background). + - stats_name: plugin_name (+ header) - criticity: criticity of the trigger - commands: a list of command line with optional {{mustache}} - mustache_dict: Plugin stats (can be use within {{mustache}}) - Return True if the commands have been ran""" - + Return True if the commands have been ran. + """ if self.get(stat_name) == criticity: # Action already executed => Exit return False @@ -75,7 +76,7 @@ class GlancesActions(object): criticity, mustache_dict)) - # Ran all actions in background + # Run all actions in background for cmd in commands: # Replace {{arg}} by the dict one (Thk to {Mustache}) if pystache_tag: diff --git a/glances/core/glances_autodiscover.py b/glances/core/glances_autodiscover.py index f9659f08..3648e35f 100644 --- a/glances/core/glances_autodiscover.py +++ b/glances/core/glances_autodiscover.py @@ -22,11 +22,7 @@ # Import system libs import socket import sys -try: - import netifaces - netifaces_tag = True -except ImportError: - netifaces_tag = False + try: from zeroconf import ( __version__ as __zeroconf_version, @@ -42,13 +38,13 @@ except ImportError: from glances.core.glances_globals import appname from glances.core.glances_logging import logger -# Zeroconf 0.16 or higher is needed +# Zeroconf 0.17 or higher is needed if zeroconf_tag: - zeroconf_min_version = (0, 16, 0) + zeroconf_min_version = (0, 17, 0) zeroconf_version = tuple([int(num) for num in __zeroconf_version.split('.')]) logger.debug("Zeroconf version {0} detected.".format(__zeroconf_version)) if zeroconf_version < zeroconf_min_version: - logger.critical("Please install zeroconf 0.16 or higher.") + logger.critical("Please install zeroconf 0.17 or higher.") sys.exit(1) # Global var @@ -57,7 +53,7 @@ zeroconf_type = "_%s._tcp." % appname class AutoDiscovered(object): - """Class to manage the auto discovered servers dict""" + """Class to manage the auto discovered servers dict.""" def __init__(self): # server_dict is a list of dict (JSON compliant) @@ -65,30 +61,30 @@ class AutoDiscovered(object): self._server_list = [] def get_servers_list(self): - """Return the current server list (list of dict)""" + """Return the current server list (list of dict).""" return self._server_list def set_server(self, server_pos, key, value): - """Set the key to the value for the server_pos (position in the list)""" + """Set the key to the value for the server_pos (position in the list).""" self._server_list[server_pos][key] = value def add_server(self, name, ip, port): - """Add a new server to the list""" - new_server = {'key': name, # Zeroconf name with both hostname and port - 'name': name.split(':')[0], # Short name - 'ip': ip, # IP address seen by the client - 'port': port, # TCP port - 'username': 'glances', # Default username - 'password': '', # Default password - 'status': 'UNKNOWN', # Server status: 'UNKNOWN', 'OFFLINE', 'ONLINE', 'PROTECTED' - 'type': 'DYNAMIC', # Server type: 'STATIC' or 'DYNAMIC' - } + """Add a new server to the list.""" + new_server = { + 'key': name, # Zeroconf name with both hostname and port + 'name': name.split(':')[0], # Short name + 'ip': ip, # IP address seen by the client + 'port': port, # TCP port + 'username': 'glances', # Default username + 'password': '', # Default password + 'status': 'UNKNOWN', # Server status: 'UNKNOWN', 'OFFLINE', 'ONLINE', 'PROTECTED' + 'type': 'DYNAMIC'} # Server type: 'STATIC' or 'DYNAMIC' self._server_list.append(new_server) logger.debug("Updated servers list (%s servers): %s" % (len(self._server_list), self._server_list)) def remove_server(self, name): - """Remove a server from the dict""" + """Remove a server from the dict.""" for i in self._server_list: if i['key'] == name: try: @@ -103,22 +99,23 @@ class AutoDiscovered(object): class GlancesAutoDiscoverListener(object): - """Zeroconf listener for Glances server""" + """Zeroconf listener for Glances server.""" def __init__(self): # Create an instance of the servers list self.servers = AutoDiscovered() def get_servers_list(self): - """Return the current server list (list of dict)""" + """Return the current server list (list of dict).""" return self.servers.get_servers_list() def set_server(self, server_pos, key, value): - """Set the key to the value for the server_pos (position in the list)""" + """Set the key to the value for the server_pos (position in the list).""" self.servers.set_server(server_pos, key, value) def add_service(self, zeroconf, srv_type, srv_name): - """Method called when a new Zeroconf client is detected + """Method called when a new Zeroconf client is detected. + Return True if the zeroconf client is a Glances server Note: the return code will never be used """ @@ -141,7 +138,7 @@ class GlancesAutoDiscoverListener(object): return True def remove_service(self, zeroconf, srv_type, srv_name): - # Remove the server from the list + """Remove the server from the list.""" self.servers.remove_server(srv_name) logger.info( "Glances server %s removed from the autodetect list" % srv_name) @@ -149,7 +146,7 @@ class GlancesAutoDiscoverListener(object): class GlancesAutoDiscoverServer(object): - """Implementation of the Zeroconf protocol (server side for the Glances client)""" + """Implementation of the Zeroconf protocol (server side for the Glances client).""" def __init__(self, args=None): if zeroconf_tag: @@ -169,14 +166,14 @@ class GlancesAutoDiscoverServer(object): self.zeroconf_enable_tag = False def get_servers_list(self): - """Return the current server list (dict of dict)""" + """Return the current server list (dict of dict).""" if zeroconf_tag and self.zeroconf_enable_tag: return self.listener.get_servers_list() else: return [] def set_server(self, server_pos, key, value): - """Set the key to the value for the server_pos (position in the list)""" + """Set the key to the value for the server_pos (position in the list).""" if zeroconf_tag and self.zeroconf_enable_tag: self.listener.set_server(server_pos, key, value) @@ -197,16 +194,15 @@ class GlancesAutoDiscoverClient(object): except socket.error as e: logger.error("Cannot start zeroconf: {0}".format(e)) - if netifaces_tag: + try: # -B @ overwrite the dynamic IPv4 choice if zeroconf_bind_address == '0.0.0.0': zeroconf_bind_address = self.find_active_ip_address() - else: - logger.error("Couldn't find the active IP address: netifaces library not found.") + except KeyError: + # Issue #528 (no network interface available) + pass - logger.info("Announce the Glances server on the LAN (using {0} IP address)".format(zeroconf_bind_address)) print("Announce the Glances server on the LAN (using {0} IP address)".format(zeroconf_bind_address)) - self.info = ServiceInfo( zeroconf_type, '{0}:{1}.{2}'.format(hostname, args.port, zeroconf_type), address=socket.inet_aton(zeroconf_bind_address), port=args.port, @@ -215,15 +211,14 @@ class GlancesAutoDiscoverClient(object): else: logger.error("Cannot announce Glances server on the network: zeroconf library not found.") - def find_active_ip_address(self): + @staticmethod + def find_active_ip_address(): """Try to find the active IP addresses.""" - try: - # Interface of the default gateway - gateway_itf = netifaces.gateways()['default'][netifaces.AF_INET][1] - # IP address for the interface - return netifaces.ifaddresses(gateway_itf)[netifaces.AF_INET][0]['addr'] - except Exception: - return None + import netifaces + # Interface of the default gateway + gateway_itf = netifaces.gateways()['default'][netifaces.AF_INET][1] + # IP address for the interface + return netifaces.ifaddresses(gateway_itf)[netifaces.AF_INET][0]['addr'] def close(self): if zeroconf_tag: diff --git a/glances/core/glances_client.py b/glances/core/glances_client.py index 755b88c0..1b1ce176 100644 --- a/glances/core/glances_client.py +++ b/glances/core/glances_client.py @@ -28,11 +28,6 @@ try: except ImportError: # Python 2 from xmlrpclib import Transport, ServerProxy, ProtocolError, Fault -try: - import http.client as httplib -except ImportError: - # Python 2 - import httplib # Import Glances libs from glances.core.glances_globals import version @@ -43,7 +38,7 @@ from glances.outputs.glances_curses import GlancesCursesClient class GlancesClientTransport(Transport): - """This class overwrite the default XML-RPC transport and manage timeout""" + """This class overwrite the default XML-RPC transport and manage timeout.""" def set_timeout(self, timeout): self.timeout = timeout @@ -58,8 +53,8 @@ class GlancesClient(object): self.args = args self.config = config - # Client mode: - self.set_mode() + # Default client mode + self._client_mode = 'glances' # Return to browser or exit self.return_to_browser = return_to_browser @@ -82,29 +77,26 @@ class GlancesClient(object): self.log_and_exit("Client couldn't create socket {0}: {1}".format(uri, e)) def log_and_exit(self, msg=''): - """Log and (exit)""" + """Log and exit.""" if not self.return_to_browser: logger.critical(msg) sys.exit(2) else: logger.error(msg) - def set_mode(self, mode='glances'): + @property + def client_mode(self): + """Get the client mode.""" + return self._client_mode + + @client_mode.setter + def client_mode(self, mode): """Set the client mode. - 'glances' = Glances server (default) - 'snmp' = SNMP (fallback) """ - self.mode = mode - return self.mode - - def get_mode(self): - """Get the client mode. - - - 'glances' = Glances server (default) - - 'snmp' = SNMP (fallback) - """ - return self.mode + self._client_mode = mode def login(self): """Logon to the server.""" @@ -112,15 +104,14 @@ class GlancesClient(object): if not self.args.snmp_force: # First of all, trying to connect to a Glances server - self.set_mode('glances') client_version = None try: client_version = self.client.init() except socket.error as err: # Fallback to SNMP - logger.error("Connection to Glances server failed (%s)" % err) - self.set_mode('snmp') - fallbackmsg = _("Trying fallback to SNMP...") + self.client_mode = 'snmp' + logger.error("Connection to Glances server failed: {0}".format(err)) + fallbackmsg = 'No Glances server found. Trying fallback to SNMP...' if not self.return_to_browser: print(fallbackmsg) else: @@ -134,22 +125,25 @@ class GlancesClient(object): self.log_and_exit(msg) return False - if self.get_mode() == 'glances' and version.split('.')[0] == client_version.split('.')[0]: - # Init stats - self.stats = GlancesStatsClient(config=self.config, args=self.args) - self.stats.set_plugins(json.loads(self.client.getAllPlugins())) - logger.debug( - "Client version: %s / Server version: %s" % (version, client_version)) - elif self.get_mode() == 'glances': - self.log_and_exit("Client and server not compatible: Client version: %s / Server version: %s" % (version, client_version)) - return False + if self.client_mode == 'glances': + # Check that both client and server are in the same major version + if version.split('.')[0] == client_version.split('.')[0]: + # Init stats + self.stats = GlancesStatsClient(config=self.config, args=self.args) + self.stats.set_plugins(json.loads(self.client.getAllPlugins())) + logger.debug("Client version: {0} / Server version: {1}".format(version, client_version)) + else: + self.log_and_exit("Client and server not compatible: \ + Client version: {0} / Server version: {1}".format(version, client_version)) + return False else: - self.set_mode('snmp') + self.client_mode = 'snmp' - if self.get_mode() == 'snmp': + # SNMP mode + if self.client_mode == 'snmp': logger.info("Trying to grab stats by SNMP...") - # Fallback to SNMP if needed + from glances.core.glances_stats import GlancesStatsClientSNMP # Init stats @@ -172,13 +166,13 @@ class GlancesClient(object): def update(self): """Update stats from Glances/SNMP server.""" - if self.get_mode() == 'glances': + if self.client_mode == 'glances': return self.update_glances() - elif self.get_mode() == 'snmp': + elif self.client_mode == 'snmp': return self.update_snmp() else: self.end() - logger.critical("Unknown server mode: {0}".format(self.get_mode())) + logger.critical("Unknown server mode: {0}".format(self.client_mode)) sys.exit(2) def update_glances(self): @@ -222,22 +216,24 @@ class GlancesClient(object): def serve_forever(self): """Main client loop.""" - exitkey = False + try: + while True and not exitkey: + # Update the stats + cs_status = self.update() - 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) + except Exception as e: + logger.critical(e) + self.end() - # Export stats using export modules - self.stats.export(self.stats) - - return self.get_mode() + return self.client_mode def end(self): """End of the client session.""" diff --git a/glances/core/glances_client_browser.py b/glances/core/glances_client_browser.py index a198399b..804b29de 100644 --- a/glances/core/glances_client_browser.py +++ b/glances/core/glances_client_browser.py @@ -38,7 +38,7 @@ from glances.outputs.glances_curses import GlancesCursesBrowser class GlancesClientBrowser(object): - """This class creates and manages the TCP client browser (servers' list).""" + """This class creates and manages the TCP client browser (servers list).""" def __init__(self, config=None, args=None): # Store the arg/config @@ -58,9 +58,9 @@ class GlancesClientBrowser(object): self.screen = GlancesCursesBrowser(args=self.args) def get_servers_list(self): - """ - Return the current server list (list of dict) - Merge of static + autodiscover servers list + """Return the current server list (list of dict). + + Merge of static + autodiscover servers list. """ ret = [] @@ -71,7 +71,16 @@ class GlancesClientBrowser(object): return ret - def serve_forever(self): + def __get_uri(self, server): + """Return the URI for the given server dict.""" + # Select the connection mode (with or without password) + if server['password'] != "": + return 'http://{0}:{1}@{2}:{3}'.format(server['username'], server['password'], + server['ip'], server['port']) + else: + return 'http://{0}:{1}'.format(server['ip'], server['port']) + + def __serve_forever(self): """Main client loop.""" while True: # No need to update the server list @@ -84,15 +93,11 @@ class GlancesClientBrowser(object): # Do not retreive stats for statics server # Why ? Because for each offline servers, the timeout will be reached # So ? The curse interface freezes - if (v['type'] == 'STATIC' and v['status'] in ['UNKNOWN', 'SNMP', 'OFFLINE']): + if v['type'] == 'STATIC' and v['status'] in ['UNKNOWN', 'SNMP', 'OFFLINE']: continue - # Select the connection mode (with or without password) - if v['password'] != "": - uri = 'http://{0}:{1}@{2}:{3}'.format(v['username'], v['password'], - v['ip'], v['port']) - else: - uri = 'http://{0}:{1}'.format(v['ip'], v['port']) + # Get the server URI + uri = self.__get_uri(v) # Try to connect to the server t = GlancesClientTransport() @@ -146,46 +151,48 @@ class GlancesClientBrowser(object): "Server list dictionnary change inside the loop (wait next update)") # Update the screen (list or Glances client) - if self.screen.get_active() is None: + if self.screen.active_server is None: # Display the Glances browser self.screen.update(self.get_servers_list()) else: # Display the Glances client for the selected server - logger.debug("Selected server: %s" % self.get_servers_list()[self.screen.get_active()]) + logger.debug("Selected server: {0}".format(self.get_servers_list()[self.screen.active_server])) # Connection can take time # Display a popup - self.screen.display_popup(_("Connect to %s:%s" % (v['name'], v['port'])), duration=1) + self.screen.display_popup( + 'Connect to {0}:{1}'.format(v['name'], v['port']), duration=1) # A password is needed to access to the server's stats - if self.get_servers_list()[self.screen.get_active()]['password'] is None: + if self.get_servers_list()[self.screen.active_server]['password'] is None: from hashlib import sha256 # Display a popup to enter password - clear_password = self.screen.display_popup(_("Password needed for %s: " % v['name']), is_input=True) + clear_password = self.screen.display_popup( + 'Password needed for {0}: '.format(v['name']), is_input=True) # Hash with SHA256 - encoded_password = sha256(clear_password).hexdigest() + encoded_password = sha256(clear_password.encode('utf-8')).hexdigest() # Store the password for the selected server self.set_in_selected('password', encoded_password) # Display the Glance client on the selected server - logger.info("Connect Glances client to the %s server" % - self.get_servers_list()[self.screen.get_active()]['key']) + logger.info("Connect Glances client to the {0} server".format( + self.get_servers_list()[self.screen.active_server]['key'])) # Init the client args_server = self.args # Overwrite connection setting - args_server.client = self.get_servers_list()[self.screen.get_active()]['ip'] - args_server.port = self.get_servers_list()[self.screen.get_active()]['port'] - args_server.username = self.get_servers_list()[self.screen.get_active()]['username'] - args_server.password = self.get_servers_list()[self.screen.get_active()]['password'] - client = GlancesClient(config=self.config, - args=args_server, - return_to_browser=True) + args_server.client = self.get_servers_list()[self.screen.active_server]['ip'] + args_server.port = self.get_servers_list()[self.screen.active_server]['port'] + args_server.username = self.get_servers_list()[self.screen.active_server]['username'] + args_server.password = self.get_servers_list()[self.screen.active_server]['password'] + client = GlancesClient(config=self.config, args=args_server, return_to_browser=True) # Test if client and server are in the same major version if not client.login(): - self.screen.display_popup(_("Sorry, cannot connect to %s (see log file for additional information)" % v['name'])) + self.screen.display_popup( + "Sorry, cannot connect to '{0}'\n" + "See 'glances.log' for more details".format(v['name'])) # Set the ONLINE status for the selected server self.set_in_selected('status', 'OFFLINE') @@ -195,8 +202,8 @@ class GlancesClientBrowser(object): connection_type = client.serve_forever() try: - logger.debug("Disconnect Glances client from the %s server" % - self.get_servers_list()[self.screen.get_active()]['key']) + logger.debug("Disconnect Glances client from the {0} server".format( + self.get_servers_list()[self.screen.active_server]['key'])) except IndexError: # Server did not exist anymore pass @@ -208,19 +215,28 @@ class GlancesClientBrowser(object): self.set_in_selected('status', 'ONLINE') # Return to the browser (no server selected) - self.screen.set_active(None) + 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""" + """Set the (key, value) for the selected server in the list.""" # Static list then dynamic one - if self.screen.get_active() >= len(self.static_server.get_servers_list()): - self.autodiscover_server.set_server(self.screen.get_active() - len(self.static_server.get_servers_list()), - key, - value) + if self.screen.active_server >= len(self.static_server.get_servers_list()): + self.autodiscover_server.set_server( + self.screen.active_server - len(self.static_server.get_servers_list()), + key, value) else: - self.static_server.set_server(self.screen.get_active(), - key, - value) + self.static_server.set_server(self.screen.active_server, key, value) def end(self): """End of the client browser session.""" diff --git a/glances/core/glances_config.py b/glances/core/glances_config.py index 935f08e3..828fb7d1 100644 --- a/glances/core/glances_config.py +++ b/glances/core/glances_config.py @@ -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('processlist', 'cpu_careful', '50') + self.parser.set('processlist', 'cpu_warning', '70') + self.parser.set('processlist', 'cpu_critical', '90') + self.parser.set('processlist', 'mem_careful', '50') + self.parser.set('processlist', 'mem_warning', '70') + self.parser.set('processlist', '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) diff --git a/glances/core/glances_cpu_percent.py b/glances/core/glances_cpu_percent.py new file mode 100644 index 00000000..9488d8d4 --- /dev/null +++ b/glances/core/glances_cpu_percent.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# +# This file is part of Glances. +# +# Copyright (C) 2015 Nicolargo +# +# 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 . + +"""CPU percent stats shared between CPU and Quicklook plugins.""" + +from glances.core.glances_timer import Timer + +import psutil + + +class CpuPercent(object): + + """Get and store the CPU percent.""" + + def __init__(self, cached_time=1): + self.cpu_percent = 0 + + # cached_time is the minimum time interval between stats updates + # since last update is passed (will retrieve old cached info instead) + self.timer = Timer(0) + self.cached_time = cached_time + + def get(self): + """Update and/or return the CPU using the psutil library.""" + # Never update more than 1 time per cached_time + if self.timer.finished(): + self.cpu_percent = psutil.cpu_percent(interval=0.0) + self.timer = Timer(self.cached_time) + return self.cpu_percent + + +# CpuPercent instance shared between plugins +cpu_percent = CpuPercent() diff --git a/glances/core/glances_globals.py b/glances/core/glances_globals.py index 3cf9fa51..4d150e62 100644 --- a/glances/core/glances_globals.py +++ b/glances/core/glances_globals.py @@ -51,15 +51,3 @@ exports_path = os.path.realpath(os.path.join(work_path, '..', 'exports')) sys_path = sys.path[:] sys.path.insert(1, plugins_path) sys.path.insert(1, exports_path) - -def get_locale_path(paths): - for path in paths: - if os.path.exists(path): - return path - -# 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]) diff --git a/glances/core/glances_logging.py b/glances/core/glances_logging.py index c7cb7e94..b5e604bb 100644 --- a/glances/core/glances_logging.py +++ b/glances/core/glances_logging.py @@ -17,10 +17,15 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -"""Custom logging class""" +"""Custom logging class.""" import logging -import logging.config +try: + # Python 2.6 + from logutils.dictconfig import dictConfig +except ImportError: + # Python >= 2.7 + from logging.config import dictConfig import os import tempfile @@ -72,29 +77,24 @@ LOGGING_CFG = { def tempfile_name(): - """Return the tempfile name (full path)""" + """Return the tempfile name (full path).""" ret = os.path.join(tempfile.gettempdir(), 'glances.log') if os.access(ret, os.F_OK) and not os.access(ret, os.W_OK): - print("Warning: can't write logs to file {} (permission denied)".format(ret)) + print("WARNING: Couldn't write to log file {0}: (Permission denied)".format(ret)) ret = tempfile.mkstemp(prefix='glances', suffix='.tmp', text=True) - print("Create a new log file: {}".format(ret[1])) + print("Create a new log file: {0}".format(ret[1])) return ret[1] + return ret def glances_logger(): - """Build and return the logger""" + """Build and return the logger.""" temp_path = tempfile_name() _logger = logging.getLogger() - try: - LOGGING_CFG['handlers']['file']['filename'] = temp_path - logging.config.dictConfig(LOGGING_CFG) - except AttributeError: - # dictConfig is only available for Python 2.7 or higher - # Minimal configuration for Python 2.6 - logging.basicConfig(filename=temp_path, - level=logging.DEBUG, - format='%(asctime)s -- %(levelname)s -- %(message)s') + LOGGING_CFG['handlers']['file']['filename'] = temp_path + dictConfig(LOGGING_CFG) + return _logger logger = glances_logger() diff --git a/glances/core/glances_logs.py b/glances/core/glances_logs.py index f2f9a3d4..14c6ee4d 100644 --- a/glances/core/glances_logs.py +++ b/glances/core/glances_logs.py @@ -87,29 +87,26 @@ class GlancesLogs(object): else: # Default sort is... process_auto_by = 'cpu_percent' - glances_processes.setautosortkey(process_auto_by) - - return process_auto_by + glances_processes.auto_sort = True + glances_processes.sort_key = process_auto_by def reset_process_sort(self): - """Reset the process_auto_by variable.""" + """Reset the process auto sort key.""" # Default sort is... - process_auto_by = 'cpu_percent' - glances_processes.setautosortkey(process_auto_by) - glances_processes.setmanualsortkey(None) - - return process_auto_by + glances_processes.auto_sort = True + glances_processes.sort_key = 'cpu_percent' def add(self, item_state, item_type, item_value, - proc_list=[], proc_desc="", - peak_time=3): + proc_list=None, proc_desc="", peak_time=6): """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 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 + If event < peak_time the the alert is not setoff. """ + proc_list = proc_list or [] + # Add or update the log item_index = self.__itemexist__(item_type) if item_index < 0: @@ -121,24 +118,23 @@ class GlancesLogs(object): # Create the new log item # Time is stored in Epoch format # Epoch -> DMYHMS = datetime.fromtimestamp(epoch) - item = [] - # START DATE - item.append(time.mktime(datetime.now().timetuple())) - item.append(-1) # END DATE - item.append(item_state) # STATE: WARNING|CRITICAL - item.append(item_type) # TYPE: CPU, LOAD, MEM... - item.append(item_value) # MAX - item.append(item_value) # AVG - item.append(item_value) # MIN - item.append(item_value) # SUM - item.append(1) # COUNT - # Process list is sorted automaticaly - # Overwrite the user choise - # topprocess = sorted(proc_list, key=lambda process: process[process_auto_by], - # reverse=True) - # item.append(topprocess[0:3]) # TOP 3 PROCESS LIST - item.append([]) # TOP 3 PROCESS LIST - item.append(proc_desc) # MONITORED PROCESSES DESC + item = [ + time.mktime(datetime.now().timetuple()), # START DATE + -1, # END DATE + item_state, # STATE: WARNING|CRITICAL + item_type, # TYPE: CPU, LOAD, MEM... + item_value, # MAX + item_value, # AVG + item_value, # MIN + item_value, # SUM + 1, # COUNT + # Process list is sorted automatically + # Overwrite the user choice + # topprocess = sorted(proc_list, key=lambda process: process[process_auto_by], + # reverse=True) + # topprocess[0:3], # TOP 3 PROCESS LIST + [], # TOP 3 PROCESS LIST + proc_desc] # MONITORED PROCESSES DESC # Add the item to the list self.logs_list.insert(0, item) @@ -190,12 +186,12 @@ class GlancesLogs(object): def clean(self, critical=False): """Clean the logs list by deleting finished items. - By default, only delete WARNING message - If critical = True, also delete CRITICAL message + By default, only delete WARNING message. + If critical = True, also delete CRITICAL message. """ # Create a new clean list clean_logs_list = [] - while (self.len() > 0): + while self.len() > 0: item = self.logs_list.pop() if item[1] < 0 or (not critical and item[2].startswith("CRITICAL")): clean_logs_list.insert(0, item) diff --git a/glances/core/glances_main.py b/glances/core/glances_main.py index fbc17417..6d4a2e37 100644 --- a/glances/core/glances_main.py +++ b/glances/core/glances_main.py @@ -27,7 +27,7 @@ import tempfile # Import Glances libs from glances.core.glances_config import Config -from glances.core.glances_globals import appname, is_windows, psutil_version, version +from glances.core.glances_globals import appname, is_linux, is_windows, psutil_version, version from glances.core.glances_logging import logger @@ -96,94 +96,104 @@ Start the client browser (browser mode):\n\ parser.add_argument( '-V', '--version', action='version', version=_version) parser.add_argument('-d', '--debug', action='store_true', default=False, - dest='debug', help=_('Enable debug mode')) + dest='debug', help='enable debug mode') parser.add_argument('-C', '--config', dest='conf_file', - help=_('path to the configuration file')) + help='path to the configuration file') # Enable or disable option on startup parser.add_argument('--disable-network', action='store_true', default=False, - dest='disable_network', help=_('disable network module')) + dest='disable_network', help='disable network module') + parser.add_argument('--disable-ip', action='store_true', default=False, + dest='disable_ip', help='disable IP module') parser.add_argument('--disable-diskio', action='store_true', default=False, - dest='disable_diskio', help=_('disable disk I/O module')) + dest='disable_diskio', help='disable disk I/O module') parser.add_argument('--disable-fs', action='store_true', default=False, - dest='disable_fs', help=_('disable filesystem module')) + dest='disable_fs', help='disable filesystem module') parser.add_argument('--disable-sensors', action='store_true', default=False, - dest='disable_sensors', help=_('disable sensors module')) + dest='disable_sensors', help='disable sensors module') + parser.add_argument('--disable-hddtemp', action='store_true', default=False, + dest='disable_hddtemp', help='disable HD temperature module') parser.add_argument('--disable-raid', action='store_true', default=False, - dest='disable_raid', help=_('disable RAID module')) + dest='disable_raid', help='disable RAID module') parser.add_argument('--disable-docker', action='store_true', default=False, - dest='disable_docker', help=_('disable Docker module')) - parser.add_argument('--disable-left-sidebar', action='store_true', default=False, - dest='disable_left_sidebar', help=_('disable network, disk io, FS and sensors modules (need Py3Sensors lib)')) + dest='disable_docker', help='disable Docker module') + parser.add_argument('--disable-left-sidebar', action='store_true', + default=False, dest='disable_left_sidebar', + help='disable network, disk I/O, FS and sensors modules (py3sensors needed)') parser.add_argument('--disable-process', action='store_true', default=False, - dest='disable_process', help=_('disable process module')) + dest='disable_process', help='disable process module') parser.add_argument('--disable-log', action='store_true', default=False, - dest='disable_log', help=_('disable log module')) + dest='disable_log', help='disable log module') + parser.add_argument('--disable-quicklook', action='store_true', default=False, + dest='disable_quicklook', help='disable quick look module') parser.add_argument('--disable-bold', action='store_false', default=True, - dest='disable_bold', help=_('disable bold mode in the terminal')) + dest='disable_bold', help='disable bold mode in the terminal') parser.add_argument('--enable-process-extended', action='store_true', default=False, - dest='enable_process_extended', help=_('enable extended stats on top process')) + dest='enable_process_extended', help='enable extended stats on top process') parser.add_argument('--enable-history', action='store_true', default=False, - dest='enable_history', help=_('enable the history mode (need MatPlotLib lib)')) + dest='enable_history', help='enable the history mode (matplotlib needed)') parser.add_argument('--path-history', default=tempfile.gettempdir(), - dest='path_history', help=_('Set the export path for graph history')) + dest='path_history', help='set the export path for graph history') # Export modules feature parser.add_argument('--export-csv', default=None, - dest='export_csv', help=_('export stats to a CSV file')) + dest='export_csv', help='export stats to a CSV file') parser.add_argument('--export-influxdb', action='store_true', default=False, - dest='export_influxdb', help=_('export stats to an InfluxDB server (need InfluDB lib)')) + dest='export_influxdb', help='export stats to an InfluxDB server (influxdb needed)') parser.add_argument('--export-statsd', action='store_true', default=False, - dest='export_statsd', help=_('export stats to a Statsd server (need StatsD lib)')) + dest='export_statsd', help='export stats to a StatsD server (statsd needed)') + parser.add_argument('--export-rabbitmq', action='store_true', default=False, + dest='export_rabbitmq', help='export stats to rabbitmq broker (pika needed)') # Client/Server option parser.add_argument('-c', '--client', dest='client', - help=_('connect to a Glances server by IPv4/IPv6 address or hostname')) + help='connect to a Glances server by IPv4/IPv6 address or hostname') parser.add_argument('-s', '--server', action='store_true', default=False, - dest='server', help=_('run Glances in server mode')) + dest='server', help='run Glances in server mode') parser.add_argument('--browser', action='store_true', default=False, - dest='browser', help=_('start the client browser (list of servers)')) + dest='browser', help='start the client browser (list of servers)') parser.add_argument('--disable-autodiscover', action='store_true', default=False, - dest='disable_autodiscover', help=_('disable autodiscover feature')) + dest='disable_autodiscover', help='disable autodiscover feature') parser.add_argument('-p', '--port', default=None, type=int, dest='port', - help=_('define the client/server TCP port [default: {0}]').format(self.server_port)) + help='define the client/server TCP port [default: {0}]'.format(self.server_port)) parser.add_argument('-B', '--bind', default='0.0.0.0', dest='bind_address', - help=_('bind server to the given IPv4/IPv6 address or hostname')) - parser.add_argument('--password-badidea', dest='password_arg', - help=_('define password from the command line')) + help='bind server to the given IPv4/IPv6 address or hostname') parser.add_argument('--password', action='store_true', default=False, dest='password_prompt', - help=_('define a client/server password from the prompt or file')) + help='define a client/server password') parser.add_argument('--snmp-community', default='public', dest='snmp_community', - help=_('SNMP community')) + help='SNMP community') parser.add_argument('--snmp-port', default=161, type=int, - dest='snmp_port', help=_('SNMP port')) + dest='snmp_port', help='SNMP port') parser.add_argument('--snmp-version', default='2c', dest='snmp_version', - help=_('SNMP version (1, 2c or 3)')) + help='SNMP version (1, 2c or 3)') parser.add_argument('--snmp-user', default='private', dest='snmp_user', - help=_('SNMP username (only for SNMPv3)')) + help='SNMP username (only for SNMPv3)') parser.add_argument('--snmp-auth', default='password', dest='snmp_auth', - help=_('SNMP authentication key (only for SNMPv3)')) + help='SNMP authentication key (only for SNMPv3)') parser.add_argument('--snmp-force', action='store_true', default=False, - dest='snmp_force', help=_('force SNMP mode')) + dest='snmp_force', help='force SNMP mode') parser.add_argument('-t', '--time', default=self.refresh_time, type=float, - dest='time', help=_('set refresh time in seconds [default: {0} sec]').format(self.refresh_time)) + dest='time', help='set refresh time in seconds [default: {0} sec]'.format(self.refresh_time)) parser.add_argument('-w', '--webserver', action='store_true', default=False, - dest='webserver', help=_('run Glances in web server mode (need Bootle lib)')) + dest='webserver', help='run Glances in web server mode (bottle needed)') # Display options + parser.add_argument('-q', '--quiet', default=False, action='store_true', + dest='quiet', help='do not display the curses interface') parser.add_argument('-f', '--process-filter', default=None, type=str, - dest='process_filter', help=_('set the process filter pattern (regular expression)')) + dest='process_filter', help='set the process filter pattern (regular expression)') parser.add_argument('--process-short-name', action='store_true', default=False, - dest='process_short_name', help=_('force short name for processes name')) + dest='process_short_name', help='force short name for processes name') if not is_windows: parser.add_argument('--hide-kernel-threads', action='store_true', default=False, - dest='no_kernel_threads', help=_('hide kernel threads in process list')) - parser.add_argument('--tree', action='store_true', default=False, - dest='process_tree', help=_('display processes as a tree')) + dest='no_kernel_threads', help='hide kernel threads in process list') + if is_linux: + parser.add_argument('--tree', action='store_true', default=False, + dest='process_tree', help='display processes as a tree') parser.add_argument('-b', '--byte', action='store_true', default=False, - dest='byte', help=_('display network rate in byte per second')) + dest='byte', help='display network rate in byte per second') parser.add_argument('-1', '--percpu', action='store_true', default=False, - dest='percpu', help=_('start Glances in per CPU mode')) + dest='percpu', help='start Glances in per CPU mode') parser.add_argument('--fs-free-space', action='store_false', default=False, - dest='fs_free_space', help=_('display FS free space instead of used')) + dest='fs_free_space', help='display FS free space instead of used') parser.add_argument('--theme-white', action='store_true', default=False, - dest='theme_white', help=_('optimize display for white background')) + dest='theme_white', help='optimize display colors for white background') return parser @@ -217,22 +227,15 @@ Start the client browser (browser mode):\n\ # Server or client login/password args.username = self.username - if args.password_arg is not None: - from hashlib import sha256 - # Password is given as an argument - # Hash with SHA256 - # Only the SHA will be transmit on the network - args.password = sha256(args.password_arg).hexdigest() - elif args.password_prompt: + if args.password_prompt: # Interactive or file password if args.server: args.password = self.__get_password( - description=_( - "Define the password for the Glances server"), + description='Define the password for the Glances server', confirm=True) elif args.client: args.password = self.__get_password( - description=_("Enter the Glances server password"), + description='Enter the Glances server password', clear=True) else: # Default is no password @@ -260,6 +263,11 @@ Start the client browser (browser mode):\n\ sys.exit(2) logger.debug("History output path is set to {0}".format(args.path_history)) + # Disable HDDTemp if sensors are disabled + if args.disable_sensors: + args.disable_hddtemp = True + logger.debug("Sensors and HDDTemp are disabled") + return args def __hash_password(self, plain_password): diff --git a/glances/core/glances_monitor_list.py b/glances/core/glances_monitor_list.py index 98b0604f..7b9103f8 100644 --- a/glances/core/glances_monitor_list.py +++ b/glances/core/glances_monitor_list.py @@ -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,14 +68,13 @@ 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)) - pass else: if description is not None and regex is not None: # Build the new item @@ -127,26 +127,26 @@ class MonitorList(object): # Iter upon the monitored list for i in range(0, len(self.get())): # Search monitored processes by a regular expression - processlist = glances_processes.getlist() + processlist = glances_processes.getalllist() monitoredlist = [p for p in processlist if re.search(self.regex(i), p['cmdline']) is not None] self.__monitor_list[i]['count'] = len(monitoredlist) - if self.command(i) is None: - # If there is no command specified in the conf file - # then display CPU and MEM % - self.__monitor_list[i]['result'] = 'CPU: {0:.1f}% | MEM: {1:.1f}%'.format( - sum([p['cpu_percent'] for p in monitoredlist]), - sum([p['memory_percent'] for p in monitoredlist])) - continue - else: + if self.command(i) is not None: # Execute the user command line try: self.__monitor_list[i]['result'] = subprocess.check_output(self.command(i), shell=True) except subprocess.CalledProcessError: - self.__monitor_list[i]['result'] = _("Error: ") + self.command(i) + self.__monitor_list[i]['result'] = 'Error: ' + self.command(i) except Exception: - self.__monitor_list[i]['result'] = _("Cannot execute command") + self.__monitor_list[i]['result'] = 'Cannot execute command' + + if self.command(i) is None or self.__monitor_list[i]['result'] == '': + # If there is no command specified in the conf file + # then display CPU and MEM % + self.__monitor_list[i]['result'] = 'CPU: {0:.1f}% | MEM: {1:.1f}%'.format( + sum([p['cpu_percent'] for p in monitoredlist]), + sum([p['memory_percent'] for p in monitoredlist])) return self.__monitor_list diff --git a/glances/core/glances_password.py b/glances/core/glances_password.py index 3ec9179c..6032487a 100644 --- a/glances/core/glances_password.py +++ b/glances/core/glances_password.py @@ -110,11 +110,11 @@ class GlancesPassword(object): # password_plain is the plain SHA-256 password # password_hashed is the salt + SHA-256 password - password_sha = hashlib.sha256(getpass.getpass(_("Password: ")).encode('utf-8')).hexdigest() + password_sha = hashlib.sha256(getpass.getpass('Password: ').encode('utf-8')).hexdigest() password_hashed = self.hash_password(password_sha) if confirm: # password_confirm is the clear password (only used to compare) - password_confirm = hashlib.sha256(getpass.getpass(_("Password (confirm): ")).encode('utf-8')).hexdigest() + password_confirm = hashlib.sha256(getpass.getpass('Password (confirm): ').encode('utf-8')).hexdigest() if not self.check_password(password_hashed, password_confirm): logger.critical("Sorry, passwords do not match. Exit.") @@ -128,8 +128,8 @@ class GlancesPassword(object): # Save the hashed password to the password file if not clear: - save_input = input(_("Do you want to save the password? [Yes/No]: ")) - if len(save_input) > 0 and save_input[0].upper() == _('Y'): + save_input = input('Do you want to save the password? [Yes/No]: ') + if len(save_input) > 0 and save_input[0].upper() == 'Y': self.save_password(password_hashed) return password diff --git a/glances/core/glances_processes.py b/glances/core/glances_processes.py index 6584a3d0..34a786ae 100644 --- a/glances/core/glances_processes.py +++ b/glances/core/glances_processes.py @@ -19,47 +19,47 @@ # Import Python lib import collections -import operator import os import re -# Import psutil -import psutil - # Import Glances lib from glances.core.glances_globals import is_bsd, is_linux, is_mac, is_windows from glances.core.glances_logging import logger -from glances.core.glances_timer import getTimeSinceLastUpdate, Timer +from glances.core.glances_timer import Timer, getTimeSinceLastUpdate + +# Import psutil +import psutil def is_kernel_thread(proc): - """ Return True if proc is a kernel thread, False instead. """ + """Return True if proc is a kernel thread, False instead.""" try: return os.getpgid(proc.pid) == 0 - except OSError: # Python >= 3.3 raises ProcessLookupError, which inherits OSError + # Python >= 3.3 raises ProcessLookupError, which inherits OSError + except OSError: # return False is process is dead return False class ProcessTreeNode(object): - """ - Represent a process tree. + """Represent a process tree. - We avoid recursive algorithm to manipulate the tree because function calls are expensive with CPython. + 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): - """ Return the tree as a string for debugging. """ + """Return the tree as a string for debugging.""" lines = [] nodes_to_print = collections.deque([collections.deque([("#", self)])]) while nodes_to_print: @@ -69,7 +69,8 @@ class ProcessTreeNode(object): if current_node.is_root: lines.append(indent_str) else: - lines.append("%s[%s]" % (indent_str, current_node.process.name())) + lines.append("%s[%s]" % + (indent_str, current_node.process.name())) indent_str = " " * (len(lines[-1]) - 1) children_nodes_to_print = collections.deque() for child in current_node.children: @@ -77,14 +78,18 @@ class ProcessTreeNode(object): tree_char = "└─" else: tree_char = "├─" - children_nodes_to_print.appendleft((indent_str + tree_char, child)) + children_nodes_to_print.appendleft( + (indent_str + tree_char, child)) if children_nodes_to_print: nodes_to_print.append(children_nodes_to_print) return "\n".join(lines) 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): + """Set sorting key or func for use with __iter__. + + This affects the whole tree from this node. + """ + 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() @@ -94,8 +99,8 @@ class ProcessTreeNode(object): nodes_to_flag_unsorted.extend(current_node.children) def get_weight(self): - """ Return "weight" of a process and all its children for sorting. """ - if self.sort_key == "name": + """Return 'weight' of a process and all its children for sorting.""" + if self.sort_key == 'name' or self.sort_key == 'username': return self.stats[self.sort_key] # sum ressource usage for self and children @@ -128,53 +133,63 @@ class ProcessTreeNode(object): return total def __iter__(self): - """ Iterator returning ProcessTreeNode in sorted order, recursively. """ + """Iterator returning ProcessTreeNode in sorted order, recursively.""" if not self.is_root: yield self if not self.children_sorted: # 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) + self.children.sort( + key=self.__class__.get_weight, reverse=self.sort_reverse) self.children_sorted = True for child in self.children: for n in iter(child): yield n def iter_children(self, exclude_incomplete_stats=True): - """ - Iterator returning ProcessTreeNode in sorted order (only children of this node, non recursive). + """Iterator returning ProcessTreeNode in sorted order. - If exclude_incomplete_stats is True, exclude processes not having full statistics. - It can happen after a resort (change of sort key) because process stats are not grabbed immediately, - but only at next full update. + Return only children of this node, non recursive. + + If exclude_incomplete_stats is True, exclude processes not + having full statistics. It can happen after a resort (change of + sort key) because process stats are not grabbed immediately, but + only at next full update. """ if not self.children_sorted: # 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) + self.children.sort( + 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): + if not exclude_incomplete_stats or "time_since_update" in child.stats: yield child def find_process(self, process): - """ Search in tree for the ProcessTreeNode owning process, return it or None if not found. """ + """Search in tree for the ProcessTreeNode owning process. + + Return it or None if not found. + """ nodes_to_search = collections.deque([self]) while nodes_to_search: current_node = nodes_to_search.pop() - if (not current_node.is_root) and (current_node.process.pid == process.pid): + if not current_node.is_root and current_node.process.pid == process.pid: return current_node nodes_to_search.extend(current_node.children) @staticmethod - def build_tree(process_dict, sort_key, hide_kernel_threads): - """ Build a process tree using using parent/child relationships, and return the tree root node. """ + def build_tree(process_dict, sort_key, sort_reverse, hide_kernel_threads): + """Build a process tree using using parent/child relationships. + + 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: @@ -192,13 +207,16 @@ class ProcessTreeNode(object): # parent is not in tree, add this node later nodes_to_add_last.append(new_node) - # next pass(es): add nodes to their parents if it could not be done in previous pass + # next pass(es): add nodes to their parents if it could not be done in + # previous pass while nodes_to_add_last: - node_to_add = nodes_to_add_last.popleft() # pop from left and append to right to avoid infinite loop + # pop from left and append to right to avoid infinite loop + node_to_add = nodes_to_add_last.popleft() try: parent_process = node_to_add.process.parent() except psutil.NoSuchProcess: - # parent is dead, consider no parent, add this node at the top level + # parent is dead, consider no parent, add this node at the top + # level tree_root.children.append(node_to_add) else: if parent_process is None: @@ -242,10 +260,11 @@ class GlancesProcesses(object): self.process_tree = None # Init stats - self.resetsort() + self.auto_sort = True + self._sort_key = 'cpu_percent' + self.allprocesslist = [] self.processlist = [] - self.processcount = { - 'total': 0, 'running': 0, 'sleeping': 0, 'thread': 0} + self.processcount = {'total': 0, 'running': 0, 'sleeping': 0, 'thread': 0} # Tag to enable/disable the processes stats (to reduce the Glances CPU consumption) # Default is to enable the processes stats @@ -254,13 +273,12 @@ class GlancesProcesses(object): # Extended stats for top process is enable by default self.disable_extended_tag = False - # Maximum number of processes showed in the UI interface - # None if no limit - self.max_processes = None + # Maximum number of processes showed in the UI (None if no limit) + self._max_processes = None # Process filter is a regular expression - self.process_filter = None - self.process_filter_re = None + self._process_filter = None + self._process_filter_re = None # Whether or not to hide kernel threads self.no_kernel_threads = False @@ -283,255 +301,279 @@ class GlancesProcesses(object): """Disable extended process stats.""" self.disable_extended_tag = True - def set_max_processes(self, value): - """Set the maximum number of processes showed in the UI interfaces""" - self.max_processes = value - return self.max_processes + @property + def max_processes(self): + """Get the maximum number of processes showed in the UI.""" + return self._max_processes - def get_max_processes(self): - """Get the maximum number of processes showed in the UI interfaces""" - return self.max_processes + @max_processes.setter + def max_processes(self, value): + """Set the maximum number of processes showed in the UI.""" + self._max_processes = value - def set_process_filter(self, value): - """Set the process filter""" + @property + def process_filter(self): + """Get the process filter.""" + return self._process_filter + + @process_filter.setter + def process_filter(self, value): + """Set the process filter.""" logger.info("Set process filter to {0}".format(value)) - self.process_filter = value + self._process_filter = value if value is not None: try: - self.process_filter_re = re.compile(value) - logger.debug("Process filter regex compilation OK: {0}".format(self.get_process_filter())) + self._process_filter_re = re.compile(value) + logger.debug("Process filter regex compilation OK: {0}".format(self.process_filter)) except Exception: logger.error("Cannot compile process filter regex: {0}".format(value)) - self.process_filter_re = None + self._process_filter_re = None else: - self.process_filter_re = None - return self.process_filter + self._process_filter_re = None - def get_process_filter(self): - """Get the process filter""" - return self.process_filter - - def get_process_filter_re(self): - """Get the process regular expression compiled""" - return self.process_filter_re + @property + def process_filter_re(self): + """Get the process regular expression compiled.""" + return self._process_filter_re def is_filtered(self, value): - """Return True if the value should be filtered""" - if self.get_process_filter() is None: + """Return True if the value should be filtered.""" + if self.process_filter is None: # No filter => Not filtered return False else: - # logger.debug(self.get_process_filter() + " <> " + value + " => " + str(self.get_process_filter_re().match(value) is None)) - return self.get_process_filter_re().match(value) is None + # logger.debug(self.process_filter + " <> " + value + " => " + str(self.process_filter_re.match(value) is None)) + return self.process_filter_re.match(value) is None def disable_kernel_threads(self): - """ Ignore kernel threads in process list. """ + """Ignore kernel threads in process list.""" self.no_kernel_threads = True def enable_tree(self): - """ Enable process tree. """ + """Enable process tree.""" self._enable_tree = True def is_tree_enabled(self): - """ Return True if process tree is enabled, False instead. """ + """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. + + => cpu_percent, memory_percent, io_counters, name, cmdline + """ + procstat['mandatory_stats'] = True + + # Process CPU, MEM percent and name + 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 + return None + + # Process command line (cached with internal cache) + try: + self.cmdline_cache[procstat['pid']] + except KeyError: + # Patch for issue #391 + try: + self.cmdline_cache[ + procstat['pid']] = ' '.join(proc.cmdline()) + except (AttributeError, UnicodeDecodeError, psutil.AccessDenied, psutil.NoSuchProcess): + self.cmdline_cache[procstat['pid']] = "" + procstat['cmdline'] = self.cmdline_cache[procstat['pid']] + + # Process IO + # procstat['io_counters'] is a list: + # [read_bytes, write_bytes, read_bytes_old, write_bytes_old, io_tag] + # If io_tag = 0 > Access denied (display "?") + # If io_tag = 1 > No access denied (display the IO rate) + # Note Disk IO stat not available on Mac OS + if not is_mac: + try: + # Get the process IO counters + proc_io = proc.io_counters() + io_new = [proc_io.read_bytes, proc_io.write_bytes] + except (psutil.AccessDenied, psutil.NoSuchProcess, NotImplementedError): + # Access denied to process IO (no root account) + # NoSuchProcess (process die between first and second grab) + # Put 0 in all values (for sort) and io_tag = 0 (for + # display) + procstat['io_counters'] = [0, 0] + [0, 0] + io_tag = 0 + else: + # For IO rate computation + # Append saved IO r/w bytes + try: + procstat['io_counters'] = io_new + \ + self.io_old[procstat['pid']] + except KeyError: + procstat['io_counters'] = io_new + [0, 0] + # then save the IO r/w bytes + self.io_old[procstat['pid']] = io_new + io_tag = 1 + + # Append the IO tag (for display) + procstat['io_counters'] += [io_tag] + + return procstat + + def __get_standard_stats(self, proc, procstat): + """ + Get standard_stats: for all the displayed processes. + + => username, status, memory_info, cpu_times + """ + procstat['standard_stats'] = True + + # Process username (cached with internal cache) + try: + self.username_cache[procstat['pid']] + except KeyError: + try: + self.username_cache[procstat['pid']] = proc.username() + except psutil.NoSuchProcess: + self.username_cache[procstat['pid']] = "?" + except (KeyError, psutil.AccessDenied): + try: + self.username_cache[procstat['pid']] = proc.uids().real + except (KeyError, AttributeError, psutil.AccessDenied): + self.username_cache[procstat['pid']] = "?" + procstat['username'] = self.username_cache[procstat['pid']] + + # Process status, nice, memory_info and cpu_times + try: + procstat.update( + proc.as_dict(attrs=['status', 'nice', 'memory_info', 'cpu_times'])) + except psutil.NoSuchProcess: + pass + else: + procstat['status'] = str(procstat['status'])[:1].upper() + + return procstat + + def __get_extended_stats(self, proc, procstat): + """ + Get extended_stats: only for top processes (see issue #403). + + => connections (UDP/TCP), memory_swap... + """ + procstat['extended_stats'] = True + + # CPU affinity (Windows and Linux only) + try: + procstat.update(proc.as_dict(attrs=['cpu_affinity'])) + except psutil.NoSuchProcess: + pass + except AttributeError: + procstat['cpu_affinity'] = None + # Memory extended + try: + procstat.update(proc.as_dict(attrs=['memory_info_ex'])) + except psutil.NoSuchProcess: + pass + except AttributeError: + procstat['memory_info_ex'] = None + # Number of context switch + try: + procstat.update(proc.as_dict(attrs=['num_ctx_switches'])) + except psutil.NoSuchProcess: + pass + except AttributeError: + procstat['num_ctx_switches'] = None + # Number of file descriptors (Unix only) + try: + procstat.update(proc.as_dict(attrs=['num_fds'])) + except psutil.NoSuchProcess: + pass + except AttributeError: + procstat['num_fds'] = None + # Threads number + try: + procstat.update(proc.as_dict(attrs=['num_threads'])) + except psutil.NoSuchProcess: + pass + except AttributeError: + procstat['num_threads'] = None + + # Number of handles (Windows only) + if is_windows: + try: + procstat.update(proc.as_dict(attrs=['num_handles'])) + except psutil.NoSuchProcess: + pass + else: + procstat['num_handles'] = None + + # SWAP memory (Only on Linux based OS) + # http://www.cyberciti.biz/faq/linux-which-process-is-using-swap/ + if is_linux: + try: + procstat['memory_swap'] = sum( + [v.swap for v in proc.memory_maps()]) + except psutil.NoSuchProcess: + pass + except psutil.AccessDenied: + procstat['memory_swap'] = None + except Exception: + # Add a dirty except to handle the PsUtil issue #413 + procstat['memory_swap'] = None + + # Process network connections (TCP and UDP) + try: + procstat['tcp'] = len(proc.connections(kind="tcp")) + procstat['udp'] = len(proc.connections(kind="udp")) + except Exception: + procstat['tcp'] = None + procstat['udp'] = None + + # IO Nice + # http://pythonhosted.org/psutil/#psutil.Process.ionice + if is_linux or is_windows: + try: + procstat.update(proc.as_dict(attrs=['ionice'])) + except psutil.NoSuchProcess: + pass + else: + procstat['ionice'] = None + + return procstat + def __get_process_stats(self, proc, mandatory_stats=True, standard_stats=True, extended_stats=False): - """ - Get process stats of the proc processes (proc is returned psutil.process_iter()) - mandatory_stats: need for the sorting/filter step - => cpu_percent, memory_percent, io_counters, name, cmdline - standard_stats: for all the displayed processes - => username, status, memory_info, cpu_times - extended_stats: only for top processes (see issue #403) - => connections (UDP/TCP), memory_swap... - """ - + """Get stats of running processes.""" # Process ID (always) procstat = proc.as_dict(attrs=['pid']) if mandatory_stats: - procstat['mandatory_stats'] = True + procstat = self.__get_mandatory_stats(proc, procstat) - # Process CPU, MEM percent and name - try: - procstat.update( - proc.as_dict(attrs=['cpu_percent', 'memory_percent', 'name', 'cpu_times'], ad_value='')) - except psutil.NoSuchProcess: - # Correct issue #414 - return None - if procstat['cpu_percent'] == '' or procstat['memory_percent'] == '': - # Do not display process if we cannot get the basic - # cpu_percent or memory_percent stats - return None + if procstat is not None and standard_stats: + procstat = self.__get_standard_stats(proc, procstat) - # Process command line (cached with internal cache) - try: - self.cmdline_cache[procstat['pid']] - except KeyError: - # Patch for issue #391 - try: - self.cmdline_cache[ - procstat['pid']] = ' '.join(proc.cmdline()) - except (AttributeError, UnicodeDecodeError, psutil.AccessDenied, psutil.NoSuchProcess): - self.cmdline_cache[procstat['pid']] = "" - procstat['cmdline'] = self.cmdline_cache[procstat['pid']] - - # Process IO - # procstat['io_counters'] is a list: - # [read_bytes, write_bytes, read_bytes_old, write_bytes_old, io_tag] - # If io_tag = 0 > Access denied (display "?") - # If io_tag = 1 > No access denied (display the IO rate) - # Note Disk IO stat not available on Mac OS - if not is_mac: - try: - # Get the process IO counters - proc_io = proc.io_counters() - io_new = [proc_io.read_bytes, proc_io.write_bytes] - except (psutil.AccessDenied, psutil.NoSuchProcess): - # Access denied to process IO (no root account) - # NoSuchProcess (process die between first and second grab) - # Put 0 in all values (for sort) and io_tag = 0 (for - # display) - procstat['io_counters'] = [0, 0] + [0, 0] - io_tag = 0 - else: - # For IO rate computation - # Append saved IO r/w bytes - try: - procstat['io_counters'] = io_new + \ - self.io_old[procstat['pid']] - except KeyError: - procstat['io_counters'] = io_new + [0, 0] - # then save the IO r/w bytes - self.io_old[procstat['pid']] = io_new - io_tag = 1 - - # Append the IO tag (for display) - procstat['io_counters'] += [io_tag] - - if standard_stats: - procstat['standard_stats'] = True - - # Process username (cached with internal cache) - try: - self.username_cache[procstat['pid']] - except KeyError: - try: - self.username_cache[procstat['pid']] = proc.username() - except psutil.NoSuchProcess: - self.username_cache[procstat['pid']] = "?" - except (KeyError, psutil.AccessDenied): - try: - self.username_cache[procstat['pid']] = proc.uids().real - except (KeyError, AttributeError, psutil.AccessDenied): - self.username_cache[procstat['pid']] = "?" - procstat['username'] = self.username_cache[procstat['pid']] - - # Process status, nice, memory_info and cpu_times - try: - procstat.update( - proc.as_dict(attrs=['status', 'nice', 'memory_info', 'cpu_times'])) - except psutil.NoSuchProcess: - pass - else: - procstat['status'] = str(procstat['status'])[:1].upper() - - if extended_stats and not self.disable_extended_tag: - procstat['extended_stats'] = True - - # CPU affinity (Windows and Linux only) - try: - procstat.update(proc.as_dict(attrs=['cpu_affinity'])) - except psutil.NoSuchProcess: - pass - except AttributeError: - procstat['cpu_affinity'] = None - # Memory extended - try: - procstat.update(proc.as_dict(attrs=['memory_info_ex'])) - except psutil.NoSuchProcess: - pass - except AttributeError: - procstat['memory_info_ex'] = None - # Number of context switch - try: - procstat.update(proc.as_dict(attrs=['num_ctx_switches'])) - except psutil.NoSuchProcess: - pass - except AttributeError: - procstat['num_ctx_switches'] = None - # Number of file descriptors (Unix only) - try: - procstat.update(proc.as_dict(attrs=['num_fds'])) - except psutil.NoSuchProcess: - pass - except AttributeError: - procstat['num_fds'] = None - # Threads number - try: - procstat.update(proc.as_dict(attrs=['num_threads'])) - except psutil.NoSuchProcess: - pass - except AttributeError: - procstat['num_threads'] = None - - # Number of handles (Windows only) - if is_windows: - try: - procstat.update(proc.as_dict(attrs=['num_handles'])) - except psutil.NoSuchProcess: - pass - else: - procstat['num_handles'] = None - - # SWAP memory (Only on Linux based OS) - # http://www.cyberciti.biz/faq/linux-which-process-is-using-swap/ - if is_linux: - try: - procstat['memory_swap'] = sum( - [v.swap for v in proc.memory_maps()]) - except psutil.NoSuchProcess: - pass - except psutil.AccessDenied: - procstat['memory_swap'] = None - except Exception: - # Add a dirty except to handle the PsUtil issue #413 - procstat['memory_swap'] = None - - # Process network connections (TCP and UDP) - try: - procstat['tcp'] = len(proc.connections(kind="tcp")) - procstat['udp'] = len(proc.connections(kind="udp")) - except Exception: - procstat['tcp'] = None - procstat['udp'] = None - - # IO Nice - # http://pythonhosted.org/psutil/#psutil.Process.ionice - if is_linux or is_windows: - try: - procstat.update(proc.as_dict(attrs=['ionice'])) - except psutil.NoSuchProcess: - pass - else: - procstat['ionice'] = None - - # logger.debug(procstat) + if procstat is not None and extended_stats and not self.disable_extended_tag: + procstat = self.__get_extended_stats(proc, procstat) return procstat def update(self): - """ - Update the processes stats - """ + """Update the processes stats.""" # Reset the stats self.processlist = [] - self.processcount = { - 'total': 0, 'running': 0, 'sleeping': 0, 'thread': 0} + self.processcount = {'total': 0, 'running': 0, 'sleeping': 0, 'thread': 0} # Do not process if disable tag is set if self.disable_tag: @@ -544,15 +586,14 @@ class GlancesProcesses(object): processdict = {} for proc in psutil.process_iter(): # Ignore kernel threads if needed - if (self.no_kernel_threads and (not is_windows) - and is_kernel_thread(proc)): + if self.no_kernel_threads and not is_windows and is_kernel_thread(proc): continue - # If self.get_max_processes() is None: Only retreive mandatory stats + # If self.max_processes is None: Only retreive mandatory stats # Else: retreive mandatory and standard stats s = self.__get_process_stats(proc, mandatory_stats=True, - standard_stats=self.get_max_processes() is None) + standard_stats=self.max_processes is None) # Continue to the next process if it has to be filtered if s is None or (self.is_filtered(s['cmdline']) and self.is_filtered(s['name'])): continue @@ -586,12 +627,13 @@ class GlancesProcesses(object): if self._enable_tree: self.process_tree = ProcessTreeNode.build_tree(processdict, - self.getsortkey(), + self.sort_key, + self.sort_reverse, self.no_kernel_threads) for i, node in enumerate(self.process_tree): - # Only retreive stats for visible processes (get_max_processes) - if (self.get_max_processes() is not None) and (i >= self.get_max_processes()): + # Only retreive stats for visible processes (max_processes) + if self.max_processes is not None and i >= self.max_processes: break # add standard stats @@ -607,30 +649,32 @@ class GlancesProcesses(object): else: # Process optimization - # Only retreive stats for visible processes (get_max_processes) - if self.get_max_processes() is not None: + # Only retreive stats for visible processes (max_processes) + if self.max_processes is not None: # 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.getsortkey()], 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 %s (%s)" % (self.getsortkey(), e)) + logger.error("Cannot sort process list by {0}: {1}".format(self.sort_key, e)) logger.error("%s" % str(processdict.items()[0])) # Fallback to all process (issue #423) processloop = processdict.items() first = False else: - processloop = processiter[0:self.get_max_processes()] + processloop = processiter[0:self.max_processes] first = True else: # Get all processes stats processloop = processdict.items() first = False + for i in processloop: # Already existing mandatory stats procstat = i[1] - if self.get_max_processes() is not None: + if self.max_processes is not None: # Update with standard stats # and extended stats but only for TOP (first) process s = self.__get_process_stats(i[0], @@ -647,6 +691,9 @@ class GlancesProcesses(object): # Next... first = False + # Build the all processes list used by the monitored list + self.allprocesslist = processdict.values() + # Clean internals caches if timeout is reached if self.cache_timer.finished(): self.username_cache = {} @@ -658,6 +705,10 @@ class GlancesProcesses(object): """Get the number of processes.""" return self.processcount + def getalllist(self): + """Get the allprocesslist.""" + return self.allprocesslist + def getlist(self, sortedby=None): """Get the processlist.""" return self.processlist @@ -666,65 +717,14 @@ class GlancesProcesses(object): """Get the process tree.""" return self.process_tree - def getsortkey(self): - """Get the current sort key""" - if self.getmanualsortkey() is not None: - return self.getmanualsortkey() - else: - return self.getautosortkey() + @property + def sort_key(self): + """Get the current sort key.""" + return self._sort_key - def getmanualsortkey(self): - """Get the current sort key for manual sort.""" - return self.processmanualsort - - def getautosortkey(self): - """Get the current sort key for automatic sort.""" - return self.processautosort - - def setmanualsortkey(self, sortedby): - """Set the current sort key for manual sort.""" - self.processmanualsort = sortedby - if self._enable_tree and (self.process_tree is not None): - self.process_tree.set_sorting(sortedby, sortedby != "name") - return self.processmanualsort - - def setautosortkey(self, sortedby): - """Set the current sort key for automatic sort.""" - self.processautosort = sortedby - return self.processautosort - - def resetsort(self): - """Set the default sort: Auto""" - self.setmanualsortkey(None) - self.setautosortkey('cpu_percent') - - 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 + @sort_key.setter + def sort_key(self, key): + """Set the current sort key.""" + self._sort_key = key glances_processes = GlancesProcesses() diff --git a/glances/core/glances_server.py b/glances/core/glances_server.py index 6cf8176a..420b2221 100644 --- a/glances/core/glances_server.py +++ b/glances/core/glances_server.py @@ -100,7 +100,7 @@ class GlancesXMLRPCHandler(SimpleXMLRPCRequestHandler): self.send_error(401, 'Authentication failed') return False - def log_message(self, format, *args): + def log_message(self, log_format, *args): # No message displayed on the server side pass diff --git a/glances/core/glances_snmp.py b/glances/core/glances_snmp.py index 95e1e602..20569a55 100644 --- a/glances/core/glances_snmp.py +++ b/glances/core/glances_snmp.py @@ -50,7 +50,7 @@ class GlancesSNMPClient(object): self.auth = auth def __buid_result(self, varBinds): - """Build the results""" + """Build the results.""" ret = {} for name, val in varBinds: if str(val) == '': diff --git a/glances/core/glances_standalone.py b/glances/core/glances_standalone.py index 50170a97..e5cca2d9 100644 --- a/glances/core/glances_standalone.py +++ b/glances/core/glances_standalone.py @@ -19,6 +19,8 @@ """Manage the Glances standalone session.""" +from time import sleep + # Import Glances libs from glances.core.glances_globals import is_windows from glances.core.glances_logging import logger @@ -32,15 +34,16 @@ class GlancesStandalone(object): """This class creates and manages the Glances standalone session.""" def __init__(self, config=None, args=None): + # Quiet mode + self._quiet = args.quiet + self.refresh_time = args.time + # Init stats self.stats = GlancesStats(config=config, args=args) - # Default number of processes to displayed is set to 50 - glances_processes.set_max_processes(50) - # If process extended stats is disabled by user if not args.enable_process_extended: - logger.info("Extended stats for top process are disabled (default behavior)") + logger.debug("Extended stats for top process are disabled") glances_processes.disable_extended() else: logger.debug("Extended stats for top process are enabled") @@ -48,37 +51,68 @@ class GlancesStandalone(object): # Manage optionnal process filter if args.process_filter is not None: - glances_processes.set_process_filter(args.process_filter) + glances_processes.process_filter = args.process_filter if (not is_windows) and args.no_kernel_threads: # Ignore kernel threads in process list glances_processes.disable_kernel_threads() - if args.process_tree: - # Enable process tree view - glances_processes.enable_tree() + try: + if args.process_tree: + # Enable process tree view + glances_processes.enable_tree() + except AttributeError: + pass # Initial system informations update self.stats.update() - # Init screen - self.screen = GlancesCursesStandalone(args=args) + if self.quiet: + logger.info("Quiet mode is ON: Nothing will be displayed") + # In quiet mode, nothing is displayed + glances_processes.max_processes = 0 + else: + # Default number of processes to displayed is set to 50 + glances_processes.max_processes = 50 - def serve_forever(self): + # Init screen + self.screen = GlancesCursesStandalone(args=args) + + @property + def quiet(self): + return self._quiet + + def __serve_forever(self): """Main loop for the CLI.""" while True: # Update system informations self.stats.update() - # Update the screen - self.screen.update(self.stats) + if not self.quiet: + # Update the screen + self.screen.update(self.stats) + else: + # Wait... + sleep(self.refresh_time) # 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.""" - self.screen.end() + if not self.quiet: + self.screen.end() # Exit from export modules self.stats.end() diff --git a/glances/core/glances_staticlist.py b/glances/core/glances_staticlist.py index 1ff942a7..e754552e 100644 --- a/glances/core/glances_staticlist.py +++ b/glances/core/glances_staticlist.py @@ -17,7 +17,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -"""Manage the Glances server static list """ +"""Manage the Glances server static list.""" # System lib from socket import gaierror, gethostbyname @@ -28,7 +28,7 @@ from glances.core.glances_logging import logger class GlancesStaticServer(object): - """Manage the static servers list for the client browser""" + """Manage the static servers list for the client browser.""" _section = "serverlist" @@ -39,8 +39,7 @@ class GlancesStaticServer(object): self._server_list = self.load(config) def load(self, config): - """Load the server list from the configuration file""" - + """Load the server list from the configuration file.""" server_list = [] if config is None: @@ -54,7 +53,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: @@ -85,9 +84,9 @@ class GlancesStaticServer(object): return server_list def get_servers_list(self): - """Return the current server list (dict of dict)""" + """Return the current server list (dict of dict).""" return self._server_list def set_server(self, server_pos, key, value): - """Set the key to the value for the server_pos (position in the list)""" + """Set the key to the value for the server_pos (position in the list).""" self._server_list[server_pos][key] = value diff --git a/glances/core/glances_stats.py b/glances/core/glances_stats.py index 8b92334f..1f039eb6 100644 --- a/glances/core/glances_stats.py +++ b/glances/core/glances_stats.py @@ -25,7 +25,7 @@ import re import sys import threading -from glances.core.glances_globals import plugins_path, exports_path, sys_path +from glances.core.glances_globals import exports_path, plugins_path, sys_path from glances.core.glances_logging import logger # SNMP OID regexp pattern to short system name dict @@ -152,13 +152,17 @@ class GlancesStats(object): # For standalone and server modes # For each plugins, call the update method for p in self._plugins: - # logger.debug("Update %s stats" % p) + # logger.debug("Update %s stats" % p) self._plugins[p].update() - def export(self, input_stats={}): + def export(self, input_stats=None): """Export all the stats. - Each export module is ran in a dedicated thread.""" + + Each export module is ran in a dedicated thread. + """ # threads = [] + input_stats = input_stats or {} + for e in self._exports: logger.debug("Export stats using the %s module" % e) thread = threading.Thread(target=self._exports[e].update, @@ -167,11 +171,11 @@ class GlancesStats(object): thread.start() def getAll(self): - """Return all the stats (list)""" + """Return all the stats (list).""" return [self._plugins[p].get_raw() for p in self._plugins] def getAllAsDict(self): - """Return all the stats (dict)""" + """Return all the stats (dict).""" # Python > 2.6 # {p: self._plugins[p].get_raw() for p in self._plugins} ret = {} @@ -181,21 +185,21 @@ class GlancesStats(object): def getAllLimits(self): """Return the plugins limits list.""" - return [self._plugins[p].get_limits() for p in self._plugins] + return [self._plugins[p].limits for p in self._plugins] def getAllLimitsAsDict(self): - """Return all the stats limits (dict)""" + """Return all the stats limits (dict).""" ret = {} for p in self._plugins: - ret[p] = self._plugins[p].get_limits() + ret[p] = self._plugins[p].limits return ret def getAllViews(self): - """Return the plugins views""" + """Return the plugins views.""" return [self._plugins[p].get_views() for p in self._plugins] def getAllViewsAsDict(self): - """Return all the stats views (dict)""" + """Return all the stats views (dict).""" ret = {} for p in self._plugins: ret[p] = self._plugins[p].get_views() @@ -203,7 +207,7 @@ class GlancesStats(object): def get_plugin_list(self): """Return the plugin list.""" - self._plugins + return self._plugins def get_plugin(self, plugin_name): """Return the plugin name.""" @@ -213,7 +217,7 @@ class GlancesStats(object): return None def end(self): - """End of the Glances stats""" + """End of the Glances stats.""" # Close the export module for e in self._exports: self._exports[e].exit() @@ -231,8 +235,10 @@ class GlancesStatsServer(GlancesStats): # all_stats is a dict of dicts filled by the server self.all_stats = collections.defaultdict(dict) - def update(self, input_stats={}): + def update(self, input_stats=None): """Update the stats.""" + input_stats = input_stats or {} + # Force update of all the stats GlancesStats.update(self) @@ -240,7 +246,7 @@ class GlancesStatsServer(GlancesStats): self.all_stats = self._set_stats(input_stats) def _set_stats(self, input_stats): - """Set the stats to the input_stats one""" + """Set the stats to the input_stats one.""" # Build the all_stats with the get_raw() method of the plugins ret = collections.defaultdict(dict) for p in self._plugins: @@ -248,11 +254,11 @@ class GlancesStatsServer(GlancesStats): return ret def getAll(self): - """Return the stats as a list""" + """Return the stats as a list.""" return self.all_stats def getAllAsDict(self): - """Return the stats as a dict""" + """Return the stats as a dict.""" # Python > 2.6 # return {p: self.all_stats[p] for p in self._plugins} ret = {} @@ -359,7 +365,7 @@ class GlancesStatsClientSNMP(GlancesStats): return ret def get_system_name(self, oid_system_name): - """Get the short os name from the OS name OID string""" + """Get the short os name from the OS name OID string.""" short_system_name = None if oid_system_name == '': @@ -383,7 +389,8 @@ class GlancesStatsClientSNMP(GlancesStats): # For each plugins, call the update method for p in self._plugins: # Set the input method to SNMP - self._plugins[p].set_input('snmp', self.system_name) + self._plugins[p].input_method = 'snmp' + self._plugins[p].short_system_name = self.system_name try: self._plugins[p].update() except Exception as e: diff --git a/glances/core/glances_webserver.py b/glances/core/glances_webserver.py index 39c477cc..49bc4744 100644 --- a/glances/core/glances_webserver.py +++ b/glances/core/glances_webserver.py @@ -34,7 +34,7 @@ class GlancesWebServer(object): # Init stats self.stats = GlancesStats(config) - if (not is_windows) and args.no_kernel_threads: + if not is_windows and args.no_kernel_threads: # Ignore kernel threads in process list glances_processes.disable_kernel_threads() diff --git a/glances/exports/glances_csv.py b/glances/exports/glances_csv.py index 2b450027..54ea65c6 100644 --- a/glances/exports/glances_csv.py +++ b/glances/exports/glances_csv.py @@ -72,27 +72,26 @@ class Export(GlancesExport): plugins = stats.getAllPlugins() # Loop over available plugin - i = 0 - for plugin in plugins: + for i, plugin in enumerate(plugins): if plugin in self.plugins_to_export(): - if type(all_stats[i]) is list: - for item in all_stats[i]: + if isinstance(all_stats[i], list): + for stat in all_stats[i]: # First line: header if self.first_line: - fieldnames = item.keys() - csv_header += map(lambda x: plugin+'_'+item[item['key']]+'_'+x, item) + csv_header += ('{0}_{1}_{2}'.format( + plugin, stat[stat['key']], item) for item in stat) # Others lines: stats - fieldvalues = item.values() + fieldvalues = stat.values() csv_data += fieldvalues - elif type(all_stats[i]) is dict: + elif isinstance(all_stats[i], dict): # First line: header if self.first_line: fieldnames = all_stats[i].keys() - csv_header += map(lambda x: plugin+'_'+x, fieldnames) + csv_header += ('{0}_{1}'.format(plugin, fieldname) + for fieldname in fieldnames) # Others lines: stats fieldvalues = all_stats[i].values() csv_data += fieldvalues - i += 1 # Export to CSV if self.first_line: diff --git a/glances/exports/glances_export.py b/glances/exports/glances_export.py index a8681a64..3bf050b3 100644 --- a/glances/exports/glances_export.py +++ b/glances/exports/glances_export.py @@ -32,7 +32,7 @@ from glances.core.glances_logging import logger class GlancesExport(object): - """Main class for Glances' export IF.""" + """Main class for Glances export IF.""" def __init__(self, config=None, args=None): """Init the export class.""" @@ -53,34 +53,47 @@ class GlancesExport(object): logger.debug("Finalise export interface %s" % self.export_name) def plugins_to_export(self): - """Return the list of plugins to export""" - return ['cpu', 'load', 'mem', 'memswap', 'network', 'diskio', 'fs', 'processcount'] + """Return the list of plugins to export.""" + return ['cpu', + 'percpu', + 'load', + 'mem', + 'memswap', + 'network', + 'diskio', + 'fs', + 'processcount', + 'ip', + 'system', + 'uptime'] def update(self, stats): """Update stats to a server. - The method buil two list: names and values - and call the export method to export the stats""" + + The method builds two lists: names and values + and calls the export method to export the stats. + """ if not self.export_enable: return False # Get the stats all_stats = stats.getAll() + all_limits = stats.getAllLimits() plugins = stats.getAllPlugins() - # Loop over available plugin - i = 0 - for plugin in plugins: + # Loop over available plugins + for i, plugin in enumerate(plugins): if plugin in self.plugins_to_export(): - if type(all_stats[i]) is list: + if isinstance(all_stats[i], list): for item in all_stats[i]: - export_names = map( - lambda x: item[item['key']] + '.' + x, item.keys()) - export_values = item.values() + item.update(all_limits[i]) + export_names = list('{0}.{1}'.format(item[item['key']], key) + for key in item.keys()) + export_values = list(item.values()) self.export(plugin, export_names, export_values) - elif type(all_stats[i]) is dict: - export_names = all_stats[i].keys() - export_values = all_stats[i].values() + elif isinstance(all_stats[i], dict): + export_names = list(all_stats[i].keys()) + list(all_limits[i].keys()) + export_values = list(all_stats[i].values()) + list(all_limits[i].values()) self.export(plugin, export_names, export_values) - i += 1 return True diff --git a/glances/exports/glances_history.py b/glances/exports/glances_history.py index 674bdb5c..6caaf353 100644 --- a/glances/exports/glances_history.py +++ b/glances/exports/glances_history.py @@ -39,23 +39,21 @@ else: class GlancesHistory(object): - """This class define the object to manage stats history""" + """This class define the object to manage stats history.""" def __init__(self, output_folder): self.output_folder = output_folder def get_output_folder(self): - """Return the output folder where the graph are generated""" + """Return the output folder where the graph are generated.""" return self.output_folder def graph_enabled(self): - """Return True if Glances can generaate history graphs""" + """Return True if Glances can generate history graphs.""" return matplotlib_check def reset(self, stats): - """ - Reset all the history - """ + """Reset all the history.""" if not self.graph_enabled(): return False for p in stats.getAllPlugins(): @@ -65,9 +63,7 @@ class GlancesHistory(object): return True def get_graph_color(self, item): - """ - Get the item's color - """ + """Get the item's color.""" try: ret = item['color'] except KeyError: @@ -76,15 +72,11 @@ class GlancesHistory(object): return ret def get_graph_legend(self, item): - """ - Get the item's legend - """ + """Get the item's legend.""" return item['name'] def get_graph_yunit(self, item, pre_label=''): - """ - Get the item's Y unit - """ + """Get the item's Y unit.""" try: unit = " (%s)" % item['y_unit'] except KeyError: @@ -96,9 +88,9 @@ class GlancesHistory(object): return "%s%s" % (label, unit) def generate_graph(self, stats): - """ - Generate graphs from plugins history - Return the number of output files generated by the function + """Generate graphs from plugins history. + + Return the number of output files generated by the function. """ if not self.graph_enabled(): return 0 @@ -176,8 +168,7 @@ class GlancesHistory(object): fig.set_size_inches(20, 10) plt.legend(handles, labels, loc=1, prop={'size': 9}) plt.xlabel('Date') - plt.savefig( - os.path.join(self.output_folder, 'glances_%s.png' % (p)), dpi=72) + plt.savefig(os.path.join(self.output_folder, 'glances_%s.png' % p), dpi=72) index_all += 1 plt.close() diff --git a/glances/exports/glances_influxdb.py b/glances/exports/glances_influxdb.py index 60b9c1ee..36a3395f 100644 --- a/glances/exports/glances_influxdb.py +++ b/glances/exports/glances_influxdb.py @@ -20,14 +20,21 @@ """InfluxDB interface class.""" # Import sys libs -from influxdb import InfluxDBClient, client import sys +try: + from configparser import NoOptionError, NoSectionError +except ImportError: # Python 2 + from ConfigParser import NoOptionError, NoSectionError # Import Glances lib from glances.core.glances_logging import logger -from ConfigParser import NoSectionError, NoOptionError from glances.exports.glances_export import GlancesExport +from influxdb import InfluxDBClient +from influxdb.client import InfluxDBClientError +from influxdb.influxdb08 import InfluxDBClient as InfluxDBClient08 +from influxdb.influxdb08.client import InfluxDBClientError as InfluxDBClientError08 + class Export(GlancesExport): @@ -38,11 +45,12 @@ class Export(GlancesExport): GlancesExport.__init__(self, config=config, args=args) # Load the InfluxDB configuration file - self.influxdb_host = None - self.influxdb_port = None - self.influxdb_user = None - self.influxdb_password = None - self.influxdb_db = None + self.host = None + self.port = None + self.user = None + self.password = None + self.db = None + self.prefix = None self.export_enable = self.load_conf() if not self.export_enable: sys.exit(2) @@ -51,15 +59,15 @@ class Export(GlancesExport): self.client = self.init() def load_conf(self, section="influxdb"): - """Load the InfluxDb configuration in the Glances configuration file""" + """Load the InfluxDb configuration in the Glances configuration file.""" if self.config is None: return False try: - self.influxdb_host = self.config.get_raw_option(section, "host") - self.influxdb_port = self.config.get_raw_option(section, "port") - self.influxdb_user = self.config.get_raw_option(section, "user") - self.influxdb_password = self.config.get_raw_option(section, "password") - self.influxdb_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 @@ -68,39 +76,55 @@ class Export(GlancesExport): return False else: logger.debug("Load InfluxDB from the Glances configuration file") + # Prefix is optional + try: + self.prefix = self.config.get_value(section, 'prefix') + except NoOptionError: + pass return True def init(self): - """Init the connection to the InfluxDB server""" + """Init the connection to the InfluxDB server.""" if not self.export_enable: return None - db = InfluxDBClient(self.influxdb_host, - self.influxdb_port, - self.influxdb_user, - self.influxdb_password, - self.influxdb_db) + try: - get_all_db = db.get_database_list()[0].values() - except client.InfluxDBClientError as e: - logger.critical("Can not connect to InfluxDB database '%s' (%s)" % (self.influxdb_db, e)) + db = InfluxDBClient(host=self.host, + port=self.port, + username=self.user, + password=self.password, + database=self.db) + get_all_db = [i['name'] for i in db.get_list_database()] + except InfluxDBClientError: + # https://github.com/influxdb/influxdb-python/issues/138 + logger.info("Trying fallback to InfluxDB v0.8") + db = InfluxDBClient08(host=self.host, + port=self.port, + username=self.user, + password=self.password, + database=self.db) + get_all_db = [i['name'] for i in db.get_list_database()] + except InfluxDBClientError08 as e: + logger.critical("Cannot connect to InfluxDB database '%s' (%s)" % (self.db, e)) sys.exit(2) - if self.influxdb_db in get_all_db: + if self.db in get_all_db: logger.info( "Stats will be exported to InfluxDB server: {0}".format(db._baseurl)) else: - logger.critical("InfluxDB database '%s' did not exist. Please create it" % self.influxdb_db) + logger.critical("InfluxDB database '%s' did not exist. Please create it" % self.db) sys.exit(2) return db def export(self, name, columns, points): - """Write the points to the InfluxDB server""" - data = [ - { - "name": name, - "columns": columns, - "points": [points] - }] + """Write the points to the InfluxDB server.""" + # Manage prefix + if self.prefix is not None: + name = self.prefix + '.' + name + # logger.info(self.prefix) + # Create DB input + data = [{'name': name, 'columns': columns, 'points': [points]}] + # Write input to the InfluxDB database try: self.client.write_points(data) except Exception as e: diff --git a/glances/exports/glances_rabbitmq.py b/glances/exports/glances_rabbitmq.py new file mode 100644 index 00000000..c859ff30 --- /dev/null +++ b/glances/exports/glances_rabbitmq.py @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- +# +# This file is part of Glances. +# +# Copyright (C) 2015 Nicolargo +# +# 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 . + +"""JMS interface class.""" + +# Import sys libs +import datetime +import socket +import sys +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) diff --git a/glances/exports/glances_statsd.py b/glances/exports/glances_statsd.py index 982a9bfb..bd6eefd0 100644 --- a/glances/exports/glances_statsd.py +++ b/glances/exports/glances_statsd.py @@ -20,15 +20,19 @@ """Statsd interface class.""" # Import sys libs -from statsd import StatsClient -from numbers import Number import sys +from numbers import Number +try: + from configparser import NoOptionError, NoSectionError +except ImportError: # Python 2 + from ConfigParser import NoOptionError, NoSectionError # Import Glances lib from glances.core.glances_logging import logger -from ConfigParser import NoSectionError, NoOptionError from glances.exports.glances_export import GlancesExport +from statsd import StatsClient + class Export(GlancesExport): @@ -56,12 +60,12 @@ class Export(GlancesExport): prefix=self.prefix) def load_conf(self, section="statsd"): - """Load the Statsd configuration in the Glances configuration file""" + """Load the Statsd configuration in the Glances configuration file.""" 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 @@ -72,13 +76,13 @@ 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") - except NoOptionError as e: + self.prefix = self.config.get_value(section, 'prefix') + except NoOptionError: pass return True def init(self, prefix='glances'): - """Init the connection to the Statsd server""" + """Init the connection to the Statsd server.""" if not self.export_enable: return None return StatsClient(self.host, @@ -86,7 +90,7 @@ class Export(GlancesExport): prefix=prefix) def export(self, name, columns, points): - """Export the stats to the Statsd server""" + """Export the stats to the Statsd server.""" for i in range(0, len(columns)): if not isinstance(points[i], Number): continue diff --git a/glances/outputs/bottle/base.tpl b/glances/outputs/bottle/base.tpl deleted file mode 100644 index 30d69690..00000000 --- a/glances/outputs/bottle/base.tpl +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - Glances - - - - - - - -
    -
    -
    -
    - % include('plugin_text', plugin_name="system", stats=stats['system']) -
    -
    - % include('plugin_text', plugin_name="uptime", stats=stats['uptime']) -
    -
    -
    -
    -
    - % include('plugin_table', plugin_name="cpu", stats=stats['cpu']) -
    -
    - % include('plugin_table', plugin_name="load", stats=stats['load']) -
    -
    - % include('plugin_table', plugin_name="mem", stats=stats['mem']) -
    -
    - % include('plugin_table', plugin_name="memswap", stats=stats['memswap']) -
    -
    -
    -
    - % 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']) -
    -
    - % 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']) -
    -
    - % include('plugin_table', plugin_name="monitor", stats=stats['monitor']) -
    -
    - % include('plugin_table', plugin_name="processlist", stats=stats['processlist']) -
    -
    -
    - - \ No newline at end of file diff --git a/glances/outputs/bottle/plugin_table.tpl b/glances/outputs/bottle/plugin_table.tpl deleted file mode 100644 index f98e5497..00000000 --- a/glances/outputs/bottle/plugin_table.tpl +++ /dev/null @@ -1,22 +0,0 @@ -% if stats['msgdict'] != []: -
    - - - - % for msg in stats['msgdict']: - % if msg['msg'].startswith('\n'): - - - % else: - % if stats['display']: - - % end - % end - % end - - -
    - {{ msg['msg'] }} -
    -
    -% end \ No newline at end of file diff --git a/glances/outputs/bottle/plugin_text.tpl b/glances/outputs/bottle/plugin_text.tpl deleted file mode 100644 index 990e7478..00000000 --- a/glances/outputs/bottle/plugin_text.tpl +++ /dev/null @@ -1,11 +0,0 @@ -% if stats['msgdict'] != []: -
    -% for msg in stats['msgdict']: - % if stats['display']: - - {{ msg['msg'] }} - - % end -% end -
    -% end \ No newline at end of file diff --git a/glances/outputs/glances_bars.py b/glances/outputs/glances_bars.py index 729e4a63..c25924f1 100644 --- a/glances/outputs/glances_bars.py +++ b/glances/outputs/glances_bars.py @@ -20,54 +20,78 @@ """Manage bars for Glances output.""" # Import system lib +import locale from math import modf -# Global vars -curses_bars = [" ", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█"] - class Bar(object): - """Manage bar (progression or status) + + r"""Manage bar (progression or status). import sys import time b = Bar(10) for p in range(0, 100): - b.set_percent(p) + b.percent = p print("\r%s" % b), time.sleep(0.1) sys.stdout.flush() - """ - def __init__(self, size): + def __init__(self, size, + pre_char='[', + post_char=']', + empty_char='_', + with_text=True): # Bar size self.__size = size # Bar current percent self.__percent = 0 + # Char used for the decoration + self.__pre_char = pre_char + self.__post_char = post_char + self.__empty_char = empty_char + self.__with_text = with_text + # Char used for the bar + self.curses_bars = self.__get_curses_bars() - def get_size(self): - return self.__size + def __get_curses_bars(self): + # Return the chars used to display the bar + if locale.getdefaultlocale()[1] == 'UTF-8': + return [" ", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█"] + else: + return [" ", " ", " ", " ", "|", "|", "|", "|", "|"] - def set_size(self, size): - self.__size = size - return self.__size + @property + def size(self, with_decoration=False): + # Return the bar size, with or without decoration + if with_decoration: + return self.__size + if self.__with_text: + return self.__size - 6 - def get_percent(self): + # @size.setter + # def size(self, value): + # self.__size = value + + @property + def percent(self): return self.__percent - def set_percent(self, percent): - assert percent >= 0 - assert percent <= 100 - self.__percent = percent - return self.__percent + @percent.setter + def percent(self, value): + assert value >= 0 + assert value <= 100 + self.__percent = value def __str__(self): - """Return the bars""" - frac, whole = modf(self.get_size() * self.get_percent() / 100.0) - ret = curses_bars[8] * int(whole) + """Return the bars.""" + frac, whole = modf(self.size * self.percent / 100.0) + ret = self.curses_bars[8] * int(whole) if frac > 0: - ret += curses_bars[int(frac * 8)] + ret += self.curses_bars[int(frac * 8)] whole += 1 - ret += '_' * int(self.get_size() - whole) - return ret + ret += self.__empty_char * int(self.size - whole) + if self.__with_text: + ret = '{0}{1:>5}%'.format(ret, self.percent) + return self.__pre_char + ret + self.__post_char diff --git a/glances/outputs/glances_bottle.py b/glances/outputs/glances_bottle.py index b5ff8bbf..a7b60831 100644 --- a/glances/outputs/glances_bottle.py +++ b/glances/outputs/glances_bottle.py @@ -23,12 +23,11 @@ import json import os import sys -# Import Glances libs +from glances.core.glances_globals import is_windows from glances.core.glances_logging import logger -# Import mandatory Bottle lib try: - from bottle import Bottle, template, static_file, TEMPLATE_PATH, abort, response, request + from bottle import Bottle, static_file, abort, response, request except ImportError: logger.critical('Bottle module not found. Glances cannot start in web server mode.') sys.exit(2) @@ -53,9 +52,6 @@ class GlancesBottle(object): # Define routes self._route() - # Update the template path (glances/outputs/bottle) - TEMPLATE_PATH.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'bottle')) - # Path where the statics files are stored self.STATIC_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'static') @@ -63,10 +59,17 @@ class GlancesBottle(object): """Define route.""" self._app.route('/', method="GET", callback=self._index) self._app.route('/', method=["GET", "POST"], callback=self._index) + self._app.route('/', method="GET", callback=self._css) self._app.route('/', method="GET", callback=self._js) + self._app.route('/', method="GET", callback=self._js_map) + self._app.route('/', method="GET", callback=self._html) + + self._app.route('/', method="GET", callback=self._images) self._app.route('/favicon.ico', method="GET", callback=self._favicon) + # REST API + self._app.route('/api/2/help', method="GET", callback=self._api_help) self._app.route('/api/2/pluginslist', method="GET", callback=self._api_plugins) self._app.route('/api/2/all', method="GET", callback=self._api_all) self._app.route('/api/2/all/limits', method="GET", callback=self._api_all_limits) @@ -86,7 +89,7 @@ class GlancesBottle(object): self.plugins_list = self.stats.getAllPlugins() # Bind the Bottle TCP address/port - bindmsg = _("Glances web server started on http://{0}:{1}/").format(self.args.bind_address, self.args.port) + bindmsg = 'Glances web server started on http://{0}:{1}/'.format(self.args.bind_address, self.args.port) logger.info(bindmsg) print(bindmsg) self._app.run(host=self.args.bind_address, port=self.args.port, quiet=not self.args.debug) @@ -105,7 +108,12 @@ class GlancesBottle(object): self.stats.update() # Display - return self.display(self.stats, refresh_time=refresh_time) + return static_file("index.html", root=os.path.join(self.STATIC_PATH, 'html')) + + def _html(self, filename): + """Bottle callback for *.html files.""" + # Return the static file + return static_file(filename, root=os.path.join(self.STATIC_PATH, 'html')) def _css(self, filename): """Bottle callback for *.css files.""" @@ -117,16 +125,60 @@ class GlancesBottle(object): # Return the static file return static_file(filename, root=os.path.join(self.STATIC_PATH, 'js')) + def _js_map(self, filename): + """Bottle callback for *.js.map files.""" + # Return the static file + return static_file(filename, root=os.path.join(self.STATIC_PATH, 'js')) + + def _images(self, filename): + """Bottle callback for *.png files.""" + # Return the static file + return static_file(filename, root=os.path.join(self.STATIC_PATH, 'images')) + def _favicon(self): """Bottle callback for favicon.""" # Return the static file return static_file('favicon.ico', root=self.STATIC_PATH) + def _api_help(self): + """Glances API RESTFul implementation. + + Return the help data or 404 error. + """ + response.content_type = 'application/json' + + # Update the stat + view_data = self.stats.get_plugin("help").get_view_data() + try: + plist = json.dumps(view_data, sort_keys=True) + except Exception as e: + abort(404, "Cannot get help view data (%s)" % str(e)) + return plist + def _api_plugins(self): """ - Glances API RESTFul implementation - Return the plugin list - or 404 error + @api {get} /api/2/pluginslist Get plugins list + @apiVersion 2.0 + @apiName pluginslist + @apiGroup plugin + + @apiSuccess {String[]} Plugins list. + + @apiSuccessExample Success-Response: + HTTP/1.1 200 OK + [ + "load", + "help", + "ip", + "memswap", + "processlist", + ... + ] + + @apiError Cannot get plugin list. + + @apiErrorExample Error-Response: + HTTP/1.1 404 Not Found """ response.content_type = 'application/json' @@ -140,8 +192,8 @@ class GlancesBottle(object): return plist def _api_all(self): - """ - Glances API RESTFul implementation + """Glances API RESTFul implementation. + Return the JSON representation of all the plugins HTTP/200 if OK HTTP/400 if plugin is not found @@ -149,19 +201,28 @@ class GlancesBottle(object): """ response.content_type = 'application/json' - # Update the stat - self.stats.update() + if not self.args.debug: + # Update the stat + self.stats.update() - try: - # Get the JSON value of the stat value - statval = json.dumps(self.stats.getAllAsDict()) - except Exception as e: - abort(404, "Cannot get stats (%s)" % str(e)) - return statval + try: + # Get the JSON value of the stat ID + statval = json.dumps(self.stats.getAllAsDict()) + except Exception as e: + abort(404, "Cannot get stats (%s)" % str(e)) + return statval + else: + path = "~/glances/" + if is_windows: + path = "D:\\glances\\" + filepath = path + "debug.json" + + f = open(filepath) + return f.read() def _api_all_limits(self): - """ - Glances API RESTFul implementation + """Glances API RESTFul implementation. + Return the JSON representation of all the plugins limits HTTP/200 if OK HTTP/400 if plugin is not found @@ -177,8 +238,8 @@ class GlancesBottle(object): return limits def _api_all_views(self): - """ - Glances API RESTFul implementation + """Glances API RESTFul implementation. + Return the JSON representation of all the plugins views HTTP/200 if OK HTTP/400 if plugin is not found @@ -194,8 +255,8 @@ class GlancesBottle(object): return limits def _api(self, plugin): - """ - Glances API RESTFul implementation + """Glances API RESTFul implementation. + Return the JSON representation of a given plugin HTTP/200 if OK HTTP/400 if plugin is not found @@ -217,8 +278,8 @@ class GlancesBottle(object): return statval def _api_limits(self, plugin): - """ - Glances API RESTFul implementation + """Glances API RESTFul implementation. + Return the JSON limits of a given plugin HTTP/200 if OK HTTP/400 if plugin is not found @@ -234,14 +295,14 @@ class GlancesBottle(object): try: # Get the JSON value of the stat limits - ret = self.stats.get_plugin(plugin).get_limits() + ret = self.stats.get_plugin(plugin).limits except Exception as e: abort(404, "Cannot get limits for plugin %s (%s)" % (plugin, str(e))) return ret def _api_views(self, plugin): - """ - Glances API RESTFul implementation + """Glances API RESTFul implementation. + Return the JSON views of a given plugin HTTP/200 if OK HTTP/400 if plugin is not found @@ -263,8 +324,8 @@ class GlancesBottle(object): return ret def _api_item(self, plugin, item): - """ - Glances API RESTFul implementation + """Glances API RESTFul implementation. + Return the JSON represenation of the couple plugin/item HTTP/200 if OK HTTP/400 if plugin is not found @@ -287,8 +348,8 @@ class GlancesBottle(object): return plist def _api_value(self, plugin, item, value): - """ - Glances API RESTFul implementation + """Glances API RESTFul implementation. + Return the process stats (dict) for the given item=value HTTP/200 if OK HTTP/400 if plugin is not found @@ -309,33 +370,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 - """ - - stats = { - 'system': self.stats.get_plugin('system').get_stats_display(args=self.args), - 'uptime': self.stats.get_plugin('uptime').get_stats_display(args=self.args), - 'cpu': self.stats.get_plugin('cpu').get_stats_display(args=self.args), - 'load': self.stats.get_plugin('load').get_stats_display(args=self.args), - 'mem': self.stats.get_plugin('mem').get_stats_display(args=self.args), - 'memswap': self.stats.get_plugin('memswap').get_stats_display(args=self.args), - 'network': self.stats.get_plugin('network').get_stats_display(args=self.args), - 'diskio': self.stats.get_plugin('diskio').get_stats_display(args=self.args), - 'fs': self.stats.get_plugin('fs').get_stats_display(args=self.args), - 'raid': self.stats.get_plugin('raid').get_stats_display(args=self.args), - 'sensors': self.stats.get_plugin('sensors').get_stats_display(args=self.args), - 'alert': self.stats.get_plugin('alert').get_stats_display(args=self.args), - 'processcount': self.stats.get_plugin('processcount').get_stats_display(args=self.args), - 'monitor': self.stats.get_plugin('monitor').get_stats_display(args=self.args), - 'processlist': self.stats.get_plugin('processlist').get_stats_display(args=self.args), - 'docker': self.stats.get_plugin('docker').get_stats_display(args=self.args) - } - - return template('base', refresh_time=refresh_time, stats=stats) - class EnableCors(object): name = 'enable_cors' diff --git a/glances/outputs/glances_colorconsole.py b/glances/outputs/glances_colorconsole.py index 49c55037..3cd674e1 100644 --- a/glances/outputs/glances_colorconsole.py +++ b/glances/outputs/glances_colorconsole.py @@ -80,10 +80,10 @@ class Screen(object): def subwin(self, x, y): return self - def keypad(self, id): + def keypad(self, screen_id): return None - def nodelay(self, id): + def nodelay(self, screen_id): return None def getch(self): @@ -170,8 +170,8 @@ class WCurseLight(object): def napms(self, t): time.sleep(t / 1000 if t > 1000 else 1) - def init_pair(self, id, fg, bk): - self.colors[id] = [max(fg, 0), max(bk, 0)] + def init_pair(self, color_id, fg, bk): + self.colors[color_id] = [max(fg, 0), max(bk, 0)] - def color_pair(self, id): - return id + def color_pair(self, color_id): + return color_id diff --git a/glances/outputs/glances_curses.py b/glances/outputs/glances_curses.py index fbd1375a..1b98a3d9 100644 --- a/glances/outputs/glances_curses.py +++ b/glances/outputs/glances_curses.py @@ -20,6 +20,7 @@ """Curses interface class.""" # Import system lib +import re import sys # Import Glances lib @@ -36,7 +37,8 @@ if not is_windows: import curses.panel from curses.textpad import Textbox except ImportError: - logger.critical("Curses module not found. Glances cannot start in standalone mode.") + logger.critical( + "Curses module not found. Glances cannot start in standalone mode.") sys.exit(1) else: from glances.outputs.glances_colorconsole import WCurseLight @@ -45,9 +47,9 @@ else: class _GlancesCurses(object): - """ - This class manages the curses display (and key pressed). - Note: It is a private class, use GlancesCursesClient or GlancesCursesBrowser + """This class manages the curses display (and key pressed). + + Note: It is a private class, use GlancesCursesClient or GlancesCursesBrowser. """ def __init__(self, args=None): @@ -126,6 +128,7 @@ class _GlancesCurses(object): self.no_color = curses.color_pair(1) self.default_color = curses.color_pair(3) | A_BOLD self.nice_color = curses.color_pair(9) | A_BOLD + self.cpu_time_color = curses.color_pair(9) | A_BOLD self.ifCAREFUL_color = curses.color_pair(4) | A_BOLD self.ifWARNING_color = curses.color_pair(5) | A_BOLD self.ifCRITICAL_color = curses.color_pair(2) | A_BOLD @@ -139,6 +142,7 @@ class _GlancesCurses(object): self.no_color = curses.A_NORMAL self.default_color = curses.A_NORMAL self.nice_color = A_BOLD + self.cpu_time_color = A_BOLD self.ifCAREFUL_color = curses.A_UNDERLINE self.ifWARNING_color = A_BOLD self.ifCRITICAL_color = curses.A_REVERSE @@ -160,6 +164,7 @@ class _GlancesCurses(object): 'PROCESS': self.default_color2, 'STATUS': self.default_color2, 'NICE': self.nice_color, + 'CPU_TIME': self.cpu_time_color, 'CAREFUL': self.ifCAREFUL_color2, 'WARNING': self.ifWARNING_color2, 'CRITICAL': self.ifCRITICAL_color2, @@ -175,9 +180,6 @@ class _GlancesCurses(object): # Init refresh time self.__refresh_time = args.time - # Init process sort method - self.args.process_sorted_by = 'auto' - # Init edit filter tag self.edit_filter = False @@ -200,11 +202,12 @@ class _GlancesCurses(object): 'Stats history disabled because MatPlotLib is not installed') def set_cursor(self, value): - """Configure the curse cursor apparence - 0: invisible - 1: visible - 2: very visible - """ + """Configure the curse cursor apparence. + + 0: invisible + 1: visible + 2: very visible + """ if hasattr(curses, 'curs_set'): try: curses.curs_set(value) @@ -248,21 +251,24 @@ class _GlancesCurses(object): elif self.pressedkey == ord('2'): # '2' > Enable/disable left sidebar self.args.disable_left_sidebar = not self.args.disable_left_sidebar + elif self.pressedkey == ord('3'): + # '3' > Enable/disable quicklook + self.args.disable_quicklook = not self.args.disable_quicklook elif self.pressedkey == ord('/'): # '/' > Switch between short/long name for processes self.args.process_short_name = not self.args.process_short_name elif self.pressedkey == ord('a'): - # 'a' > Sort processes automatically - self.args.process_sorted_by = 'auto' - glances_processes.resetsort() + # 'a' > Sort processes automatically and reset to 'cpu_percent' + glances_processes.auto_sort = True + glances_processes.sort_key = 'cpu_percent' elif self.pressedkey == ord('b'): # 'b' > Switch between bit/s and Byte/s for network IO # self.net_byteps_tag = not self.net_byteps_tag self.args.byte = not self.args.byte elif self.pressedkey == ord('c'): # 'c' > Sort processes by CPU usage - self.args.process_sorted_by = 'cpu_percent' - glances_processes.setmanualsortkey(self.args.process_sorted_by) + glances_processes.auto_sort = False + glances_processes.sort_key = 'cpu_percent' elif self.pressedkey == ord('d'): # 'd' > Show/hide disk I/O stats self.args.disable_diskio = not self.args.disable_diskio @@ -290,22 +296,25 @@ class _GlancesCurses(object): self.args.help_tag = not self.args.help_tag elif self.pressedkey == ord('i'): # 'i' > Sort processes by IO rate (not available on OS X) - self.args.process_sorted_by = 'io_counters' - glances_processes.setmanualsortkey(self.args.process_sorted_by) + glances_processes.auto_sort = False + glances_processes.sort_key = 'io_counters' + elif self.pressedkey == ord('I'): + # 'I' > Show/hide IP module + self.args.disable_ip = not self.args.disable_ip elif self.pressedkey == ord('l'): # 'l' > Show/hide log messages self.args.disable_log = not self.args.disable_log elif self.pressedkey == ord('m'): # 'm' > Sort processes by MEM usage - self.args.process_sorted_by = 'memory_percent' - glances_processes.setmanualsortkey(self.args.process_sorted_by) + glances_processes.auto_sort = False + glances_processes.sort_key = 'memory_percent' elif self.pressedkey == ord('n'): # 'n' > Show/hide network stats self.args.disable_network = not self.args.disable_network elif self.pressedkey == ord('p'): # 'p' > Sort processes by name - self.args.process_sorted_by = 'name' - glances_processes.setmanualsortkey(self.args.process_sorted_by) + glances_processes.auto_sort = False + glances_processes.sort_key = 'name' elif self.pressedkey == ord('r'): # 'r' > Reset history self.reset_history_tag = not self.reset_history_tag @@ -317,13 +326,17 @@ class _GlancesCurses(object): self.args.disable_sensors = not self.args.disable_sensors elif self.pressedkey == ord('t'): # 't' > Sort processes by TIME usage - self.args.process_sorted_by = 'cpu_times' - glances_processes.setmanualsortkey(self.args.process_sorted_by) + glances_processes.auto_sort = False + glances_processes.sort_key = 'cpu_times' elif self.pressedkey == ord('T'): # '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 @@ -357,31 +370,29 @@ class _GlancesCurses(object): curses.endwin() 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 + """Init the line and column position for the curses inteface.""" + self.init_line() + self.init_column() def init_line(self): - """Init the line position for the curses inteface""" + """Init the line position for the curses inteface.""" self.line = 0 self.next_line = 0 def init_column(self): - """Init the column position for the curses inteface""" + """Init the column position for the curses inteface.""" self.column = 0 self.next_column = 0 def new_line(self): - """New line in the curses interface""" + """New line in the curses interface.""" self.line = self.next_line def new_column(self): - """New column in the curses interface""" + """New column in the curses interface.""" self.column = self.next_column - def display(self, stats, cs_status="None"): + def display(self, stats, cs_status=None): """Display stats on the screen. stats: Stats database to display @@ -426,6 +437,10 @@ class _GlancesCurses(object): stats_memswap = stats.get_plugin('memswap').get_stats_display() stats_network = stats.get_plugin('network').get_stats_display( args=self.args, max_width=plugin_max_width) + try: + stats_ip = stats.get_plugin('ip').get_stats_display(args=self.args) + except AttributeError: + stats_ip = None stats_diskio = stats.get_plugin( 'diskio').get_stats_display(args=self.args) stats_fs = stats.get_plugin('fs').get_stats_display( @@ -452,11 +467,10 @@ class _GlancesCurses(object): max_processes_displayed -= 4 if max_processes_displayed < 0: max_processes_displayed = 0 - if glances_processes.get_max_processes() is None or \ - glances_processes.get_max_processes() != max_processes_displayed: - logger.debug("Set number of displayed processes to %s" % - max_processes_displayed) - glances_processes.set_max_processes(max_processes_displayed) + if (glances_processes.max_processes is None or + glances_processes.max_processes != max_processes_displayed): + logger.debug("Set number of displayed processes to {0}".format(max_processes_displayed)) + glances_processes.max_processes = max_processes_displayed stats_processlist = stats.get_plugin( 'processlist').get_stats_display(args=self.args) @@ -472,55 +486,93 @@ class _GlancesCurses(object): # ... and exit return False + # ================================== # Display first line (system+uptime) + # ================================== + # Space between column + self.space_between_column = 0 self.new_line() - l = self.get_stats_display_width( - stats_system) + self.get_stats_display_width(stats_uptime) + self.space_between_column - self.display_plugin(stats_system, display_optional=(screen_x >= l)) + l_uptime = self.get_stats_display_width( + stats_system) + self.space_between_column + self.get_stats_display_width(stats_ip) + 3 + self.get_stats_display_width(stats_uptime) + self.display_plugin( + stats_system, display_optional=(screen_x >= l_uptime)) + self.new_column() + self.display_plugin(stats_ip) + # Space between column + self.space_between_column = 3 self.new_column() self.display_plugin(stats_uptime) - # Display second line (CPU|PERCPU+LOAD+MEM+SWAP+) - # CPU|PERCPU + # ======================================================== + # Display second line (+CPU|PERCPU+LOAD+MEM+SWAP) + # ======================================================== self.init_column() self.new_line() + # Init quicklook + stats_quicklook = {'msgdict': []} + # Start with the mandatory stats: + # CPU | PERCPU if self.args.percpu: - l = self.get_stats_display_width(stats_percpu) + cpu_width = self.get_stats_display_width(stats_percpu) + quicklook_adapt = 114 else: - l = self.get_stats_display_width(stats_cpu) - l += self.get_stats_display_width(stats_load) + self.get_stats_display_width( - stats_mem) + self.get_stats_display_width(stats_memswap) - # Space between column - space_number = int(stats_load['msgdict'] != [ - ]) + int(stats_mem['msgdict'] != []) + int(stats_memswap['msgdict'] != []) - if space_number == 0: + cpu_width = self.get_stats_display_width( + stats_cpu, without_option=(screen_x < 80)) + quicklook_adapt = 108 + l = cpu_width + # MEM & SWAP & LOAD + l += self.get_stats_display_width(stats_mem, + without_option=(screen_x < 100)) + l += self.get_stats_display_width(stats_memswap) + l += self.get_stats_display_width(stats_load) + # Quicklook plugin size is dynamic + l_ql = 0 + if screen_x > 126 and not self.args.disable_quicklook: + # Limit the size to be align with the process + quicklook_width = min(screen_x - quicklook_adapt, 87) + try: + stats_quicklook = stats.get_plugin( + 'quicklook').get_stats_display(max_width=quicklook_width, args=self.args) + except AttributeError as e: + logger.debug("Quicklook plugin not available (%s)" % e) + else: + l_ql = self.get_stats_display_width(stats_quicklook) + # Display Quicklook + self.display_plugin(stats_quicklook) + self.new_column() + # Compute space between column + space_number = int(stats_quicklook['msgdict'] != []) + space_number += int(stats_mem['msgdict'] != []) + space_number += int(stats_memswap['msgdict'] != []) + space_number += int(stats_load['msgdict'] != []) + if space_number < 1: space_number = 1 if screen_x > (space_number * self.space_between_column + l): - self.space_between_column = int((screen_x - l) / space_number) - # Display + self.space_between_column = int((screen_x - l_ql - l) / space_number) + # Display others stats if self.args.percpu: self.display_plugin(stats_percpu) else: self.display_plugin(stats_cpu, display_optional=(screen_x >= 80)) self.new_column() - self.display_plugin(stats_load) - self.new_column() - self.display_plugin(stats_mem, display_optional=( - screen_x >= (space_number * self.space_between_column + l))) + self.display_plugin(stats_mem, display_optional=(screen_x >= 100)) self.new_column() self.display_plugin(stats_memswap) + self.new_column() + self.display_plugin(stats_load) # Space between column self.space_between_column = 3 # Backup line position self.saved_line = self.next_line + # ================================================================== # Display left sidebar (NETWORK+DISKIO+FS+SENSORS+Current time) + # ================================================================== self.init_column() - if (not (self.args.disable_network and self.args.disable_diskio - and self.args.disable_fs and self.args.disable_raid - and self.args.disable_sensors)) \ - and not self.args.disable_left_sidebar: + if not (self.args.disable_network and self.args.disable_diskio and + self.args.disable_fs and self.args.disable_raid and + self.args.disable_sensors) and not self.args.disable_left_sidebar: self.new_line() self.display_plugin(stats_network) self.new_line() @@ -534,6 +586,9 @@ class _GlancesCurses(object): self.new_line() self.display_plugin(stats_now) + # ==================================== + # Display right stats (process and co) + # ==================================== # If space available... if screen_x > 52: # Restore line position @@ -546,7 +601,7 @@ class _GlancesCurses(object): self.display_plugin(stats_docker) self.new_line() self.display_plugin(stats_processcount) - if glances_processes.get_process_filter() is None and cs_status == 'None': + if glances_processes.process_filter is None and cs_status is None: # Do not display stats monitor list if a filter exist self.new_line() self.display_plugin(stats_monitor) @@ -562,34 +617,34 @@ class _GlancesCurses(object): # Generate history graph if self.history_tag and self.args.enable_history: self.display_popup( - _("Generate graphs history in %s\nPlease wait...") % self.glances_history.get_output_folder()) + 'Generate graphs history in {0}\nPlease wait...'.format( + self.glances_history.get_output_folder())) self.display_popup( - _("Generate graphs history in %s\nDone: %s graphs generated") % (self.glances_history.get_output_folder(), self.glances_history.generate_graph(stats))) + 'Generate graphs history in {0}\nDone: {1} graphs generated'.format( + self.glances_history.get_output_folder(), + self.glances_history.generate_graph(stats))) elif self.reset_history_tag and self.args.enable_history: - self.display_popup(_("Reset history")) + self.display_popup('Reset history') self.glances_history.reset(stats) elif (self.history_tag or self.reset_history_tag) and not self.args.enable_history: try: self.glances_history.graph_enabled() except Exception: - self.display_popup( - _("History disabled\nEnable it using --enable-history")) + self.display_popup('History disabled\nEnable it using --enable-history') else: - self.display_popup( - _("History disabled\nPlease install MatPlotLib")) + self.display_popup('History disabled\nPlease install matplotlib') self.history_tag = False self.reset_history_tag = False # Display edit filter popup - # Only in standalone mode (cs_status == 'None') - if self.edit_filter and cs_status == 'None': - new_filter = self.display_popup(_("Process filter pattern: "), - is_input=True, - input_value=glances_processes.get_process_filter()) - glances_processes.set_process_filter(new_filter) + # Only in standalone mode (cs_status is None) + if self.edit_filter and cs_status is None: + new_filter = self.display_popup( + 'Process filter pattern: ', is_input=True, + input_value=glances_processes.process_filter) + glances_processes.process_filter = new_filter elif self.edit_filter and cs_status != 'None': - self.display_popup( - _("Process filter only available in standalone mode")) + self.display_popup('Process filter only available in standalone mode') self.edit_filter = False return True @@ -601,18 +656,20 @@ class _GlancesCurses(object): input_size=30, input_value=None): """ + Display a centered popup. + If is_input is False: Display a centered popup with the given message during duration seconds If size_x and size_y: set the popup size else set it automatically Return True if the popup could be displayed + If is_input is True: Display a centered popup with the given message and a input field If size_x and size_y: set the popup size else set it automatically Return the input string or None if the field is empty """ - # Center the popup sentence_list = message.split('\n') if size_x is None: @@ -637,10 +694,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 @@ -683,7 +738,7 @@ class _GlancesCurses(object): # Exit if: # - the plugin_stats message is empty # - the display tag = False - if not plugin_stats['msgdict'] or not plugin_stats['display']: + if plugin_stats is None or not plugin_stats['msgdict'] or not plugin_stats['display']: # Exit return 0 @@ -711,7 +766,7 @@ class _GlancesCurses(object): # New line if m['msg'].startswith('\n'): # Go to the next line - y = y + 1 + y += 1 # Return to the first column x = display_x continue @@ -743,24 +798,25 @@ 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 offset = len(m['msg']) - x = x + offset + x += offset if x > x_max: x_max = x # Compute the next Glances column/line position - self.next_column = max(self.next_column, x_max + self.space_between_column) + self.next_column = max( + self.next_column, x_max + self.space_between_column) self.next_line = max(self.next_line, y + self.space_between_line) def erase(self): """Erase the content of the screen.""" self.term_window.erase() - def flush(self, stats, cs_status="None"): + def flush(self, stats, cs_status=None): """Clear and update the screen. stats: Stats database to display @@ -772,7 +828,7 @@ class _GlancesCurses(object): self.erase() self.display(stats, cs_status=cs_status) - def update(self, stats, cs_status="None", return_to_browser=False): + def update(self, stats, cs_status=None, return_to_browser=False): """Update the screen. Wait for __refresh_time sec / catch key every 100 ms. @@ -818,11 +874,11 @@ class _GlancesCurses(object): try: if without_option: # Size without options - c = len(max(''.join([(i['msg'] if not i['optional'] else "") + c = len(max(''.join([(re.sub(r'[^\x00-\x7F]+', ' ', i['msg']) if not i['optional'] else "") for i in curse_msg['msgdict']]).split('\n'), key=len)) else: # Size with all options - c = len(max(''.join([i['msg'] + c = len(max(''.join([re.sub(r'[^\x00-\x7F]+', ' ', i['msg']) for i in curse_msg['msgdict']]).split('\n'), key=len)) except Exception: return 0 @@ -844,21 +900,21 @@ class _GlancesCurses(object): class GlancesCursesStandalone(_GlancesCurses): - """Class for the Glances' curse standalone""" + """Class for the Glances curse standalone.""" pass class GlancesCursesClient(_GlancesCurses): - """Class for the Glances' curse client""" + """Class for the Glances curse client.""" pass class GlancesCursesBrowser(_GlancesCurses): - """Class for the Glances' curse client browser""" + """Class for the Glances curse client browser.""" def __init__(self, args=None): # Init the father class @@ -881,48 +937,44 @@ class GlancesCursesBrowser(_GlancesCurses): self.__refresh_time = args.time # Init the cursor position for the client browser - self.cursor_init() + self.cursor_position = 0 # Active Glances server number - self.set_active() + self._active_server = None - def set_active(self, index=None): - """Set the active server or None if no server selected""" - self.active_server = index - return self.active_server + @property + def active_server(self): + """Return the active server or None if it's the browser list.""" + return self._active_server - def get_active(self): - """Return the active server (the one display in front) or None if it is the browser list""" - return self.active_server + @active_server.setter + def active_server(self, index): + """Set the active server or None if no server selected.""" + self._active_server = index - def cursor_init(self): - """Init the cursor position to the top of the list""" - return self.cursor_set(0) - - def cursor_set(self, pos): - """Set the cursor position and return it""" - self.cursor_position = pos + @property + def cursor(self): + """Get the cursor position.""" return self.cursor_position - def cursor_get(self): - """Return the cursor position""" - return self.cursor_position + @cursor.setter + def cursor(self, position): + """Set the cursor position.""" + self.cursor_position = position def cursor_up(self, servers_list): - """Set the cursor to position N-1 in the list""" + """Set the cursor to position N-1 in the list.""" if self.cursor_position > 0: self.cursor_position -= 1 else: self.cursor_position = len(servers_list) - 1 - return self.cursor_position def cursor_down(self, servers_list): - """Set the cursor to position N-1 in the list""" + """Set the cursor to position N-1 in the list.""" if self.cursor_position < len(servers_list) - 1: self.cursor_position += 1 else: self.cursor_position = 0 - return self.cursor_position def __catch_key(self, servers_list): # Catch the browser pressed key @@ -936,11 +988,10 @@ class GlancesCursesBrowser(_GlancesCurses): sys.exit(0) elif self.pressedkey == 10: # 'ENTER' > Run Glances on the selected server - logger.debug("Server number %s selected" % (self.cursor_get() + 1)) - self.set_active(self.cursor_get()) + logger.debug("Server number {0} selected".format(self.cursor + 1)) + self.active_server = self.cursor elif self.pressedkey == 259: # 'UP' > Up in the server list - logger self.cursor_up(servers_list) elif self.pressedkey == 258: # 'DOWN' > Down in the server list @@ -957,6 +1008,7 @@ class GlancesCursesBrowser(_GlancesCurses): servers_list: Dict of dict with servers stats """ # Flush display + logger.debug("Servers list: {}".format(servers_list)) self.flush(servers_list) # Wait @@ -974,17 +1026,19 @@ class GlancesCursesBrowser(_GlancesCurses): # Wait 100ms... curses.napms(100) - return self.get_active() + return self.active_server def flush(self, servers_list): """Update the servers' list screen. + servers_list: List of dict with servers stats """ self.erase() self.display(servers_list) def display(self, servers_list): - """Display the servers list + """Display the servers list. + Return: True if the stats have been displayed False if the stats have not been displayed (no server available) @@ -1003,17 +1057,16 @@ class GlancesCursesBrowser(_GlancesCurses): # Display top header if len(servers_list) == 0: if self.first_scan and not self.args.disable_autodiscover: - msg = _("Glances is scanning your network (please wait)...") + msg = 'Glances is scanning your network. Please wait...' self.first_scan = False else: - msg = _("No Glances servers available") + msg = 'No Glances server available' elif len(servers_list) == 1: - msg = _("One Glances server available") + msg = 'One Glances server available' else: - msg = _("%d Glances servers available" % - len(servers_list)) + msg = '{0} Glances servers available'.format(len(servers_list)) if self.args.disable_autodiscover: - msg += ' ' + _("(auto discover is disabled)") + msg += ' ' + '(auto discover is disabled)' self.term_window.addnstr(y, x, msg, screen_x - x, @@ -1023,41 +1076,39 @@ class GlancesCursesBrowser(_GlancesCurses): return False # Display the Glances server list - #================================ + # ================================ # Table of table # Item description: [stats_id, column name, column size] column_def = [ - ['name', _('Name'), 16], + ['name', 'Name', 16], ['alias', None, None], - ['load_min5', _('LOAD'), 6], - ['cpu_percent', _('CPU%'), 5], - ['mem_percent', _('MEM%'), 5], - ['status', _('STATUS'), 8], - ['ip', _('IP'), 15], - # ['port', _('PORT'), 5], - ['hr_name', _('OS'), 16], + ['load_min5', 'LOAD', 6], + ['cpu_percent', 'CPU%', 5], + ['mem_percent', 'MEM%', 5], + ['status', 'STATUS', 8], + ['ip', 'IP', 15], + # ['port', 'PORT', 5], + ['hr_name', 'OS', 16], ] 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... # ... and if the cursor is in the latest position - if self.cursor_get() > len(servers_list) - 1: + if self.cursor > len(servers_list) - 1: # Set the cursor position to the latest item - self.cursor_set(len(servers_list) - 1) + self.cursor = len(servers_list) - 1 # Display table line = 0 @@ -1075,7 +1126,7 @@ class GlancesCursesBrowser(_GlancesCurses): try: if c[0] == 'alias' and v[c[0]] is not None: server_stat['name'] = v[c[0]] - except KeyError as e: + except KeyError: pass # Display line for server stats @@ -1083,25 +1134,18 @@ class GlancesCursesBrowser(_GlancesCurses): xc = x # Is the line selected ? - if line == self.cursor_get(): + if line == self.cursor: # Display cursor - self.term_window.addnstr(y, xc, - ">", - screen_x - xc, - self.colors_list['BOLD']) - - # Display alias instead of name - server_stat + self.term_window.addnstr( + y, xc, ">", screen_x - xc, self.colors_list['BOLD']) # Display the line xc += 2 for c in column_def: if xc < screen_x and y < screen_y and c[1] is not None: # Display server stats - self.term_window.addnstr(y, xc, - "%s" % server_stat[c[0]], - c[2], - self.colors_list[v['status']]) + self.term_window.addnstr( + y, xc, format(server_stat[c[0]]), c[2], self.colors_list[v['status']]) xc += c[2] + self.space_between_column cpt += 1 # Next line, next server... diff --git a/glances/outputs/static/css/style.css b/glances/outputs/static/css/style.css index 3ac50123..d1bf4d1b 100644 --- a/glances/outputs/static/css/style.css +++ b/glances/outputs/static/css/style.css @@ -3,31 +3,48 @@ body { color: #BBB; font-family: "Lucida Sans Typewriter", "Lucida Console", Monaco, "Bitstream Vera Sans Mono", monospace; } -.plugin { - margin-bottom: 20px; -} -.plugin table { + +.table { + display: table; width: 100%; } -.plugin table tr td:not(:first-child) { +.table-row-group { + display: table-row-group +} +.table-row { + display: table-row; +} +.table-cell { + display: table-cell; text-align: right; } -.underline{ +.plugin { + margin-bottom: 20px; +} +.plugin.table-row-group .table-row:last-child .table-cell { + padding-bottom: 20px; +} + +.underline { text-decoration: underline } -.bold{ +.bold { font-weight: bold; } -.sort{ +.sort { font-weight: bold; -} -.sort:after{ - content: '\25BC' + color: white; } .text-right { text-align: right; } +.text-left { + text-align: left; +} +.sidebar .table-cell:not(.text-left) { + padding-left: 10px; +} /* Theme */ @@ -35,6 +52,10 @@ body { font-weight: bold; color: white; } +.highlight { + font-weight: bold; + color: magenta; +} .ok { color: green; } @@ -53,10 +74,10 @@ body { color: white; } .warning { - color: orange; + color: magenta; } .warning_log { - background-color: orange; + background-color: magenta; color: white; } .critical { @@ -77,25 +98,85 @@ body { } /* Plugins */ -#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 { +#processlist .table-cell, #containers .table-cell { padding: 0px 5px 0px 5px; white-space: nowrap; } -#processlist table tr td:nth-child(6), -#processlist table tr td:nth-child(12) { +gl-monitor-list { + display: block; +} +gl-monitor-list .table-cell { text-align: left; } -#docker table tr td:nth-child(2), -#docker table tr td:nth-child(6) { - text-align: left; -} \ No newline at end of file +/* Loading page */ + +#loading-page .glances-logo { + background: url('glances.png') no-repeat center center; + background-size: contain; +} + +@media (max-width: 750px) { + #loading-page .glances-logo { + height: 400px; + } +} +@media (min-width: 750px) { + #loading-page .glances-logo { + height: 500px; + } +} + + +/* +Loading animation +source : https://github.com/lukehaas/css-loaders +*/ +#loading-page .loader:before, +#loading-page .loader:after, +#loading-page .loader { + border-radius: 50%; + width: 1em; + height: 1em; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; + -webkit-animation: loader 1.8s infinite ease-in-out; + animation: loader 1.8s infinite ease-in-out; +} +#loading-page .loader { + margin: auto; + font-size: 10px; + position: relative; + text-indent: -9999em; + -webkit-animation-delay: 0.16s; + animation-delay: 0.16s; +} +#loading-page .loader:before { + left: -3.5em; +} +#loading-page .loader:after { + left: 3.5em; + -webkit-animation-delay: 0.32s; + animation-delay: 0.32s; +} +#loading-page .loader:before, +#loading-page .loader:after { + content: ''; + position: absolute; + top: 0; +} +@-webkit-keyframes loader { + 0%, 80%, 100% { + box-shadow: 0 2.5em 0 -1.3em #56CA69; + } + 40% { + box-shadow: 0 2.5em 0 0 #56CA69; + } +} +@keyframes loader { + 0%, 80%, 100% { + box-shadow: 0 2.5em 0 -1.3em #56CA69; + } + 40% { + box-shadow: 0 2.5em 0 0 #56CA69; + } +} diff --git a/glances/outputs/static/html/components/monitor_process.html b/glances/outputs/static/html/components/monitor_process.html new file mode 100644 index 00000000..ec883040 --- /dev/null +++ b/glances/outputs/static/html/components/monitor_process.html @@ -0,0 +1,4 @@ +
    {{ process.description }}
    +
    {{ process.count > 1 ? process.count : '' }}
    +
    {{ process.count > 0 ? 'RUNNING' : 'NOT RUNNING' }}
    +
    {{ process.result }}
    diff --git a/glances/outputs/static/html/help.html b/glances/outputs/static/html/help.html new file mode 100644 index 00000000..b193d08e --- /dev/null +++ b/glances/outputs/static/html/help.html @@ -0,0 +1,63 @@ +
    +
    {{help.version}} {{help.psutil_version}}
    +
    +
     
    +
    +
    {{help.configuration_file}}
    +
    +
     
    +
    +
    {{help.sort_auto}}
    +
    {{help.sort_network}}
    +
    +
    +
    {{help.sort_cpu}}
    +
    {{help.show_hide_alert}}
    +
    +
    +
    {{help.show_mem}}
    +
    {{help.delete_warning_alerts}}
    +
    +
    +
    {{help.sort_proc}}
    +
    {{help.delete_warning_critical_alerts}}
    +
    +
    +
    {{help.sort_io}}
    +
    {{help.percpu}}
    +
    +
    +
    {{help.show_hide_help}}
    +
    {{help.show_hide_diskio}}
    +
    +
    +
    {{help.view_network_io_combination}}
    +
    {{help.view_cumulative_network}}
    +
    +
    +
    {{help.show_hide_network}}
    +
    {{help.show_hide_filesytem_freespace}}
    +
    +
    +
    {{help.show_hide_sensors}}
    +
    {{help.generate_graphs}}
    +
    +
    +
    {{help.show_hide_left_sidebar}}
    +
    {{help.reset_history}}
    +
    +
    +
    {{help.enable_disable_process_stats}}
    +
    {{help.quit}}
    +
    +
    +
    {{help.enable_disable_top_extends_stats}}
    +
    {{help.enable_disable_short_processname}}
    +
    +
    +
    {{help.enable_disable_docker}}
    +
    +
     
    +
    +
    {{help.edit_pattern_filter}}
    +
    diff --git a/glances/outputs/static/html/index.html b/glances/outputs/static/html/index.html new file mode 100644 index 00000000..f9b20a70 --- /dev/null +++ b/glances/outputs/static/html/index.html @@ -0,0 +1,28 @@ + + + + + + + Glances + + + + + + + + + + + + + + + + + + + + + diff --git a/glances/outputs/static/html/plugins/alert.html b/glances/outputs/static/html/plugins/alert.html new file mode 100644 index 00000000..ea13e876 --- /dev/null +++ b/glances/outputs/static/html/plugins/alert.html @@ -0,0 +1,7 @@ +
    +
    +
    +{{alert.begin | date : 'yyyy-MM-dd H:mm:ss'}} ({{ alert.ongoing ? 'ongoing' : alert.duration }}) - {{alert[2]}} on {{alert[3]}} ({{alert[4]}}) +
    +
    +
    diff --git a/glances/outputs/static/html/plugins/alerts.html b/glances/outputs/static/html/plugins/alerts.html new file mode 100644 index 00000000..a03db0fc --- /dev/null +++ b/glances/outputs/static/html/plugins/alerts.html @@ -0,0 +1,2 @@ +No warning or critical alert detected +Warning or critical alerts (lasts {{result['alert'].length}} entries) diff --git a/glances/outputs/static/html/plugins/cpu.html b/glances/outputs/static/html/plugins/cpu.html new file mode 100644 index 00000000..84d5f2d0 --- /dev/null +++ b/glances/outputs/static/html/plugins/cpu.html @@ -0,0 +1,44 @@ +
    +
    +
    CPU
    +
    {{result["cpu"].total}}%
    +
    +
    +
    user:
    +
    + {{result["cpu"].user}}% +
    +
    +
    +
    system:
    +
    + {{result["cpu"].system}}% +
    +
    +
    +
    idle:
    +
    {{result["cpu"].idle}}%
    +
    +
    +
    +
    +
    PER CPU
    +
    {{percpu.total}}%
    +
    +
    +
    user:
    +
    + {{percpu.user}}% +
    +
    +
    +
    system:
    +
    + {{percpu.system}}% +
    +
    +
    +
    idle:
    +
    {{percpu.idle}}%
    +
    +
    diff --git a/glances/outputs/static/html/plugins/cpu_more.html b/glances/outputs/static/html/plugins/cpu_more.html new file mode 100644 index 00000000..2c16332a --- /dev/null +++ b/glances/outputs/static/html/plugins/cpu_more.html @@ -0,0 +1,26 @@ +
    +
    +
    nice:
    +
    + {{result["cpu"].nice}}% +
    +
    +
    +
    irq:
    +
    + {{result["cpu"].irq}}% +
    +
    +
    +
    iowait:
    +
    + {{result["cpu"].iowait}}% +
    +
    +
    +
    steal:
    +
    + {{result["cpu"].steal}}% +
    +
    +
    diff --git a/glances/outputs/static/html/plugins/diskio.html b/glances/outputs/static/html/plugins/diskio.html new file mode 100644 index 00000000..35426170 --- /dev/null +++ b/glances/outputs/static/html/plugins/diskio.html @@ -0,0 +1,10 @@ +
    +
    DISK I/O
    +
    R/s
    +
    W/s
    +
    +
    +
    {{disk.disk_name | min_size}}
    +
    {{disk.read_bytes | bytes}}
    +
    {{disk.write_bytes | bytes}}
    +
    diff --git a/glances/outputs/static/html/plugins/docker.html b/glances/outputs/static/html/plugins/docker.html new file mode 100644 index 00000000..d30fa2d0 --- /dev/null +++ b/glances/outputs/static/html/plugins/docker.html @@ -0,0 +1,20 @@ +CONTAINERS {{ result['docker']['containers'].length }} (served by Docker {{ result['docker']['version']['Version'] }}) + +
    +
    +
    Id
    +
    Name
    +
    Status
    +
    CPU%
    +
    MEM
    +
    Command
    +
    +
    +
    {{ container.Id | limitTo:12 }}
    +
    {{ container.Names[0] }}
    +
    {{ container.Status }}
    +
    {{ container.cpu.total | number:1 }}
    +
    {{ container.memory.usage | bytes }}
    +
    {{ container.Command }}
    +
    +
    diff --git a/glances/outputs/static/html/plugins/fs.html b/glances/outputs/static/html/plugins/fs.html new file mode 100644 index 00000000..cd26163c --- /dev/null +++ b/glances/outputs/static/html/plugins/fs.html @@ -0,0 +1,12 @@ +
    +
    FILE SYS
    +
    Used
    +
    Total
    +
    +
    +
    {{fs.mnt_point}} ({{fs.device_name}})
    +
    + {{fs.size - fs.free | bytes}} +
    +
    {{fs.size | bytes}}
    +
    diff --git a/glances/outputs/static/html/plugins/ip.html b/glances/outputs/static/html/plugins/ip.html new file mode 100644 index 00000000..161244d1 --- /dev/null +++ b/glances/outputs/static/html/plugins/ip.html @@ -0,0 +1 @@ + - IP {{result["ip"].address}}/{{result["ip"].mask_cidr}} diff --git a/glances/outputs/static/html/plugins/load.html b/glances/outputs/static/html/plugins/load.html new file mode 100644 index 00000000..32677109 --- /dev/null +++ b/glances/outputs/static/html/plugins/load.html @@ -0,0 +1,24 @@ +
    +
    +
    LOAD
    +
    {{result["load"].cpucore}}-core
    +
    +
    +
    1 min:
    +
    + {{result["load"].min1 | number : 2}} +
    +
    +
    +
    5 min:
    +
    + {{result["load"].min5 | number : 2}} +
    +
    +
    +
    15 min:
    +
    + {{result["load"].min15 | number : 2}} +
    +
    +
    diff --git a/glances/outputs/static/html/plugins/mem.html b/glances/outputs/static/html/plugins/mem.html new file mode 100644 index 00000000..c02ff402 --- /dev/null +++ b/glances/outputs/static/html/plugins/mem.html @@ -0,0 +1,20 @@ +
    +
    +
    MEM
    +
    {{result["mem"].percent}}%
    +
    +
    +
    total:
    +
    {{result["mem"].total | bytes}}
    +
    +
    +
    used:
    +
    + {{result["mem"].used | bytes:2}} +
    +
    +
    +
    free:
    +
    {{result["mem"].free | bytes}}
    +
    +
    diff --git a/glances/outputs/static/html/plugins/mem_more.html b/glances/outputs/static/html/plugins/mem_more.html new file mode 100644 index 00000000..913a17d5 --- /dev/null +++ b/glances/outputs/static/html/plugins/mem_more.html @@ -0,0 +1,18 @@ +
    +
    +
    active:
    +
    {{result["mem"].active | bytes}}
    +
    +
    +
    inactive:
    +
    {{result["mem"].inactive | bytes}}
    +
    +
    +
    buffers:
    +
    {{result["mem"].buffers | bytes}}
    +
    +
    +
    cached:
    +
    {{result["mem"].cached | bytes}}
    +
    +
    diff --git a/glances/outputs/static/html/plugins/memswap.html b/glances/outputs/static/html/plugins/memswap.html new file mode 100644 index 00000000..af9c4025 --- /dev/null +++ b/glances/outputs/static/html/plugins/memswap.html @@ -0,0 +1,20 @@ +
    +
    +
    SWAP
    +
    {{result["memswap"].percent}}%
    +
    +
    +
    total:
    +
    {{result["memswap"].total | bytes}}
    +
    +
    +
    used:
    +
    + {{result["memswap"].used | bytes}} +
    +
    +
    +
    free:
    +
    {{result["memswap"].free | bytes}}
    +
    +
    diff --git a/glances/outputs/static/html/plugins/monitor.html b/glances/outputs/static/html/plugins/monitor.html new file mode 100644 index 00000000..01ded842 --- /dev/null +++ b/glances/outputs/static/html/plugins/monitor.html @@ -0,0 +1,3 @@ +
    + +
    diff --git a/glances/outputs/static/html/plugins/network.html b/glances/outputs/static/html/plugins/network.html new file mode 100644 index 00000000..1f1a4016 --- /dev/null +++ b/glances/outputs/static/html/plugins/network.html @@ -0,0 +1,12 @@ +
    +
    NETWORK
    +
    Rx/s
    +
    Tx/s
    +
    +
    +
    {{network.interface_name | min_size}}
    +
    {{network.rx | bytes}}
    +
    {{network.tx | bytes}}
    +
    {{network.rx | bits}}
    +
    {{network.tx | bits}}
    +
    diff --git a/glances/outputs/static/html/plugins/processcount.html b/glances/outputs/static/html/plugins/processcount.html new file mode 100644 index 00000000..a787edd3 --- /dev/null +++ b/glances/outputs/static/html/plugins/processcount.html @@ -0,0 +1,6 @@ +TASKS +{{result["processcount"].total}} ({{result["processcount"].thread}} thr), +{{result["processcount"].running}} run, +{{result["processcount"].sleeping}} slp, +{{result["processcount"].stopped}} oth + sorted {{ sorter.auto ? 'automatically' : '' }} by {{ sorter.getColumnLabel(sorter.column) }}, flat view diff --git a/glances/outputs/static/html/plugins/processlist.html b/glances/outputs/static/html/plugins/processlist.html new file mode 100644 index 00000000..d738721b --- /dev/null +++ b/glances/outputs/static/html/plugins/processlist.html @@ -0,0 +1,33 @@ +
    +
    +
    CPU%
    +
    MEM%
    + + +
    PID
    +
    USER
    +
    NI
    +
    S
    + + + +
    Command
    +
    +
    +
    {{process.cpu_percent | number:1}}
    +
    {{process.memory_percent | number:1}}
    + + +
    {{process.pid}}
    +
    {{process.username}}
    +
    {{process.nice | exclamation}}
    +
    {{process.status}}
    + + + +
    {{process.name}}
    +
    {{process.cmdline}}
    +
    +
    diff --git a/glances/outputs/static/html/plugins/sensors.html b/glances/outputs/static/html/plugins/sensors.html new file mode 100644 index 00000000..0ee09581 --- /dev/null +++ b/glances/outputs/static/html/plugins/sensors.html @@ -0,0 +1,13 @@ +
    +
    SENSORS
    +
    +
    +
    {{ sensor.label }}
    +
    {{ sensor.unit }}
    +
    + {{ sensor.value }} +
    +
    + {{ sensor.value }} +
    +
    diff --git a/glances/outputs/static/html/plugins/system.html b/glances/outputs/static/html/plugins/system.html new file mode 100644 index 00000000..6349117d --- /dev/null +++ b/glances/outputs/static/html/plugins/system.html @@ -0,0 +1,3 @@ +{{ result["system"].hostname }} + + diff --git a/glances/outputs/static/html/plugins/uptime.html b/glances/outputs/static/html/plugins/uptime.html new file mode 100644 index 00000000..10222fb4 --- /dev/null +++ b/glances/outputs/static/html/plugins/uptime.html @@ -0,0 +1 @@ +Uptime: {{result["uptime"]}} diff --git a/glances/outputs/static/html/stats.html b/glances/outputs/static/html/stats.html new file mode 100644 index 00000000..6f5598d5 --- /dev/null +++ b/glances/outputs/static/html/stats.html @@ -0,0 +1,64 @@ +
    + +
    Loading...
    +
    + +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    diff --git a/glances/outputs/static/images/glances.png b/glances/outputs/static/images/glances.png new file mode 100644 index 00000000..2a8e62ba Binary files /dev/null and b/glances/outputs/static/images/glances.png differ diff --git a/glances/outputs/static/js/app.js b/glances/outputs/static/js/app.js new file mode 100644 index 00000000..4186b40b --- /dev/null +++ b/glances/outputs/static/js/app.js @@ -0,0 +1,13 @@ +var glancesApp = angular.module('glancesApp', ['ngRoute']) + +.config(function($routeProvider, $locationProvider) { + $routeProvider.when('/', { + templateUrl : 'stats.html', + controller : 'statsController' + }).when('/:refresh_time', { + templateUrl : 'stats.html', + controller : 'statsController' + }); + + $locationProvider.html5Mode(true); +}); diff --git a/glances/outputs/static/js/directives.js b/glances/outputs/static/js/directives.js new file mode 100644 index 00000000..d0f48d35 --- /dev/null +++ b/glances/outputs/static/js/directives.js @@ -0,0 +1,78 @@ +glancesApp.directive("sortableTh", function() { + return { + restrict: 'A', + scope: { + sorter: '=' + }, + link: function (scope, element, attrs) { + + scope.$watch(function() { + return scope.sorter.column; + }, function(newValue, oldValue) { + + if (angular.isArray(newValue)) { + if (newValue.indexOf(attrs.column) !== -1) { + element.addClass('sort'); + } else { + element.removeClass('sort'); + } + } else { + if (attrs.column === newValue) { + element.addClass('sort'); + } else { + element.removeClass('sort'); + } + } + + }); + + element.on('click', function() { + + scope.sorter.column = attrs.column; + + scope.$apply(); + }); + } + }; +}); + +glancesApp.directive("glMonitorList", function() { + return { + restrict: 'AE', + scope: { + processes: '=' + }, + templateUrl: 'plugins/monitor.html', + controller: function() { + + } + } +}) + +glancesApp.directive("glMonitorProcess", function() { + return { + restrict: 'AE', + require: "^glMonitorList", + templateUrl: 'components/monitor_process.html', + scope: { + process: '=' + }, + link: function(scope, element, attrs) { + + count = scope.process.count; + countMin = scope.process.countmin; + countMax = scope.process.countmax; + + if (count > 0) { + if ((countMin == null || count >= countMin) && (countMax == null || count <= countMax)) { + scope.descriptionClass = 'ok'; + } else { + scope.descriptionClass = 'careful'; + } + } else { + scope.descriptionClass = countMin == null ? 'ok' : 'critical'; + } + + } + } +}); diff --git a/glances/outputs/static/js/filters.js b/glances/outputs/static/js/filters.js new file mode 100644 index 00000000..cab65529 --- /dev/null +++ b/glances/outputs/static/js/filters.js @@ -0,0 +1,86 @@ +glancesApp.filter('min_size', function() { + return function(input) { + var max = 8; + if (input.length > max) { + return "_" + input.substring(input.length - max) + } + return input + }; +}); +glancesApp.filter('exclamation', function() { + return function(input) { + if (input === undefined || input === '') { + return '?'; + } + return input; + }; +}); + +glancesApp.filter('bytes', function() { + return function (bytes, low_precision) { + low_precision = low_precision || false; + if (isNaN(parseFloat(bytes)) || !isFinite(bytes) || bytes == 0){ + return '0'; + } + + var symbols = ['K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; + var prefix = { + 'Y': 1208925819614629174706176, + 'Z': 1180591620717411303424, + 'E': 1152921504606846976, + 'P': 1125899906842624, + 'T': 1099511627776, + 'G': 1073741824, + 'M': 1048576, + 'K': 1024 + }; + + var reverseSymbols = _(symbols).reverse().value(); + for (var i = 0; i < reverseSymbols.length; i++) { + var symbol = reverseSymbols[i]; + var value = bytes / prefix[symbol]; + + if(value > 1) { + var decimal_precision = 0; + + if(value < 10) { + decimal_precision = 2; + } + else if(value < 100) { + decimal_precision = 1; + } + + if(low_precision) { + if(symbol == 'MK') { + decimal_precision = 0; + } + else { + decimal_precision = _.min([1, decimal_precision]); + } + } + else if(symbol == 'K') { + decimal_precision = 0; + } + + return parseFloat(value).toFixed(decimal_precision) + symbol; + } + } + + return bytes; + } +}); + +glancesApp.filter('bits', function($filter) { + return function (bits, low_precision) { + bits = Math.round(bits) * 8; + return $filter('bytes')(bits, low_precision) + 'b'; + } +}); + +glancesApp.filter('leftPad', function($filter) { + return function (value, length, chars) { + length = length || 0; + chars = chars || ' '; + return _.padLeft(value, length, chars); + } +}); diff --git a/glances/outputs/static/js/modernizr.custom.js b/glances/outputs/static/js/modernizr.custom.js deleted file mode 100755 index c6ead250..00000000 --- a/glances/outputs/static/js/modernizr.custom.js +++ /dev/null @@ -1,4 +0,0 @@ -/* Modernizr 2.8.2 (Custom Build) | MIT & BSD - * Build: http://modernizr.com/download/#-touch-shiv-cssclasses-teststyles-prefixes-load - */ -;window.Modernizr=function(a,b,c){function w(a){j.cssText=a}function x(a,b){return w(m.join(a+";")+(b||""))}function y(a,b){return typeof a===b}function z(a,b){return!!~(""+a).indexOf(b)}function A(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:y(f,"function")?f.bind(d||b):f}return!1}var d="2.8.2",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m=" -webkit- -moz- -o- -ms- ".split(" "),n={},o={},p={},q=[],r=q.slice,s,t=function(a,c,d,e){var f,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:h+(d+1),l.appendChild(j);return f=["­",'"].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},u={}.hasOwnProperty,v;!y(u,"undefined")&&!y(u.call,"undefined")?v=function(a,b){return u.call(a,b)}:v=function(a,b){return b in a&&y(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=r.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(r.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(r.call(arguments)))};return e}),n.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:t(["@media (",m.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c};for(var B in n)v(n,B)&&(s=B.toLowerCase(),e[s]=n[B](),q.push((e[s]?"":"no-")+s));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)v(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},w(""),i=k=null,function(a,b){function l(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function m(){var a=s.elements;return typeof a=="string"?a.split(" "):a}function n(a){var b=j[a[h]];return b||(b={},i++,a[h]=i,j[i]=b),b}function o(a,c,d){c||(c=b);if(k)return c.createElement(a);d||(d=n(c));var g;return d.cache[a]?g=d.cache[a].cloneNode():f.test(a)?g=(d.cache[a]=d.createElem(a)).cloneNode():g=d.createElem(a),g.canHaveChildren&&!e.test(a)&&!g.tagUrn?d.frag.appendChild(g):g}function p(a,c){a||(a=b);if(k)return a.createDocumentFragment();c=c||n(a);var d=c.frag.cloneNode(),e=0,f=m(),g=f.length;for(;e",g="hidden"in a,k=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){g=!0,k=!0}})();var s={elements:d.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:c,shivCSS:d.shivCSS!==!1,supportsUnknownElements:k,shivMethods:d.shivMethods!==!1,type:"default",shivDocument:r,createElement:o,createDocumentFragment:p};a.html5=s,r(b)}(this,b),e._version=d,e._prefixes=m,e.testStyles=t,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+q.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f= 1) { + $scope.refreshTime = new_refresh_time + } + } + } + + $scope.init_limits = function() { + $http.get('/api/2/all/limits').success(function(response, status, headers, config) { + $scope.pluginLimits = response + }).error(function(response, status, headers, config) { + console.log('error : ' + response+ status + headers + config); + }); + } + + $scope.init_help = function() { + $http.get('/api/2/help').success(function(response, status, headers, config) { + $scope.help = response + }); + } + + $scope.show_hide = function(bloc) { + if(bloc == 'help') { + $scope.help_screen = !$scope.help_screen + } else { + $scope.show[bloc] = !$scope.show[bloc] + } + } + + var canceler = undefined; + + /** + * Refresh all the data of the view + */ + $scope.refreshData = function() { + canceler = $q.defer(); + $http.get('/api/2/all', {timeout: canceler.promise}).success(function(response, status, headers, config) { + + function timemillis(array) { + var sum = 0.0 + for (var i = 0; i < array.length; i++) { + sum += array[i] * 1000.0; + } + return sum; + } + function timedelta(input) { + var sum = timemillis(input); + var d = new Date(sum); + + return { + hours: d.getUTCHours(), // TODO : multiple days ( * (d.getDay() * 24))) + minutes: d.getUTCMinutes(), + seconds: d.getUTCSeconds(), + milliseconds: parseInt("" + d.getUTCMilliseconds() / 10) + }; + }; + + function durationBetweenTwoDates(startDate, endDate) { + var duration = endDate - startDate; + var seconds = parseInt((duration/1000)%60) + , minutes = parseInt((duration/(1000*60))%60) + , hours = parseInt((duration/(1000*60*60))%24); + + return _.padLeft(hours,2,'0') + ":" + _.padLeft(minutes,2,'0') + ":" + _.padLeft(seconds,2,'0'); + } + + for (var i = 0; i < response['processlist'].length; i++) { + var process = response['processlist'][i] + process.memvirt = process.memory_info[1] + process.memres = process.memory_info[0] + process.timeplus = timedelta(process.cpu_times) + process.timemillis = timemillis(process.cpu_times) + + process.io_read = '?'; + process.io_write = '?'; + + if (process.io_counters) { + process.io_read = (process.io_counters[0] - process.io_counters[2]) / process.time_since_update; + + if (process.io_read != 0) { + process.io_read = $filter('bytes')(process.io_read); + } + + process.io_write = (process.io_counters[1] - process.io_counters[3]) / process.time_since_update; + + if (process.io_write != 0) { + process.io_write = $filter('bytes')(process.io_write); + } + } + } + for (var i = 0; i < response['alert'].length; i++) { + var alert = response['alert'][i]; + alert.begin = alert[0] * 1000; + alert.end = alert[1] * 1000; + alert.ongoing = alert[1] == -1; + + if (!alert.ongoing) { + alert.duration = durationBetweenTwoDates(alert.begin, alert.end); + } + } + + $scope.is_bsd = response['system'].os_name === 'FreeBSD'; + $scope.is_linux = response['system'].os_name === 'Linux'; + $scope.is_mac = response['system'].os_name === 'Darwin'; + $scope.is_windows = response['system'].os_name === 'Windows'; + + $scope.result = response; + canceler.resolve() + }).error(function(d, status, headers, config) { + console.log('error status:' + status + " - headers = " + headers); + canceler.resolve() + }); + } + + $scope.isNice = function(nice) { + if(nice !== undefined && (($scope.is_windows && nice != 32) || (!$scope.is_windows && nice != 0))) { + return true; + } + + return false; + } + + $scope.getAlert = function(pluginName, limitNamePrefix, current, maximum, log) { + current = current || 0; + maximum = maximum || 100; + log = log || false; + log_str = log ? '_log' : ''; + + var value = (current * 100) / maximum; + + if ($scope.pluginLimits != undefined && $scope.pluginLimits[pluginName] != undefined) { + for (var i = 0; i < $scope.limitSuffix.length; i++) { + var limitName = limitNamePrefix + $scope.limitSuffix[i] + var limit = $scope.pluginLimits[pluginName][limitName] + + if (value >= limit) { + var pos = limitName.lastIndexOf("_") + var className = limitName.substring(pos + 1) + + return className + log_str; + } + } + } + + return "ok" + log_str; + } + + $scope.getAlertLog = function(pluginName, limitNamePrefix, current, maximum) { + return $scope.getAlert(pluginName, limitNamePrefix, current, maximum, true); + } + + $scope.init_refresh_time(); + $scope.init_limits(); + $scope.init_help(); + + var stop; + $scope.configure_refresh = function () { + if (!angular.isDefined(stop)) { + //$scope.refreshData(); + stop = $interval(function() { + $scope.refreshData(); + }, $scope.refreshTime * 1000); // in milliseconds + } + } + + $scope.$watch( + function() { return $scope.refreshTime; }, + function(newValue, oldValue) { + $scope.stop_refresh(); + $scope.configure_refresh(); + } + ); + + $scope.stop_refresh = function() { + if (angular.isDefined(stop)) { + $interval.cancel(stop); + stop = undefined; + } + }; + + $scope.$on('$destroy', function() { + // Make sure that the interval is destroyed too + $scope.stop_refresh(); + }); + + $scope.onKeyDown = function($event) { + if ($event.keyCode == keycodes.a) { // a Sort processes automatically + $scope.sorter.column = "cpu_percent"; + $scope.sorter.auto = true; + } else if ($event.keyCode == keycodes.c) {//c Sort processes by CPU% + $scope.sorter.column = "cpu_percent"; + $scope.sorter.auto = false; + } else if ($event.keyCode == keycodes.m) {//m Sort processes by MEM% + $scope.sorter.column = "memory_percent"; + $scope.sorter.auto = false; + } else if ($event.keyCode == keycodes.p) {//p Sort processes by name + $scope.sorter.column = "name"; + $scope.sorter.auto = false; + } else if ($event.keyCode == keycodes.i) {//i Sort processes by I/O rate + $scope.sorter.column = ['io_read', 'io_write']; + $scope.sorter.auto = false; + } else if ($event.keyCode == keycodes.t) {//t Sort processes by CPU times + $scope.sorter.column = "timemillis"; + $scope.sorter.auto = false; + } else if ($event.keyCode == keycodes.u) {//t Sort processes by user + $scope.sorter.column = "username"; + $scope.sorter.auto = false; + } else if ($event.keyCode == keycodes.d) {//d Show/hide disk I/O stats + $scope.show_hide('diskio') + } else if ($event.keyCode == keycodes.f) {//f Show/hide filesystem stats + $scope.show_hide('fs') + } else if ($event.keyCode == keycodes.n) {//n sort_by Show/hide network stats + $scope.show_hide('network') + } else if ($event.keyCode == keycodes.s) {//s Show/hide sensors stats + $scope.show_hide('sensors') + } else if ($event.keyCode == keycodes.TWO && $event.shiftKey) {//2 Show/hide left sidebar + $scope.show_hide('sidebar') + } else if ($event.keyCode == keycodes.z) {//z Enable/disable processes stats + $scope.show_hide('process_stats') + } else if ($event.keyCode == keycodes.e) {//e Enable/disable top extended stats + $scope.show_hide('top_extended_stats') + } else if ($event.keyCode == keycodes.SLASH) {// SLASH Enable/disable short processes name + $scope.show_hide('short_process_name') + } else if ($event.keyCode == keycodes.D && $event.shiftKey) {//D Enable/disable Docker stats + $scope.show_hide('docker_stats') + } else if ($event.keyCode == keycodes.b) {//b Bytes or bits for network I/O + $scope.show_hide('network_by_bytes') + } else if ($event.keyCode == keycodes.l) {//l Show/hide alert logs + $scope.show_hide('alert') + } else if ($event.keyCode == keycodes.w) {//w Delete warning alerts + $scope.show_hide('warning_alerts') + } else if ($event.keyCode == keycodes.x) {//x Delete warning and critical alerts + $scope.show_hide('warning_critical_alerts') + } else if ($event.keyCode == keycodes.ONE && $event.shiftKey) {//1 Global CPU or per-CPU stats + $scope.show_hide('per_cpu') + } else if ($event.keyCode == keycodes.h) {//h Show/hide this help screen + $scope.show_hide('help') + } else if ($event.keyCode == keycodes.T && $event.shiftKey) {//T View network I/O as combination + $scope.show_hide('network_io_combination') + } else if ($event.keyCode == keycodes.u) {//u View cumulative network I/O + $scope.show_hide('network_io_cumulative') + } else if ($event.keyCode == keycodes.F && $event.shiftKey) {//F Show filesystem free space + $scope.show_hide('filesystem_freespace') + } else if ($event.keyCode == keycodes.g) {//g Generate graphs for current history + // not available + } else if ($event.keyCode == keycodes.r) {//r Reset history + // not available + } else if ($event.keyCode == keycodes.q) {//q Quit (Esc and Ctrl-C also work) + // not available + } + } +}); diff --git a/glances/outputs/static/js/variables.js b/glances/outputs/static/js/variables.js new file mode 100644 index 00000000..6537b500 --- /dev/null +++ b/glances/outputs/static/js/variables.js @@ -0,0 +1,30 @@ +var keycodes = { + 'a' : '65', + 'c' : '67', + 'm' : '77', + 'p' : '80', + 'i' : '73', + 't' : '84', + 'u' : '85', + 'd' : '68', + 'f' : '70', + 'n' : '78', + 's' : '83', + 'TWO': '50', + 'z' : '90', + 'e' : '69', + 'SLASH': '191', + 'D' : '68', + 'b' : '66', + 'l' : '76', + 'w' : '87', + 'x' : '88', + 'ONE': '49', + 'h' : '72', + 'T' : '84', + 'u' : '85', + 'F' : '70', + 'g' : '71', + 'r' : '82', + 'q' : '81' +} diff --git a/glances/outputs/static/js/vendors/angular-route.min.js b/glances/outputs/static/js/vendors/angular-route.min.js new file mode 100644 index 00000000..4e533cd1 --- /dev/null +++ b/glances/outputs/static/js/vendors/angular-route.min.js @@ -0,0 +1,15 @@ + +/* + AngularJS v1.2.28 + (c) 2010-2014 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(n,e,A){'use strict';function x(s,g,h){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(a,c,b,f,w){function y(){p&&(p.remove(),p=null);k&&(k.$destroy(),k=null);l&&(h.leave(l,function(){p=null}),p=l,l=null)}function v(){var b=s.current&&s.current.locals;if(e.isDefined(b&&b.$template)){var b=a.$new(),d=s.current;l=w(b,function(d){h.enter(d,null,l||c,function(){!e.isDefined(t)||t&&!a.$eval(t)||g()});y()});k=d.scope=b;k.$emit("$viewContentLoaded");k.$eval(u)}else y()} +var k,l,p,t=b.autoscroll,u=b.onload||"";a.$on("$routeChangeSuccess",v);v()}}}function z(e,g,h){return{restrict:"ECA",priority:-400,link:function(a,c){var b=h.current,f=b.locals;c.html(f.$template);var w=e(c.contents());b.controller&&(f.$scope=a,f=g(b.controller,f),b.controllerAs&&(a[b.controllerAs]=f),c.data("$ngControllerController",f),c.children().data("$ngControllerController",f));w(a)}}}n=e.module("ngRoute",["ng"]).provider("$route",function(){function s(a,c){return e.extend(new (e.extend(function(){}, +{prototype:a})),c)}function g(a,e){var b=e.caseInsensitiveMatch,f={originalPath:a,regexp:a},h=f.keys=[];a=a.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)([\?\*])?/g,function(a,e,b,c){a="?"===c?c:null;c="*"===c?c:null;h.push({name:b,optional:!!a});e=e||"";return""+(a?"":e)+"(?:"+(a?e:"")+(c&&"(.+?)"||"([^/]+)")+(a||"")+")"+(a||"")}).replace(/([\/$\*])/g,"\\$1");f.regexp=RegExp("^"+a+"$",b?"i":"");return f}var h={};this.when=function(a,c){h[a]=e.extend({reloadOnSearch:!0},c,a&&g(a,c));if(a){var b= +"/"==a[a.length-1]?a.substr(0,a.length-1):a+"/";h[b]=e.extend({redirectTo:a},g(b,c))}return this};this.otherwise=function(a){this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$http","$templateCache","$sce",function(a,c,b,f,g,n,v,k){function l(){var d=p(),m=r.current;if(d&&m&&d.$$route===m.$$route&&e.equals(d.pathParams,m.pathParams)&&!d.reloadOnSearch&&!u)m.params=d.params,e.copy(m.params,b),a.$broadcast("$routeUpdate",m);else if(d||m)u=!1,a.$broadcast("$routeChangeStart", +d,m),(r.current=d)&&d.redirectTo&&(e.isString(d.redirectTo)?c.path(t(d.redirectTo,d.params)).search(d.params).replace():c.url(d.redirectTo(d.pathParams,c.path(),c.search())).replace()),f.when(d).then(function(){if(d){var a=e.extend({},d.resolve),c,b;e.forEach(a,function(d,c){a[c]=e.isString(d)?g.get(d):g.invoke(d)});e.isDefined(c=d.template)?e.isFunction(c)&&(c=c(d.params)):e.isDefined(b=d.templateUrl)&&(e.isFunction(b)&&(b=b(d.params)),b=k.getTrustedResourceUrl(b),e.isDefined(b)&&(d.loadedTemplateUrl= +b,c=n.get(b,{cache:v}).then(function(a){return a.data})));e.isDefined(c)&&(a.$template=c);return f.all(a)}}).then(function(c){d==r.current&&(d&&(d.locals=c,e.copy(d.params,b)),a.$broadcast("$routeChangeSuccess",d,m))},function(c){d==r.current&&a.$broadcast("$routeChangeError",d,m,c)})}function p(){var a,b;e.forEach(h,function(f,h){var q;if(q=!b){var g=c.path();q=f.keys;var l={};if(f.regexp)if(g=f.regexp.exec(g)){for(var k=1,p=g.length;k").append(b).html();try{return 3===b[0].nodeType?x(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+x(b)})}catch(d){return x(c)}}function bc(b){try{return decodeURIComponent(b)}catch(a){}}function cc(b){var a={},c,d;r((b||"").split("&"),function(b){b&&(c=b.replace(/\+/g,"%20").split("="),d=bc(c[0]),D(d)&&(b=D(c[1])?bc(c[1]):!0,lb.call(a,d)?L(a[d])?a[d].push(b):a[d]=[a[d],b]:a[d]=b))});return a}function Cb(b){var a= +[];r(b,function(b,d){L(b)?r(b,function(b){a.push(Da(d,!0)+(!0===b?"":"="+Da(b,!0)))}):a.push(Da(d,!0)+(!0===b?"":"="+Da(b,!0)))});return a.length?a.join("&"):""}function mb(b){return Da(b,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function Da(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,a?"%20":"+")}function Wc(b,a){function c(a){a&&d.push(a)}var d=[b],e,f,g=["ng:app","ng-app","x-ng-app", +"data-ng-app"],h=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;r(g,function(a){g[a]=!0;c(X.getElementById(a));a=a.replace(":","\\:");b.querySelectorAll&&(r(b.querySelectorAll("."+a),c),r(b.querySelectorAll("."+a+"\\:"),c),r(b.querySelectorAll("["+a+"]"),c))});r(d,function(a){if(!e){var b=h.exec(" "+a.className+" ");b?(e=a,f=(b[2]||"").replace(/\s+/g,",")):r(a.attributes,function(b){!e&&g[b.name]&&(e=a,f=b.value)})}});e&&a(e,f?[f]:[])}function dc(b,a){var c=function(){b=A(b);if(b.injector()){var c=b[0]===X? +"document":ia(b);throw Va("btstrpd",c.replace(//,">"));}a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);a.unshift("ng");c=ec(a);c.invoke(["$rootScope","$rootElement","$compile","$injector","$animate",function(a,b,c,d,e){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return c},d=/^NG_DEFER_BOOTSTRAP!/;if(W&&!d.test(W.name))return c();W.name=W.name.replace(d,"");Xa.resumeBootstrap=function(b){r(b,function(b){a.push(b)});c()}}function nb(b,a){a= +a||"_";return b.replace(Xc,function(b,d){return(d?a:"")+b.toLowerCase()})}function Db(b,a,c){if(!b)throw Va("areq",a||"?",c||"required");return b}function Ya(b,a,c){c&&L(b)&&(b=b[b.length-1]);Db(N(b),a,"not a function, got "+(b&&"object"===typeof b?b.constructor.name||"Object":typeof b));return b}function Ea(b,a){if("hasOwnProperty"===b)throw Va("badname",a);}function fc(b,a,c){if(!a)return b;a=a.split(".");for(var d,e=b,f=a.length,g=0;g 
    "+e[1]+a.replace(le,"<$1>")+e[2];d.removeChild(d.firstChild);for(a=e[0];a--;)d=d.lastChild;a=0;for(e=d.childNodes.length;a=R?(c.preventDefault=null,c.stopPropagation=null,c.isDefaultPrevented=null):(delete c.preventDefault,delete c.stopPropagation,delete c.isDefaultPrevented)};c.elem=b;return c}function Na(b,a){var c=typeof b,d;"function"==c||"object"==c&&null!==b?"function"==typeof(d= +b.$$hashKey)?d=b.$$hashKey():d===u&&(d=b.$$hashKey=(a||ib)()):d=b;return c+":"+d}function db(b,a){if(a){var c=0;this.nextUid=function(){return++c}}r(b,this.put,this)}function qc(b){var a,c;"function"===typeof b?(a=b.$inject)||(a=[],b.length&&(c=b.toString().replace(oe,""),c=c.match(pe),r(c[1].split(qe),function(b){b.replace(re,function(b,c,d){a.push(d)})})),b.$inject=a):L(b)?(c=b.length-1,Ya(b[c],"fn"),a=b.slice(0,c)):Ya(b,"fn",!0);return a}function ec(b){function a(a){return function(b,c){if(T(b))r(b, +Yb(a));else return a(b,c)}}function c(a,b){Ea(a,"service");if(N(b)||L(b))b=n.instantiate(b);if(!b.$get)throw eb("pget",a);return l[a+h]=b}function d(a,b){return c(a,{$get:b})}function e(a){var b=[],c,d,f,h;r(a,function(a){if(!m.get(a)){m.put(a,!0);try{if(G(a))for(c=$a(a),b=b.concat(e(c.requires)).concat(c._runBlocks),d=c._invokeQueue,f=0,h=d.length;f 4096 bytes)!"));else{if(k.cookie!== +ca)for(ca=k.cookie,d=ca.split("; "),M={},f=0;fm&&this.remove(q.key),b},get:function(a){if(m").parent()[0])});var f=O(a,b,a,c,d,e);ba(a,"ng-scope");return function(b,c,d,e){Db(b,"scope");var g=c?Oa.clone.call(a):a;r(d,function(a,b){g.data("$"+b+"Controller",a)});d=0;for(var k=g.length;darguments.length&& +(b=a,a=u);Ia&&(c=ca);return n(a,b,c)}var y,Q,B,M,C,P,ca={},ra;y=c===f?d:ha(d,new Ob(A(f),d.$attr));Q=y.$$element;if(K){var ue=/^\s*([@=&])(\??)\s*(\w*)\s*$/;P=e.$new(!0);!I||I!==K&&I!==K.$$originalDirective?Q.data("$isolateScopeNoTemplate",P):Q.data("$isolateScope",P);ba(Q,"ng-isolate-scope");r(K.scope,function(a,c){var d=a.match(ue)||[],f=d[3]||c,g="?"==d[2],d=d[1],k,l,n,q;P.$$isolateBindings[c]=d+f;switch(d){case "@":y.$observe(f,function(a){P[c]=a});y.$$observers[f].$$scope=e;y[f]&&(P[c]=b(y[f])(e)); +break;case "=":if(g&&!y[f])break;l=p(y[f]);q=l.literal?Ca:function(a,b){return a===b||a!==a&&b!==b};n=l.assign||function(){k=P[c]=l(e);throw ja("nonassign",y[f],K.name);};k=P[c]=l(e);P.$watch(function(){var a=l(e);q(a,P[c])||(q(a,k)?n(e,a=P[c]):P[c]=a);return k=a},null,l.literal);break;case "&":l=p(y[f]);P[c]=function(a){return l(e,a)};break;default:throw ja("iscp",K.name,c,a);}})}ra=n&&w;O&&r(O,function(a){var b={$scope:a===K||a.$$isolateScope?P:e,$element:Q,$attrs:y,$transclude:ra},c;C=a.controller; +"@"==C&&(C=y[a.name]);c=s(C,b);ca[a.name]=c;Ia||Q.data("$"+a.name+"Controller",c);a.controllerAs&&(b.$scope[a.controllerAs]=c)});g=0;for(B=k.length;gH.priority)break;if(V=H.scope)M=M||H,H.templateUrl||(fb("new/isolated scope",K,H,x),T(V)&&(K=H));z=H.name;!H.templateUrl&&H.controller&&(V=H.controller,O=O||{},fb("'"+z+"' controller",O[z],H,x),O[z]=H);if(V=H.transclude)F=!0,H.$$tlb|| +(fb("transclusion",ea,H,x),ea=H),"element"==V?(Ia=!0,y=H.priority,V=x,x=d.$$element=A(X.createComment(" "+z+": "+d[z]+" ")),c=x[0],ra(f,wa.call(V,0),c),S=B(V,e,y,g&&g.name,{nonTlbTranscludeDirective:ea})):(V=A(Kb(c)).contents(),x.empty(),S=B(V,e));if(H.template)if(E=!0,fb("template",I,H,x),I=H,V=N(H.template)?H.template(x,d):H.template,V=W(V),H.replace){g=H;V=Ib.test(V)?A($(V)):[];c=V[0];if(1!=V.length||1!==c.nodeType)throw ja("tplrt",z,"");ra(f,x,c);sa={$attr:{}};V=ca(c,[],sa);var Z=a.splice(Ha+ +1,a.length-(Ha+1));K&&D(V);a=a.concat(V).concat(Z);v(d,sa);sa=a.length}else x.html(V);if(H.templateUrl)E=!0,fb("template",I,H,x),I=H,H.replace&&(g=H),J=te(a.splice(Ha,a.length-Ha),x,d,f,F&&S,k,q,{controllerDirectives:O,newIsolateScopeDirective:K,templateDirective:I,nonTlbTranscludeDirective:ea}),sa=a.length;else if(H.compile)try{R=H.compile(x,d,S),N(R)?w(null,R,U,Y):R&&w(R.pre,R.post,U,Y)}catch(ve){l(ve,ia(x))}H.terminal&&(J.terminal=!0,y=Math.max(y,H.priority))}J.scope=M&&!0===M.scope;J.transcludeOnThisElement= +F;J.templateOnThisElement=E;J.transclude=S;n.hasElementTranscludeDirective=Ia;return J}function D(a){for(var b=0,c=a.length;bq.priority)&&-1!=q.restrict.indexOf(f)&&(m&&(q=$b(q,{$$start:m,$$end:n})),b.push(q),p=q)}catch(y){l(y)}}return p}function v(a,b){var c=b.$attr,d=a.$attr,e=a.$$element;r(a,function(d,e){"$"!= +e.charAt(0)&&(b[e]&&b[e]!==d&&(d+=("style"===e?";":" ")+b[e]),a.$set(e,d,!0,c[e]))});r(b,function(b,f){"class"==f?(ba(e,b),a["class"]=(a["class"]?a["class"]+" ":"")+b):"style"==f?(e.attr("style",e.attr("style")+";"+b),a.style=(a.style?a.style+";":"")+b):"$"==f.charAt(0)||a.hasOwnProperty(f)||(a[f]=b,d[f]=c[f])})}function te(a,b,c,d,e,f,g,k){var p=[],l,m,w=b[0],s=a.shift(),y=E({},s,{templateUrl:null,transclude:null,replace:null,$$originalDirective:s}),J=N(s.templateUrl)?s.templateUrl(b,c):s.templateUrl; +b.empty();n.get(t.getTrustedResourceUrl(J),{cache:q}).success(function(q){var n,t;q=W(q);if(s.replace){q=Ib.test(q)?A($(q)):[];n=q[0];if(1!=q.length||1!==n.nodeType)throw ja("tplrt",s.name,J);q={$attr:{}};ra(d,b,n);var B=ca(n,[],q);T(s.scope)&&D(B);a=B.concat(a);v(c,q)}else n=w,b.html(q);a.unshift(y);l=I(a,n,c,e,b,s,f,g,k);r(d,function(a,c){a==n&&(d[c]=b[0])});for(m=O(b[0].childNodes,e);p.length;){q=p.shift();t=p.shift();var K=p.shift(),C=p.shift(),B=b[0];if(t!==w){var P=t.className;k.hasElementTranscludeDirective&& +s.replace||(B=Kb(n));ra(K,A(t),B);ba(A(B),P)}t=l.transcludeOnThisElement?M(q,l.transclude,C):C;l(m,q,B,d,t)}p=null}).error(function(a,b,c,d){throw ja("tpload",d.url);});return function(a,b,c,d,e){a=e;p?(p.push(b),p.push(c),p.push(d),p.push(a)):(l.transcludeOnThisElement&&(a=M(b,l.transclude,e)),l(m,b,c,d,a))}}function F(a,b){var c=b.priority-a.priority;return 0!==c?c:a.name!==b.name?a.namea.status?d:n.reject(d)}var c={method:"get",transformRequest:e.transformRequest,transformResponse:e.transformResponse},d=function(a){var b=e.headers,c=E({},a.headers),d,f,b=E({},b.common,b[x(a.method)]); +a:for(d in b){a=x(d);for(f in c)if(x(f)===a)continue a;c[d]=b[d]}(function(a){var b;r(a,function(c,d){N(c)&&(b=c(),null!=b?a[d]=b:delete a[d])})})(c);return c}(a);E(c,a);c.headers=d;c.method=La(c.method);var f=[function(a){d=a.headers;var c=vc(a.data,uc(d),a.transformRequest);F(c)&&r(d,function(a,b){"content-type"===x(b)&&delete d[b]});F(a.withCredentials)&&!F(e.withCredentials)&&(a.withCredentials=e.withCredentials);return s(a,c,d).then(b,b)},u],g=n.when(c);for(r(t,function(a){(a.request||a.requestError)&& +f.unshift(a.request,a.requestError);(a.response||a.responseError)&&f.push(a.response,a.responseError)});f.length;){a=f.shift();var h=f.shift(),g=g.then(a,h)}g.success=function(a){g.then(function(b){a(b.data,b.status,b.headers,c)});return g};g.error=function(a){g.then(null,function(b){a(b.data,b.status,b.headers,c)});return g};return g}function s(c,f,g){function m(a,b,c,e){C&&(200<=a&&300>a?C.put(A,[a,b,tc(c),e]):C.remove(A));q(b,a,c,e);d.$$phase||d.$apply()}function q(a,b,d,e){b=Math.max(b,0);(200<= +b&&300>b?t.resolve:t.reject)({data:a,status:b,headers:uc(d),config:c,statusText:e})}function s(){var a=Ta(p.pendingRequests,c);-1!==a&&p.pendingRequests.splice(a,1)}var t=n.defer(),r=t.promise,C,I,A=J(c.url,c.params);p.pendingRequests.push(c);r.then(s,s);!c.cache&&!e.cache||(!1===c.cache||"GET"!==c.method&&"JSONP"!==c.method)||(C=T(c.cache)?c.cache:T(e.cache)?e.cache:w);if(C)if(I=C.get(A),D(I)){if(I&&N(I.then))return I.then(s,s),I;L(I)?q(I[1],I[0],ha(I[2]),I[3]):q(I,200,{},"OK")}else C.put(A,r);F(I)&& +((I=Pb(c.url)?b.cookies()[c.xsrfCookieName||e.xsrfCookieName]:u)&&(g[c.xsrfHeaderName||e.xsrfHeaderName]=I),a(c.method,A,f,m,g,c.timeout,c.withCredentials,c.responseType));return r}function J(a,b){if(!b)return a;var c=[];Sc(b,function(a,b){null===a||F(a)||(L(a)||(a=[a]),r(a,function(a){T(a)&&(a=va(a)?a.toISOString():oa(a));c.push(Da(b)+"="+Da(a))}))});0=R&&(!b.match(/^(get|post|head|put|delete|options)$/i)|| +!W.XMLHttpRequest))return new W.ActiveXObject("Microsoft.XMLHTTP");if(W.XMLHttpRequest)return new W.XMLHttpRequest;throw z("$httpBackend")("noxhr");}function Ud(){this.$get=["$browser","$window","$document",function(b,a,c){return ye(b,xe,b.defer,a.angular.callbacks,c[0])}]}function ye(b,a,c,d,e){function f(a,b,c){var f=e.createElement("script"),g=null;f.type="text/javascript";f.src=a;f.async=!0;g=function(a){bb(f,"load",g);bb(f,"error",g);e.body.removeChild(f);f=null;var h=-1,s="unknown";a&&("load"!== +a.type||d[b].called||(a={type:"error"}),s=a.type,h="error"===a.type?404:200);c&&c(h,s)};sb(f,"load",g);sb(f,"error",g);8>=R&&(f.onreadystatechange=function(){G(f.readyState)&&/loaded|complete/.test(f.readyState)&&(f.onreadystatechange=null,g({type:"load"}))});e.body.appendChild(f);return g}var g=-1;return function(e,k,m,l,n,q,p,s){function J(){t=g;K&&K();B&&B.abort()}function w(a,d,e,f,g){O&&c.cancel(O);K=B=null;0===d&&(d=e?200:"file"==xa(k).protocol?404:0);a(1223===d?204:d,e,f,g||"");b.$$completeOutstandingRequest(v)} +var t;b.$$incOutstandingRequestCount();k=k||b.url();if("jsonp"==x(e)){var y="_"+(d.counter++).toString(36);d[y]=function(a){d[y].data=a;d[y].called=!0};var K=f(k.replace("JSON_CALLBACK","angular.callbacks."+y),y,function(a,b){w(l,a,d[y].data,"",b);d[y]=v})}else{var B=a(e);B.open(e,k,!0);r(n,function(a,b){D(a)&&B.setRequestHeader(b,a)});B.onreadystatechange=function(){if(B&&4==B.readyState){var a=null,b=null,c="";t!==g&&(a=B.getAllResponseHeaders(),b="response"in B?B.response:B.responseText);t===g&& +10>R||(c=B.statusText);w(l,t||B.status,b,a,c)}};p&&(B.withCredentials=!0);if(s)try{B.responseType=s}catch(ba){if("json"!==s)throw ba;}B.send(m||null)}if(0=h&&(n.resolve(p),l(q.$$intervalId),delete e[q.$$intervalId]);s||b.$apply()},g);e[q.$$intervalId]=n;return q}var e={};d.cancel= +function(b){return b&&b.$$intervalId in e?(e[b.$$intervalId].reject("canceled"),a.clearInterval(b.$$intervalId),delete e[b.$$intervalId],!0):!1};return d}]}function ad(){this.$get=function(){return{id:"en-us",NUMBER_FORMATS:{DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{minInt:1,minFrac:0,maxFrac:3,posPre:"",posSuf:"",negPre:"-",negSuf:"",gSize:3,lgSize:3},{minInt:1,minFrac:2,maxFrac:2,posPre:"\u00a4",posSuf:"",negPre:"(\u00a4",negSuf:")",gSize:3,lgSize:3}],CURRENCY_SYM:"$"},DATETIME_FORMATS:{MONTH:"January February March April May June July August September October November December".split(" "), +SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "),AMPMS:["AM","PM"],medium:"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a",fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",mediumDate:"MMM d, y",shortDate:"M/d/yy",mediumTime:"h:mm:ss a",shortTime:"h:mm a"},pluralCat:function(b){return 1===b?"one":"other"}}}}function Qb(b){b=b.split("/");for(var a=b.length;a--;)b[a]= +mb(b[a]);return b.join("/")}function xc(b,a,c){b=xa(b,c);a.$$protocol=b.protocol;a.$$host=b.hostname;a.$$port=U(b.port)||ze[b.protocol]||null}function yc(b,a,c){var d="/"!==b.charAt(0);d&&(b="/"+b);b=xa(b,c);a.$$path=decodeURIComponent(d&&"/"===b.pathname.charAt(0)?b.pathname.substring(1):b.pathname);a.$$search=cc(b.search);a.$$hash=decodeURIComponent(b.hash);a.$$path&&"/"!=a.$$path.charAt(0)&&(a.$$path="/"+a.$$path)}function ta(b,a){if(0===a.indexOf(b))return a.substr(b.length)}function Ga(b){var a= +b.indexOf("#");return-1==a?b:b.substr(0,a)}function Rb(b){return b.substr(0,Ga(b).lastIndexOf("/")+1)}function zc(b,a){this.$$html5=!0;a=a||"";var c=Rb(b);xc(b,this,b);this.$$parse=function(a){var e=ta(c,a);if(!G(e))throw Sb("ipthprfx",a,c);yc(e,this,b);this.$$path||(this.$$path="/");this.$$compose()};this.$$compose=function(){var a=Cb(this.$$search),b=this.$$hash?"#"+mb(this.$$hash):"";this.$$url=Qb(this.$$path)+(a?"?"+a:"")+b;this.$$absUrl=c+this.$$url.substr(1)};this.$$parseLinkUrl=function(d, +e){var f,g;(f=ta(b,d))!==u?(g=f,g=(f=ta(a,f))!==u?c+(ta("/",f)||f):b+g):(f=ta(c,d))!==u?g=c+f:c==d+"/"&&(g=c);g&&this.$$parse(g);return!!g}}function Tb(b,a){var c=Rb(b);xc(b,this,b);this.$$parse=function(d){var e=ta(b,d)||ta(c,d),e="#"==e.charAt(0)?ta(a,e):this.$$html5?e:"";if(!G(e))throw Sb("ihshprfx",d,a);yc(e,this,b);d=this.$$path;var f=/^\/[A-Z]:(\/.*)/;0===e.indexOf(b)&&(e=e.replace(b,""));f.exec(e)||(d=(e=f.exec(d))?e[1]:d);this.$$path=d;this.$$compose()};this.$$compose=function(){var c=Cb(this.$$search), +e=this.$$hash?"#"+mb(this.$$hash):"";this.$$url=Qb(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=b+(this.$$url?a+this.$$url:"")};this.$$parseLinkUrl=function(a,c){return Ga(b)==Ga(a)?(this.$$parse(a),!0):!1}}function Ac(b,a){this.$$html5=!0;Tb.apply(this,arguments);var c=Rb(b);this.$$parseLinkUrl=function(d,e){var f,g;b==Ga(d)?f=d:(g=ta(c,d))?f=b+a+g:c===d+"/"&&(f=c);f&&this.$$parse(f);return!!f};this.$$compose=function(){var c=Cb(this.$$search),e=this.$$hash?"#"+mb(this.$$hash):"";this.$$url=Qb(this.$$path)+ +(c?"?"+c:"")+e;this.$$absUrl=b+a+this.$$url}}function tb(b){return function(){return this[b]}}function Bc(b,a){return function(c){if(F(c))return this[b];this[b]=a(c);this.$$compose();return this}}function Vd(){var b="",a=!1;this.hashPrefix=function(a){return D(a)?(b=a,this):b};this.html5Mode=function(b){return D(b)?(a=b,this):a};this.$get=["$rootScope","$browser","$sniffer","$rootElement",function(c,d,e,f){function g(a){c.$broadcast("$locationChangeSuccess",h.absUrl(),a)}var h,k=d.baseHref(),m=d.url(); +a?(k=m.substring(0,m.indexOf("/",m.indexOf("//")+2))+(k||"/"),e=e.history?zc:Ac):(k=Ga(m),e=Tb);h=new e(k,"#"+b);h.$$parseLinkUrl(m,m);var l=/^\s*(javascript|mailto):/i;f.on("click",function(a){if(!a.ctrlKey&&!a.metaKey&&2!=a.which){for(var b=A(a.target);"a"!==x(b[0].nodeName);)if(b[0]===f[0]||!(b=b.parent())[0])return;var e=b.prop("href"),g=b.attr("href")||b.attr("xlink:href");T(e)&&"[object SVGAnimatedString]"===e.toString()&&(e=xa(e.animVal).href);l.test(e)||(!e||(b.attr("target")||a.isDefaultPrevented())|| +!h.$$parseLinkUrl(e,g))||(a.preventDefault(),h.absUrl()!=d.url()&&(c.$apply(),W.angular["ff-684208-preventDefault"]=!0))}});h.absUrl()!=m&&d.url(h.absUrl(),!0);d.onUrlChange(function(a){h.absUrl()!=a&&(c.$evalAsync(function(){var b=h.absUrl();h.$$parse(a);c.$broadcast("$locationChangeStart",a,b).defaultPrevented?(h.$$parse(b),d.url(b)):g(b)}),c.$$phase||c.$digest())});var n=0;c.$watch(function(){var a=d.url(),b=h.$$replace;n&&a==h.absUrl()||(n++,c.$evalAsync(function(){c.$broadcast("$locationChangeStart", +h.absUrl(),a).defaultPrevented?h.$$parse(a):(d.url(h.absUrl(),b),g(a))}));h.$$replace=!1;return n});return h}]}function Wd(){var b=!0,a=this;this.debugEnabled=function(a){return D(a)?(b=a,this):b};this.$get=["$window",function(c){function d(a){a instanceof Error&&(a.stack?a=a.message&&-1===a.stack.indexOf(a.message)?"Error: "+a.message+"\n"+a.stack:a.stack:a.sourceURL&&(a=a.message+"\n"+a.sourceURL+":"+a.line));return a}function e(a){var b=c.console||{},e=b[a]||b.log||v;a=!1;try{a=!!e.apply}catch(k){}return a? +function(){var a=[];r(arguments,function(b){a.push(d(b))});return e.apply(b,a)}:function(a,b){e(a,null==b?"":b)}}return{log:e("log"),info:e("info"),warn:e("warn"),error:e("error"),debug:function(){var c=e("debug");return function(){b&&c.apply(a,arguments)}}()}}]}function ka(b,a){if("__defineGetter__"===b||"__defineSetter__"===b||"__lookupGetter__"===b||"__lookupSetter__"===b||"__proto__"===b)throw la("isecfld",a);return b}function ma(b,a){if(b){if(b.constructor===b)throw la("isecfn",a);if(b.document&& +b.location&&b.alert&&b.setInterval)throw la("isecwindow",a);if(b.children&&(b.nodeName||b.prop&&b.attr&&b.find))throw la("isecdom",a);if(b===Object)throw la("isecobj",a);}return b}function ub(b,a,c,d,e){ma(b,d);e=e||{};a=a.split(".");for(var f,g=0;1g?Cc(f[0],f[1],f[2],f[3],f[4],c,a):function(b,d){var e=0,h;do h=Cc(f[e++],f[e++],f[e++],f[e++],f[e++],c,a)(b,d),d=u,b=h;while(eb.length?a=b.length:a<-b.length&&(a=-b.length);0a||37<=a&&40>=a)||p()});if(e.hasEvent("paste"))a.on("paste cut",p)}a.on("change",n);d.$render=function(){a.val(d.$isEmpty(d.$viewValue)?"":d.$viewValue)};var s=c.ngPattern;s&&((e=s.match(/^\/(.*)\/([gim]*)$/))? +(s=RegExp(e[1],e[2]),e=function(a){return ua(d,"pattern",d.$isEmpty(a)||s.test(a),a)}):e=function(c){var e=b.$eval(s);if(!e||!e.test)throw z("ngPattern")("noregexp",s,e,ia(a));return ua(d,"pattern",d.$isEmpty(c)||e.test(c),c)},d.$formatters.push(e),d.$parsers.push(e));if(c.ngMinlength){var r=U(c.ngMinlength);e=function(a){return ua(d,"minlength",d.$isEmpty(a)||a.length>=r,a)};d.$parsers.push(e);d.$formatters.push(e)}if(c.ngMaxlength){var w=U(c.ngMaxlength);e=function(a){return ua(d,"maxlength",d.$isEmpty(a)|| +a.length<=w,a)};d.$parsers.push(e);d.$formatters.push(e)}}function Wb(b,a){b="ngClass"+b;return["$animate",function(c){function d(a,b){var c=[],d=0;a:for(;dR?function(b){b=b.nodeName?b:b[0];return b.scopeName&&"HTML"!=b.scopeName?La(b.scopeName+":"+b.nodeName):b.nodeName}:function(b){return b.nodeName?b.nodeName:b[0].nodeName};var Za=function(){if(D(Za.isActive_))return Za.isActive_;var b=!(!X.querySelector("[ng-csp]")&& +!X.querySelector("[data-ng-csp]"));if(!b)try{new Function("")}catch(a){b=!0}return Za.isActive_=b},Xc=/[A-Z]/g,$c={full:"1.2.28",major:1,minor:2,dot:28,codeName:"finnish-disembarkation"};S.expando="ng339";var cb=S.cache={},me=1,sb=W.document.addEventListener?function(b,a,c){b.addEventListener(a,c,!1)}:function(b,a,c){b.attachEvent("on"+a,c)},bb=W.document.removeEventListener?function(b,a,c){b.removeEventListener(a,c,!1)}:function(b,a,c){b.detachEvent("on"+a,c)};S._data=function(b){return this.cache[b[this.expando]]|| +{}};var he=/([\:\-\_]+(.))/g,ie=/^moz([A-Z])/,Hb=z("jqLite"),je=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,Ib=/<|&#?\w+;/,ke=/<([\w:]+)/,le=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,da={option:[1,'"],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};da.optgroup=da.option;da.tbody=da.tfoot=da.colgroup= +da.caption=da.thead;da.th=da.td;var Oa=S.prototype={ready:function(b){function a(){c||(c=!0,b())}var c=!1;"complete"===X.readyState?setTimeout(a):(this.on("DOMContentLoaded",a),S(W).on("load",a))},toString:function(){var b=[];r(this,function(a){b.push(""+a)});return"["+b.join(", ")+"]"},eq:function(b){return 0<=b?A(this[b]):A(this[this.length+b])},length:0,push:Pe,sort:[].sort,splice:[].splice},rb={};r("multiple selected checked disabled readOnly required open".split(" "),function(b){rb[x(b)]=b}); +var pc={};r("input select option textarea button form details".split(" "),function(b){pc[La(b)]=!0});r({data:Mb,removeData:Lb},function(b,a){S[a]=b});r({data:Mb,inheritedData:qb,scope:function(b){return A.data(b,"$scope")||qb(b.parentNode||b,["$isolateScope","$scope"])},isolateScope:function(b){return A.data(b,"$isolateScope")||A.data(b,"$isolateScopeNoTemplate")},controller:mc,injector:function(b){return qb(b,"$injector")},removeAttr:function(b,a){b.removeAttribute(a)},hasClass:Nb,css:function(b, +a,c){a=ab(a);if(D(c))b.style[a]=c;else{var d;8>=R&&(d=b.currentStyle&&b.currentStyle[a],""===d&&(d="auto"));d=d||b.style[a];8>=R&&(d=""===d?u:d);return d}},attr:function(b,a,c){var d=x(a);if(rb[d])if(D(c))c?(b[a]=!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d));else return b[a]||(b.attributes.getNamedItem(a)||v).specified?d:u;else if(D(c))b.setAttribute(a,c);else if(b.getAttribute)return b=b.getAttribute(a,2),null===b?u:b},prop:function(b,a,c){if(D(c))b[a]=c;else return b[a]},text:function(){function b(b, +d){var e=a[b.nodeType];if(F(d))return e?b[e]:"";b[e]=d}var a=[];9>R?(a[1]="innerText",a[3]="nodeValue"):a[1]=a[3]="textContent";b.$dv="";return b}(),val:function(b,a){if(F(a)){if("SELECT"===Pa(b)&&b.multiple){var c=[];r(b.options,function(a){a.selected&&c.push(a.value||a.text)});return 0===c.length?null:c}return b.value}b.value=a},html:function(b,a){if(F(a))return b.innerHTML;for(var c=0,d=b.childNodes;c":function(a,c,d,e){return d(a,c)>e(a,c)},"<=":function(a,c,d,e){return d(a,c)<=e(a,c)},">=":function(a,c,d,e){return d(a,c)>=e(a,c)},"&&":function(a,c,d,e){return d(a,c)&&e(a,c)},"||":function(a,c,d,e){return d(a,c)||e(a,c)},"&":function(a,c,d,e){return d(a, +c)&e(a,c)},"|":function(a,c,d,e){return e(a,c)(a,c,d(a,c))},"!":function(a,c,d){return!d(a,c)}},Ue={n:"\n",f:"\f",r:"\r",t:"\t",v:"\v","'":"'",'"':'"'},Ub=function(a){this.options=a};Ub.prototype={constructor:Ub,lex:function(a){this.text=a;this.index=0;this.ch=u;this.lastCh=":";for(this.tokens=[];this.index=a},isWhitespace:function(a){return" "===a||"\r"===a||"\t"===a||"\n"===a||"\v"===a||"\u00a0"===a},isIdent:function(a){return"a"<=a&&"z">=a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isExpOperator:function(a){return"-"===a||"+"===a||this.isNumber(a)}, +throwError:function(a,c,d){d=d||this.index;c=D(c)?"s "+c+"-"+this.index+" ["+this.text.substring(c,d)+"]":" "+d;throw la("lexerr",a,c,this.text);},readNumber:function(){for(var a="",c=this.index;this.index","<=",">="))a=this.binaryFn(a,c.fn,this.relational());return a},additive:function(){for(var a=this.multiplicative(),c;c=this.expect("+","-");)a=this.binaryFn(a,c.fn,this.multiplicative());return a},multiplicative:function(){for(var a=this.unary(),c;c=this.expect("*","/","%");)a=this.binaryFn(a,c.fn,this.unary());return a},unary:function(){var a;return this.expect("+")?this.primary():(a=this.expect("-"))?this.binaryFn(gb.ZERO,a.fn, +this.unary()):(a=this.expect("!"))?this.unaryFn(a.fn,this.unary()):this.primary()},fieldAccess:function(a){var c=this,d=this.expect().text,e=Dc(d,this.options,this.text);return E(function(c,d,h){return e(h||a(c,d))},{assign:function(e,g,h){(h=a(e,h))||a.assign(e,h={});return ub(h,d,g,c.text,c.options)}})},objectIndex:function(a){var c=this,d=this.expression();this.consume("]");return E(function(e,f){var g=a(e,f),h=d(e,f),k;ka(h,c.text);if(!g)return u;(g=ma(g[h],c.text))&&(g.then&&c.options.unwrapPromises)&& +(k=g,"$$v"in g||(k.$$v=u,k.then(function(a){k.$$v=a})),g=g.$$v);return g},{assign:function(e,f,g){var h=ka(d(e,g),c.text);(g=ma(a(e,g),c.text))||a.assign(e,g={});return g[h]=f}})},functionCall:function(a,c){var d=[];if(")"!==this.peekToken().text){do d.push(this.expression());while(this.expect(","))}this.consume(")");var e=this;return function(f,g){for(var h=[],k=c?c(f,g):f,m=0;ma.getHours()?c.AMPMS[0]:c.AMPMS[1]},Z:function(a){a=-1*a.getTimezoneOffset();return a=(0<=a?"+":"")+(Vb(Math[0< +a?"floor":"ceil"](a/60),2)+Vb(Math.abs(a%60),2))}},Le=/((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/,Ke=/^\-?\d+$/;Ic.$inject=["$locale"];var Ie=aa(x),Je=aa(La);Kc.$inject=["$parse"];var cd=aa({restrict:"E",compile:function(a,c){8>=R&&(c.href||c.name||c.$set("href",""),a.append(X.createComment("IE fix")));if(!c.href&&!c.xlinkHref&&!c.name)return function(a,c){var f="[object SVGAnimatedString]"===Ba.call(c.prop("href"))?"xlink:href":"href";c.on("click",function(a){c.attr(f)|| +a.preventDefault()})}}}),Fb={};r(rb,function(a,c){if("multiple"!=a){var d=qa("ng-"+c);Fb[d]=function(){return{priority:100,link:function(a,f,g){a.$watch(g[d],function(a){g.$set(c,!!a)})}}}}});r(["src","srcset","href"],function(a){var c=qa("ng-"+a);Fb[c]=function(){return{priority:99,link:function(d,e,f){var g=a,h=a;"href"===a&&"[object SVGAnimatedString]"===Ba.call(e.prop("href"))&&(h="xlinkHref",f.$attr[h]="xlink:href",g=null);f.$observe(c,function(c){c?(f.$set(h,c),R&&g&&e.prop(g,f[h])):"href"=== +a&&f.$set(h,null)})}}}});var yb={$addControl:v,$removeControl:v,$setValidity:v,$setDirty:v,$setPristine:v};Nc.$inject=["$element","$attrs","$scope","$animate"];var Qc=function(a){return["$timeout",function(c){return{name:"form",restrict:a?"EAC":"E",controller:Nc,compile:function(){return{pre:function(a,e,f,g){if(!f.action){var h=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1};sb(e[0],"submit",h);e.on("$destroy",function(){c(function(){bb(e[0],"submit",h)},0,!1)})}var k=e.parent().controller("form"), +m=f.name||f.ngForm;m&&ub(a,m,g,m);if(k)e.on("$destroy",function(){k.$removeControl(g);m&&ub(a,m,u,m);E(g,yb)})}}}}}]},dd=Qc(),qd=Qc(!0),Ve=/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/,We=/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i,Xe=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/,Rc={text:Ab,number:function(a,c,d,e,f,g){Ab(a,c,d,e,f,g);e.$parsers.push(function(a){var c=e.$isEmpty(a);if(c||Xe.test(a))return e.$setValidity("number", +!0),""===a?null:c?a:parseFloat(a);e.$setValidity("number",!1);return u});Ne(e,"number",Ye,null,e.$$validityState);e.$formatters.push(function(a){return e.$isEmpty(a)?"":""+a});d.min&&(a=function(a){var c=parseFloat(d.min);return ua(e,"min",e.$isEmpty(a)||a>=c,a)},e.$parsers.push(a),e.$formatters.push(a));d.max&&(a=function(a){var c=parseFloat(d.max);return ua(e,"max",e.$isEmpty(a)||a<=c,a)},e.$parsers.push(a),e.$formatters.push(a));e.$formatters.push(function(a){return ua(e,"number",e.$isEmpty(a)|| +jb(a),a)})},url:function(a,c,d,e,f,g){Ab(a,c,d,e,f,g);a=function(a){return ua(e,"url",e.$isEmpty(a)||Ve.test(a),a)};e.$formatters.push(a);e.$parsers.push(a)},email:function(a,c,d,e,f,g){Ab(a,c,d,e,f,g);a=function(a){return ua(e,"email",e.$isEmpty(a)||We.test(a),a)};e.$formatters.push(a);e.$parsers.push(a)},radio:function(a,c,d,e){F(d.name)&&c.attr("name",ib());c.on("click",function(){c[0].checked&&a.$apply(function(){e.$setViewValue(d.value)})});e.$render=function(){c[0].checked=d.value==e.$viewValue}; +d.$observe("value",e.$render)},checkbox:function(a,c,d,e){var f=d.ngTrueValue,g=d.ngFalseValue;G(f)||(f=!0);G(g)||(g=!1);c.on("click",function(){a.$apply(function(){e.$setViewValue(c[0].checked)})});e.$render=function(){c[0].checked=e.$viewValue};e.$isEmpty=function(a){return a!==f};e.$formatters.push(function(a){return a===f});e.$parsers.push(function(a){return a?f:g})},hidden:v,button:v,submit:v,reset:v,file:v},Ye=["badInput"],hc=["$browser","$sniffer",function(a,c){return{restrict:"E",require:"?ngModel", +link:function(d,e,f,g){g&&(Rc[x(f.type)]||Rc.text)(d,e,f,g,c,a)}}}],wb="ng-valid",xb="ng-invalid",Ra="ng-pristine",zb="ng-dirty",Ze=["$scope","$exceptionHandler","$attrs","$element","$parse","$animate",function(a,c,d,e,f,g){function h(a,c){c=c?"-"+nb(c,"-"):"";g.removeClass(e,(a?xb:wb)+c);g.addClass(e,(a?wb:xb)+c)}this.$modelValue=this.$viewValue=Number.NaN;this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$pristine=!0;this.$dirty=!1;this.$valid=!0;this.$invalid=!1;this.$name= +d.name;var k=f(d.ngModel),m=k.assign;if(!m)throw z("ngModel")("nonassign",d.ngModel,ia(e));this.$render=v;this.$isEmpty=function(a){return F(a)||""===a||null===a||a!==a};var l=e.inheritedData("$formController")||yb,n=0,q=this.$error={};e.addClass(Ra);h(!0);this.$setValidity=function(a,c){q[a]!==!c&&(c?(q[a]&&n--,n||(h(!0),this.$valid=!0,this.$invalid=!1)):(h(!1),this.$invalid=!0,this.$valid=!1,n++),q[a]=!c,h(c,a),l.$setValidity(a,c,this))};this.$setPristine=function(){this.$dirty=!1;this.$pristine= +!0;g.removeClass(e,zb);g.addClass(e,Ra)};this.$setViewValue=function(d){this.$viewValue=d;this.$pristine&&(this.$dirty=!0,this.$pristine=!1,g.removeClass(e,Ra),g.addClass(e,zb),l.$setDirty());r(this.$parsers,function(a){d=a(d)});this.$modelValue!==d&&(this.$modelValue=d,m(a,d),r(this.$viewChangeListeners,function(a){try{a()}catch(d){c(d)}}))};var p=this;a.$watch(function(){var c=k(a);if(p.$modelValue!==c){var d=p.$formatters,e=d.length;for(p.$modelValue=c;e--;)c=d[e](c);p.$viewValue!==c&&(p.$viewValue= +c,p.$render())}return c})}],Fd=function(){return{require:["ngModel","^?form"],controller:Ze,link:function(a,c,d,e){var f=e[0],g=e[1]||yb;g.$addControl(f);a.$on("$destroy",function(){g.$removeControl(f)})}}},Hd=aa({require:"ngModel",link:function(a,c,d,e){e.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}),ic=function(){return{require:"?ngModel",link:function(a,c,d,e){if(e){d.required=!0;var f=function(a){if(d.required&&e.$isEmpty(a))e.$setValidity("required",!1);else return e.$setValidity("required", +!0),a};e.$formatters.push(f);e.$parsers.unshift(f);d.$observe("required",function(){f(e.$viewValue)})}}}},Gd=function(){return{require:"ngModel",link:function(a,c,d,e){var f=(a=/\/(.*)\//.exec(d.ngList))&&RegExp(a[1])||d.ngList||",";e.$parsers.push(function(a){if(!F(a)){var c=[];a&&r(a.split(f),function(a){a&&c.push($(a))});return c}});e.$formatters.push(function(a){return L(a)?a.join(", "):u});e.$isEmpty=function(a){return!a||!a.length}}}},$e=/^(true|false|\d+)$/,Id=function(){return{priority:100, +compile:function(a,c){return $e.test(c.ngValue)?function(a,c,f){f.$set("value",a.$eval(f.ngValue))}:function(a,c,f){a.$watch(f.ngValue,function(a){f.$set("value",a)})}}}},id=Aa({compile:function(a){a.addClass("ng-binding");return function(a,d,e){d.data("$binding",e.ngBind);a.$watch(e.ngBind,function(a){d.text(a==u?"":a)})}}}),kd=["$interpolate",function(a){return function(c,d,e){c=a(d.attr(e.$attr.ngBindTemplate));d.addClass("ng-binding").data("$binding",c);e.$observe("ngBindTemplate",function(a){d.text(a)})}}], +jd=["$sce","$parse",function(a,c){return{compile:function(d){d.addClass("ng-binding");return function(d,f,g){f.data("$binding",g.ngBindHtml);var h=c(g.ngBindHtml);d.$watch(function(){return(h(d)||"").toString()},function(c){f.html(a.getTrustedHtml(h(d))||"")})}}}}],ld=Wb("",!0),nd=Wb("Odd",0),md=Wb("Even",1),od=Aa({compile:function(a,c){c.$set("ngCloak",u);a.removeClass("ng-cloak")}}),pd=[function(){return{scope:!0,controller:"@",priority:500}}],jc={},af={blur:!0,focus:!0};r("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "), +function(a){var c=qa("ng-"+a);jc[c]=["$parse","$rootScope",function(d,e){return{compile:function(f,g){var h=d(g[c],!0);return function(c,d){d.on(a,function(d){var f=function(){h(c,{$event:d})};af[a]&&e.$$phase?c.$evalAsync(f):c.$apply(f)})}}}}]});var sd=["$animate",function(a){return{transclude:"element",priority:600,terminal:!0,restrict:"A",$$tlb:!0,link:function(c,d,e,f,g){var h,k,m;c.$watch(e.ngIf,function(f){Wa(f)?k||(k=c.$new(),g(k,function(c){c[c.length++]=X.createComment(" end ngIf: "+e.ngIf+ +" ");h={clone:c};a.enter(c,d.parent(),d)})):(m&&(m.remove(),m=null),k&&(k.$destroy(),k=null),h&&(m=Eb(h.clone),a.leave(m,function(){m=null}),h=null))})}}}],td=["$http","$templateCache","$anchorScroll","$animate","$sce",function(a,c,d,e,f){return{restrict:"ECA",priority:400,terminal:!0,transclude:"element",controller:Xa.noop,compile:function(g,h){var k=h.ngInclude||h.src,m=h.onload||"",l=h.autoscroll;return function(g,h,p,r,J){var w=0,t,y,u,B=function(){y&&(y.remove(),y=null);t&&(t.$destroy(),t=null); +u&&(e.leave(u,function(){y=null}),y=u,u=null)};g.$watch(f.parseAsResourceUrl(k),function(f){var k=function(){!D(l)||l&&!g.$eval(l)||d()},p=++w;f?(a.get(f,{cache:c}).success(function(a){if(p===w){var c=g.$new();r.template=a;a=J(c,function(a){B();e.enter(a,null,h,k)});t=c;u=a;t.$emit("$includeContentLoaded");g.$eval(m)}}).error(function(){p===w&&B()}),g.$emit("$includeContentRequested")):(B(),r.template=null)})}}}}],Jd=["$compile",function(a){return{restrict:"ECA",priority:-400,require:"ngInclude", +link:function(c,d,e,f){d.html(f.template);a(d.contents())(c)}}}],ud=Aa({priority:450,compile:function(){return{pre:function(a,c,d){a.$eval(d.ngInit)}}}}),vd=Aa({terminal:!0,priority:1E3}),wd=["$locale","$interpolate",function(a,c){var d=/{}/g;return{restrict:"EA",link:function(e,f,g){var h=g.count,k=g.$attr.when&&f.attr(g.$attr.when),m=g.offset||0,l=e.$eval(k)||{},n={},q=c.startSymbol(),p=c.endSymbol(),s=/^when(Minus)?(.+)$/;r(g,function(a,c){s.test(c)&&(l[x(c.replace("when","").replace("Minus","-"))]= +f.attr(g.$attr[c]))});r(l,function(a,e){n[e]=c(a.replace(d,q+h+"-"+m+p))});e.$watch(function(){var c=parseFloat(e.$eval(h));if(isNaN(c))return"";c in l||(c=a.pluralCat(c-m));return n[c](e,f,!0)},function(a){f.text(a)})}}}],xd=["$parse","$animate",function(a,c){var d=z("ngRepeat");return{transclude:"element",priority:1E3,terminal:!0,$$tlb:!0,link:function(e,f,g,h,k){var m=g.ngRepeat,l=m.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/),n,q,p,s,u,w,t={$id:Na};if(!l)throw d("iexp", +m);g=l[1];h=l[2];(l=l[3])?(n=a(l),q=function(a,c,d){w&&(t[w]=a);t[u]=c;t.$index=d;return n(e,t)}):(p=function(a,c){return Na(c)},s=function(a){return a});l=g.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);if(!l)throw d("iidexp",g);u=l[3]||l[1];w=l[2];var y={};e.$watchCollection(h,function(a){var g,h,l=f[0],n,t={},D,C,I,x,G,v,z,F=[];if(Sa(a))v=a,G=q||p;else{G=q||s;v=[];for(I in a)a.hasOwnProperty(I)&&"$"!=I.charAt(0)&&v.push(I);v.sort()}D=v.length;h=F.length=v.length;for(g=0;gC;)d=u.pop(),q.removeOption(d.label),d.element.remove()}for(;B.length>Q;)B.pop()[0].element.remove()}var k;if(!(k=s.match(d)))throw bf("iexp",s,ia(f));var l=c(k[2]||k[1]), +m=k[4]||k[6],n=k[5],r=c(k[3]||""),x=c(k[2]?k[1]:m),A=c(k[7]),w=k[8]?c(k[8]):null,B=[[{element:f,label:""}]];z&&(a(z)(e),z.removeClass("ng-scope"),z.remove());f.empty();f.on("change",function(){e.$apply(function(){var a,c=A(e)||[],d={},k,l,q,r,s,t,v;if(p)for(l=[],r=0,t=B.length;r@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}.ng-animate-block-transitions{transition:0s all!important;-webkit-transition:0s all!important;}.ng-hide-add-active,.ng-hide-remove{display:block!important;}'); +//# sourceMappingURL=angular.min.js.map \ No newline at end of file diff --git a/glances/outputs/static/js/vendors/angular.min.js.map b/glances/outputs/static/js/vendors/angular.min.js.map new file mode 100644 index 00000000..bf40d3e2 --- /dev/null +++ b/glances/outputs/static/js/vendors/angular.min.js.map @@ -0,0 +1,8 @@ +{ +"version":3, +"file":"angular.min.js", +"lineCount":216, +"mappings":"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", +"sources":["angular.js"], +"names":["window","document","undefined","minErr","isArrayLike","obj","isWindow","length","nodeType","isString","isArray","forEach","iterator","context","key","isFunction","hasOwnProperty","call","sortedKeys","keys","push","sort","forEachSorted","i","reverseParams","iteratorFn","value","nextUid","index","uid","digit","charCodeAt","join","String","fromCharCode","unshift","setHashKey","h","$$hashKey","extend","dst","arguments","int","str","parseInt","inherit","parent","extra","noop","identity","$","valueFn","isUndefined","isDefined","isObject","isNumber","isDate","toString","isRegExp","location","alert","setInterval","isElement","node","nodeName","prop","attr","find","map","results","list","indexOf","array","arrayRemove","splice","copy","source","destination","stackSource","stackDest","$evalAsync","$watch","ngMinErr","result","Date","getTime","RegExp","match","lastIndex","shallowCopy","src","charAt","equals","o1","o2","t1","t2","isNaN","keySet","bind","self","fn","curryArgs","slice","startIndex","apply","concat","toJsonReplacer","val","toJson","pretty","JSON","stringify","fromJson","json","parse","toBoolean","v","lowercase","startingTag","element","jqLite","clone","empty","e","elemHtml","append","html","TEXT_NODE","replace","tryDecodeURIComponent","decodeURIComponent","parseKeyValue","keyValue","key_value","split","toKeyValue","parts","arrayValue","encodeUriQuery","encodeUriSegment","pctEncodeSpaces","encodeURIComponent","angularInit","bootstrap","elements","appElement","module","names","NG_APP_CLASS_REGEXP","name","getElementById","querySelectorAll","exec","className","attributes","modules","doBootstrap","injector","tag","$provide","createInjector","invoke","scope","compile","animate","$apply","data","NG_DEFER_BOOTSTRAP","test","angular","resumeBootstrap","angular.resumeBootstrap","extraModules","snake_case","separator","SNAKE_CASE_REGEXP","letter","pos","toLowerCase","assertArg","arg","reason","assertArgFn","acceptArrayAnnotation","constructor","assertNotHasOwnProperty","getter","path","bindFnToScope","lastInstance","len","getBlockElements","nodes","startNode","endNode","nextSibling","setupModuleLoader","$injectorMinErr","$$minErr","factory","requires","configFn","invokeLater","provider","method","insertMethod","invokeQueue","moduleInstance","runBlocks","config","run","block","publishExternalAPI","version","uppercase","csp","angularModule","$LocaleProvider","ngModule","$$SanitizeUriProvider","$CompileProvider","directive","htmlAnchorDirective","inputDirective","formDirective","scriptDirective","selectDirective","styleDirective","optionDirective","ngBindDirective","ngBindHtmlDirective","ngBindTemplateDirective","ngClassDirective","ngClassEvenDirective","ngClassOddDirective","ngCloakDirective","ngControllerDirective","ngFormDirective","ngHideDirective","ngIfDirective","ngIncludeDirective","ngInitDirective","ngNonBindableDirective","ngPluralizeDirective","ngRepeatDirective","ngShowDirective","ngStyleDirective","ngSwitchDirective","ngSwitchWhenDirective","ngSwitchDefaultDirective","ngOptionsDirective","ngTranscludeDirective","ngModelDirective","ngListDirective","ngChangeDirective","requiredDirective","ngValueDirective","ngIncludeFillContentDirective","ngAttributeAliasDirectives","ngEventDirectives","$AnchorScrollProvider","$AnimateProvider","$BrowserProvider","$CacheFactoryProvider","$ControllerProvider","$DocumentProvider","$ExceptionHandlerProvider","$FilterProvider","$InterpolateProvider","$IntervalProvider","$HttpProvider","$HttpBackendProvider","$LocationProvider","$LogProvider","$ParseProvider","$RootScopeProvider","$QProvider","$SceProvider","$SceDelegateProvider","$SnifferProvider","$TemplateCacheProvider","$TimeoutProvider","$WindowProvider","$$RAFProvider","$$AsyncCallbackProvider","camelCase","SPECIAL_CHARS_REGEXP","_","offset","toUpperCase","MOZ_HACK_REGEXP","jqLitePatchJQueryRemove","dispatchThis","filterElems","getterIfNoArguments","removePatch","param","filter","fireEvent","set","setIndex","setLength","childIndex","children","shift","triggerHandler","childLength","jQuery","originalJqFn","$original","JQLite","trim","jqLiteMinErr","parsed","SINGLE_TAG_REGEXP","fragment","createDocumentFragment","HTML_REGEXP","tmp","appendChild","createElement","TAG_NAME_REGEXP","wrap","wrapMap","_default","innerHTML","XHTML_TAG_REGEXP","removeChild","firstChild","lastChild","j","jj","childNodes","textContent","createTextNode","jqLiteAddNodes","jqLiteClone","cloneNode","jqLiteDealoc","jqLiteRemoveData","jqLiteOff","type","unsupported","events","jqLiteExpandoStore","handle","eventHandler","removeEventListenerFn","expandoId","ng339","expandoStore","jqCache","$destroy","jqId","jqLiteData","isSetter","keyDefined","isSimpleGetter","jqLiteHasClass","selector","getAttribute","jqLiteRemoveClass","cssClasses","setAttribute","cssClass","jqLiteAddClass","existingClasses","root","jqLiteController","jqLiteInheritedData","documentElement","ii","parentNode","host","jqLiteEmpty","getBooleanAttrName","booleanAttr","BOOLEAN_ATTR","BOOLEAN_ELEMENTS","createEventHandler","event","preventDefault","event.preventDefault","returnValue","stopPropagation","event.stopPropagation","cancelBubble","target","srcElement","defaultPrevented","prevent","isDefaultPrevented","event.isDefaultPrevented","eventHandlersCopy","msie","elem","hashKey","nextUidFn","objType","HashMap","isolatedUid","this.nextUid","put","annotate","$inject","fnText","STRIP_COMMENTS","argDecl","FN_ARGS","FN_ARG_SPLIT","FN_ARG","all","underscore","last","modulesToLoad","supportObject","delegate","provider_","providerInjector","instantiate","$get","providerCache","providerSuffix","factoryFn","loadModules","moduleFn","loadedModules","get","_runBlocks","_invokeQueue","invokeArgs","message","stack","createInternalInjector","cache","getService","serviceName","INSTANTIATING","err","locals","args","Type","Constructor","returnedValue","prototype","instance","has","service","$injector","constant","instanceCache","decorator","decorFn","origProvider","orig$get","origProvider.$get","origInstance","instanceInjector","servicename","autoScrollingEnabled","disableAutoScrolling","this.disableAutoScrolling","$window","$location","$rootScope","getFirstAnchor","scroll","hash","elm","scrollIntoView","getElementsByName","scrollTo","autoScrollWatch","autoScrollWatchAction","$$rAF","$timeout","supported","Browser","$log","$sniffer","completeOutstandingRequest","outstandingRequestCount","outstandingRequestCallbacks","pop","error","startPoller","interval","setTimeout","check","pollFns","pollFn","pollTimeout","fireUrlChange","lastBrowserUrl","url","urlChangeListeners","listener","rawDocument","history","clearTimeout","pendingDeferIds","isMock","$$completeOutstandingRequest","$$incOutstandingRequestCount","self.$$incOutstandingRequestCount","notifyWhenNoOutstandingRequests","self.notifyWhenNoOutstandingRequests","callback","addPollFn","self.addPollFn","href","baseElement","reloadLocation","self.url","sameBase","stripHash","replaceState","pushState","urlChangeInit","onUrlChange","self.onUrlChange","on","hashchange","$$checkUrlChange","baseHref","self.baseHref","lastCookies","lastCookieString","cookiePath","cookies","self.cookies","cookieLength","cookie","escape","warn","cookieArray","unescape","substring","defer","self.defer","delay","timeoutId","cancel","self.defer.cancel","deferId","$document","this.$get","cacheFactory","cacheId","options","refresh","entry","freshEnd","staleEnd","n","link","p","nextEntry","prevEntry","caches","size","stats","capacity","Number","MAX_VALUE","lruHash","lruEntry","remove","removeAll","destroy","info","cacheFactory.info","cacheFactory.get","$cacheFactory","$$sanitizeUriProvider","hasDirectives","Suffix","COMMENT_DIRECTIVE_REGEXP","CLASS_DIRECTIVE_REGEXP","EVENT_HANDLER_ATTR_REGEXP","this.directive","registerDirective","directiveFactory","$exceptionHandler","directives","priority","require","controller","restrict","aHrefSanitizationWhitelist","this.aHrefSanitizationWhitelist","regexp","imgSrcSanitizationWhitelist","this.imgSrcSanitizationWhitelist","$interpolate","$http","$templateCache","$parse","$controller","$sce","$animate","$$sanitizeUri","$compileNodes","transcludeFn","maxPriority","ignoreDirective","previousCompileContext","nodeValue","compositeLinkFn","compileNodes","safeAddClass","publicLinkFn","cloneConnectFn","transcludeControllers","parentBoundTranscludeFn","$linkNode","JQLitePrototype","eq","$element","addClass","nodeList","$rootElement","childLinkFn","childScope","childBoundTranscludeFn","nodeListLength","stableNodeList","Array","linkFns","nodeLinkFn","$new","transcludeOnThisElement","createBoundTranscludeFn","transclude","templateOnThisElement","attrs","linkFnFound","Attributes","collectDirectives","applyDirectivesToNode","$$element","terminal","previousBoundTranscludeFn","boundTranscludeFn","transcludedScope","cloneFn","controllers","scopeCreated","$$transcluded","attrsMap","$attr","addDirective","directiveNormalize","nodeName_","isNgAttr","nAttrs","attrStartName","attrEndName","specified","ngAttrName","NG_ATTR_BINDING","substr","directiveNName","nName","addAttrInterpolateDirective","addTextInterpolateDirective","byPriority","groupScan","attrStart","attrEnd","depth","hasAttribute","$compileMinErr","groupElementsLinkFnWrapper","linkFn","compileNode","templateAttrs","jqCollection","originalReplaceDirective","preLinkFns","postLinkFns","addLinkFns","pre","post","directiveName","newIsolateScopeDirective","$$isolateScope","cloneAndAnnotateFn","getControllers","elementControllers","retrievalMethod","optional","linkNode","controllersBoundTransclude","cloneAttachFn","hasElementTranscludeDirective","isolateScope","LOCAL_REGEXP","templateDirective","$$originalDirective","definition","scopeName","attrName","mode","lastValue","parentGet","parentSet","compare","$$isolateBindings","$observe","$$observers","$$scope","literal","a","b","assign","parentValueWatch","parentValue","controllerDirectives","controllerInstance","controllerAs","$scope","scopeToChild","template","templateUrl","terminalPriority","newScopeDirective","nonTlbTranscludeDirective","hasTranscludeDirective","hasTemplate","$compileNode","$template","childTranscludeFn","$$start","$$end","directiveValue","assertNoDuplicate","$$tlb","createComment","replaceWith","replaceDirective","contents","denormalizeTemplate","newTemplateAttrs","templateDirectives","unprocessedDirectives","markDirectivesAsIsolate","mergeTemplateAttributes","compileTemplateUrl","Math","max","tDirectives","startAttrName","endAttrName","srcAttr","dstAttr","$set","tAttrs","linkQueue","afterTemplateNodeLinkFn","afterTemplateChildLinkFn","beforeTemplateCompileNode","origAsyncDirective","derivedSyncDirective","getTrustedResourceUrl","success","content","tempTemplateAttrs","beforeTemplateLinkNode","linkRootElement","oldClasses","response","code","headers","delayedNodeLinkFn","ignoreChildLinkFn","rootElement","diff","what","previousDirective","text","interpolateFn","textInterpolateCompileFn","templateNode","hasCompileParent","textInterpolateLinkFn","bindings","interpolateFnWatchAction","getTrustedContext","attrNormalizedName","HTML","RESOURCE_URL","attrInterpolatePreLinkFn","$$inter","newValue","oldValue","$updateClass","elementsToRemove","newNode","firstElementToRemove","removeCount","j2","replaceChild","expando","k","kk","annotation","$addClass","classVal","$removeClass","removeClass","newClasses","toAdd","tokenDifference","toRemove","setClass","writeAttr","booleanKey","removeAttr","listeners","startSymbol","endSymbol","PREFIX_REGEXP","str1","str2","values","tokens1","tokens2","token","CNTRL_REG","register","this.register","expression","identifier","exception","cause","parseHeaders","line","headersGetter","headersObj","transformData","fns","JSON_START","JSON_END","PROTECTION_PREFIX","CONTENT_TYPE_APPLICATION_JSON","defaults","d","interceptorFactories","interceptors","responseInterceptorFactories","responseInterceptors","$httpBackend","$browser","$q","requestConfig","transformResponse","resp","status","reject","transformRequest","mergeHeaders","defHeaders","reqHeaders","defHeaderName","reqHeaderName","common","lowercaseDefHeaderName","execHeaders","headerContent","headerFn","header","chain","serverRequest","reqData","withCredentials","sendReq","then","promise","when","reversedInterceptors","interceptor","request","requestError","responseError","thenFn","rejectFn","promise.success","promise.error","done","headersString","statusText","resolvePromise","$$phase","deferred","resolve","removePendingReq","idx","pendingRequests","cachedResp","buildUrl","params","defaultCache","xsrfValue","urlIsSameOrigin","xsrfCookieName","xsrfHeaderName","timeout","responseType","toISOString","interceptorFactory","responseFn","createShortMethods","createShortMethodsWithData","createXhr","XMLHttpRequest","ActiveXObject","createHttpBackend","callbacks","$browserDefer","jsonpReq","callbackId","script","async","body","called","addEventListenerFn","onreadystatechange","script.onreadystatechange","readyState","ABORTED","timeoutRequest","jsonpDone","xhr","abort","completeRequest","urlResolve","protocol","counter","open","setRequestHeader","xhr.onreadystatechange","responseHeaders","getAllResponseHeaders","responseText","send","this.startSymbol","this.endSymbol","mustHaveExpression","trustedContext","endIndex","hasInterpolation","startSymbolLength","exp","endSymbolLength","$interpolateMinErr","part","getTrusted","valueOf","newErr","$interpolate.startSymbol","$interpolate.endSymbol","count","invokeApply","clearInterval","iteration","skipApply","$$intervalId","tick","notify","intervals","interval.cancel","short","pluralCat","num","encodePath","segments","parseAbsoluteUrl","absoluteUrl","locationObj","appBase","parsedUrl","$$protocol","$$host","hostname","$$port","port","DEFAULT_PORTS","parseAppUrl","relativeUrl","prefixed","$$path","pathname","$$search","search","$$hash","beginsWith","begin","whole","stripFile","lastIndexOf","LocationHtml5Url","basePrefix","$$html5","appBaseNoFile","$$parse","this.$$parse","pathUrl","$locationMinErr","$$compose","this.$$compose","$$url","$$absUrl","$$parseLinkUrl","this.$$parseLinkUrl","relHref","appUrl","prevAppUrl","rewrittenUrl","LocationHashbangUrl","hashPrefix","withoutBaseUrl","withoutHashUrl","windowsFilePathExp","firstPathSegmentMatch","LocationHashbangInHtml5Url","locationGetter","property","locationGetterSetter","preprocess","html5Mode","this.hashPrefix","prefix","this.html5Mode","afterLocationChange","oldUrl","$broadcast","absUrl","initialUrl","LocationMode","IGNORE_URI_REGEXP","ctrlKey","metaKey","which","absHref","animVal","newUrl","$digest","changeCounter","$locationWatch","currentReplace","$$replace","debug","debugEnabled","this.debugEnabled","flag","formatError","Error","sourceURL","consoleLog","console","logFn","log","hasApply","arg1","arg2","ensureSafeMemberName","fullExpression","$parseMinErr","ensureSafeObject","Object","setter","setValue","fullExp","propertyObj","unwrapPromises","promiseWarning","$$v","isPossiblyDangerousMemberName","cspSafeGetterFn","key0","key1","key2","key3","key4","eso","o","expensiveChecks","eso0","eso1","eso2","eso3","eso4","cspSafePromiseEnabledGetter","pathVal","cspSafeGetter","getterFnWithExtraArgs","s","l","getterFn","getterFnCache","getterFnCacheExpensive","getterFnCacheDefault","pathKeys","pathKeysLength","needsEnsureSafeObject","lookupJs","wrapWithEso","evaledFnGetter","Function","cacheDefault","cacheExpensive","$parseOptions","this.unwrapPromises","logPromiseWarnings","this.logPromiseWarnings","$filter","$parseOptionsExpensive","promiseWarningCache","parsedExpression","parseOptions","lexer","Lexer","parser","Parser","qFactory","nextTick","exceptionHandler","defaultCallback","defaultErrback","pending","ref","createInternalRejectedPromise","progress","errback","progressback","wrappedCallback","wrappedErrback","wrappedProgressback","catch","finally","makePromise","resolved","handleCallback","isResolved","callbackOutput","promises","requestAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","cancelAnimationFrame","webkitCancelAnimationFrame","mozCancelAnimationFrame","webkitCancelRequestAnimationFrame","rafSupported","raf","id","timer","TTL","$rootScopeMinErr","lastDirtyWatch","digestTtl","this.digestTtl","Scope","$id","$parent","$$watchers","$$nextSibling","$$prevSibling","$$childHead","$$childTail","$root","$$destroyed","$$asyncQueue","$$postDigestQueue","$$listeners","$$listenerCount","beginPhase","phase","compileToFn","decrementListenerCount","current","initWatchVal","isolate","child","$$childScopeClass","this.$$childScopeClass","watchExp","objectEquality","watcher","listenFn","watcher.fn","newVal","oldVal","originalFn","deregisterWatch","$watchCollection","veryOldValue","trackVeryOldValue","changeDetected","objGetter","internalArray","internalObject","initRun","oldLength","$watchCollectionWatch","newLength","bothNaN","$watchCollectionAction","watch","watchers","asyncQueue","postDigestQueue","dirty","ttl","watchLog","logIdx","logMsg","asyncTask","$eval","next","$on","this.$watch","expr","$$postDigest","namedListeners","indexOfListener","$emit","listenerArgs","array1","currentScope","sanitizeUri","uri","isImage","regex","normalizedVal","adjustMatcher","matcher","$sceMinErr","adjustMatchers","matchers","adjustedMatchers","SCE_CONTEXTS","resourceUrlWhitelist","resourceUrlBlacklist","this.resourceUrlWhitelist","this.resourceUrlBlacklist","generateHolderType","Base","holderType","trustedValue","$$unwrapTrustedValue","this.$$unwrapTrustedValue","holderType.prototype.valueOf","holderType.prototype.toString","htmlSanitizer","trustedValueHolderBase","byType","CSS","URL","JS","trustAs","maybeTrusted","allowed","enabled","this.enabled","$sceDelegate","msieDocumentMode","sce","isEnabled","sce.isEnabled","sce.getTrusted","parseAs","sce.parseAs","sceParseAsTrusted","enumValue","lName","eventSupport","android","userAgent","navigator","boxee","documentMode","vendorPrefix","vendorRegex","bodyStyle","style","transitions","animations","webkitTransition","webkitAnimation","hasEvent","divElm","deferreds","$$timeoutId","timeout.cancel","base","urlParsingNode","requestUrl","originUrl","filters","suffix","currencyFilter","dateFilter","filterFilter","jsonFilter","limitToFilter","lowercaseFilter","numberFilter","orderByFilter","uppercaseFilter","comparator","comparatorType","predicates","predicates.check","objKey","filtered","$locale","formats","NUMBER_FORMATS","amount","currencySymbol","CURRENCY_SYM","formatNumber","PATTERNS","GROUP_SEP","DECIMAL_SEP","number","fractionSize","pattern","groupSep","decimalSep","isFinite","isNegative","abs","numStr","formatedText","hasExponent","toFixed","fractionLen","min","minFrac","maxFrac","round","fraction","lgroup","lgSize","group","gSize","negPre","posPre","negSuf","posSuf","padNumber","digits","neg","dateGetter","date","dateStrGetter","shortForm","jsonStringToDate","string","R_ISO8601_STR","tzHour","tzMin","dateSetter","setUTCFullYear","setFullYear","timeSetter","setUTCHours","setHours","m","ms","parseFloat","format","DATETIME_FORMATS","NUMBER_STRING","DATE_FORMATS_SPLIT","DATE_FORMATS","object","input","limit","Infinity","out","sortPredicate","reverseOrder","reverseComparator","comp","descending","v1","v2","predicate","ngDirective","FormController","toggleValidCss","isValid","validationErrorKey","VALID_CLASS","INVALID_CLASS","form","parentForm","nullFormCtrl","invalidCount","errors","$error","controls","$name","ngForm","$dirty","$pristine","$valid","$invalid","$addControl","PRISTINE_CLASS","form.$addControl","control","$removeControl","form.$removeControl","queue","validationToken","$setValidity","form.$setValidity","$setDirty","form.$setDirty","DIRTY_CLASS","$setPristine","form.$setPristine","validate","ctrl","validatorName","validity","testFlags","flags","addNativeHtml5Validators","badFlags","ignoreFlags","$$hasNativeValidators","$parsers","validator","textInputType","VALIDITY_STATE_PROPERTY","placeholder","noevent","$$validityState","composing","ev","ngTrim","revalidate","$viewValue","$setViewValue","deferListener","keyCode","$render","ctrl.$render","$isEmpty","ngPattern","patternValidator","patternObj","$formatters","ngMinlength","minlength","minLengthValidator","ngMaxlength","maxlength","maxLengthValidator","classDirective","arrayDifference","arrayClasses","classes","digestClassCounts","classCounts","classesToUpdate","ngClassWatchAction","$index","old$index","mod","isActive_","active","querySelector","addEventListener","attachEvent","removeEventListener","detachEvent","_data","JQLite._data","optgroup","option","tbody","tfoot","colgroup","caption","thead","th","td","ready","trigger","fired","removeAttribute","css","currentStyle","lowercasedName","getNamedItem","ret","getText","textProp","NODE_TYPE_TEXT_PROPERTY","$dv","multiple","selected","nodeCount","onFn","eventFns","contains","compareDocumentPosition","adown","bup","eventmap","related","relatedTarget","one","off","replaceNode","insertBefore","contentDocument","prepend","wrapNode","after","newElement","toggleClass","condition","classCondition","nextElementSibling","getElementsByTagName","extraParameters","dummyEvent","handlerArgs","eventName","eventFnsCopy","arg3","unbind","$animateMinErr","$$selectors","classNameFilter","this.classNameFilter","$$classNameFilter","$$asyncCallback","enter","leave","move","add","PATH_MATCH","paramValue","CALL","APPLY","BIND","OPERATORS","null","true","false","+","-","*","/","%","^","===","!==","==","!=","<",">","<=",">=","&&","||","&","|","!","ESCAPE","lex","ch","lastCh","tokens","is","readString","peek","readNumber","isIdent","readIdent","isWhitespace","ch2","ch3","fn2","fn3","throwError","chars","was","isExpOperator","start","end","colStr","peekCh","ident","lastDot","peekIndex","methodName","quote","rawString","hex","rep","ZERO","statements","primary","expect","filterChain","consume","arrayDeclaration","functionCall","objectIndex","fieldAccess","msg","peekToken","e1","e2","e3","e4","t","unaryFn","right","ternaryFn","left","middle","binaryFn","statement","argsFn","fnInvoke","assignment","ternary","logicalOR","logicalAND","equality","relational","additive","multiplicative","unary","field","indexFn","contextGetter","fnPtr","elementFns","allConstant","elementFn","keyValues","ampmGetter","getHours","AMPMS","timeZoneGetter","zone","getTimezoneOffset","paddedZone","xlinkHref","propName","normalized","ngBooleanAttrWatchAction","formDirectiveFactory","isNgForm","formElement","action","preventDefaultListener","parentFormCtrl","alias","URL_REGEXP","EMAIL_REGEXP","NUMBER_REGEXP","inputType","numberInputType","numberBadFlags","minValidator","maxValidator","urlInputType","urlValidator","emailInputType","emailValidator","radioInputType","checked","checkboxInputType","trueValue","ngTrueValue","falseValue","ngFalseValue","ctrl.$isEmpty","NgModelController","$modelValue","NaN","$viewChangeListeners","ngModelGet","ngModel","ngModelSet","this.$isEmpty","inheritedData","this.$setValidity","this.$setPristine","this.$setViewValue","ngModelWatch","formatters","ctrls","modelCtrl","formCtrl","ngChange","required","ngList","viewValue","CONSTANT_VALUE_REGEXP","tpl","tplAttr","ngValue","ngValueConstantLink","ngValueLink","valueWatchAction","templateElement","ngBind","ngBindWatchAction","ngBindTemplate","tElement","ngBindHtml","getStringValue","ngBindHtmlWatchAction","getTrustedHtml","forceAsyncEvents","ngEventHandler","$transclude","previousElements","ngIf","ngIfWatchAction","$anchorScroll","srcExp","ngInclude","onloadExp","onload","autoScrollExp","autoscroll","previousElement","currentElement","cleanupLastIncludeContent","parseAsResourceUrl","ngIncludeWatchAction","afterAnimation","thisChangeId","newScope","$compile","ngInit","BRACE","numberExp","whenExp","whens","whensExpFns","isWhen","attributeName","ngPluralizeWatch","ngPluralizeWatchAction","ngRepeatMinErr","ngRepeat","trackByExpGetter","trackByIdExpFn","trackByIdArrayFn","trackByIdObjFn","valueIdentifier","keyIdentifier","hashFnLocals","lhs","rhs","trackByExp","lastBlockMap","ngRepeatAction","collection","previousNode","nextNode","nextBlockMap","arrayLength","trackByIdFn","collectionKeys","nextBlockOrder","trackById","$first","$last","$middle","$odd","$even","ngShow","ngShowWatchAction","ngHide","ngHideWatchAction","ngStyle","ngStyleWatchAction","newStyles","oldStyles","ngSwitchController","cases","selectedTranscludes","selectedElements","selectedScopes","ngSwitch","ngSwitchWatchAction","change","selectedTransclude","selectedScope","caseElement","anchor","ngSwitchWhen","$attrs","ngOptionsMinErr","NG_OPTIONS_REGEXP","nullModelCtrl","optionsMap","ngModelCtrl","unknownOption","databound","init","self.init","ngModelCtrl_","nullOption_","unknownOption_","addOption","self.addOption","removeOption","self.removeOption","hasOption","renderUnknownOption","self.renderUnknownOption","unknownVal","self.hasOption","setupAsSingle","selectElement","selectCtrl","ngModelCtrl.$render","emptyOption","setupAsMultiple","lastView","items","selectMultipleWatch","setupAsOptions","render","optionGroups","optionGroupNames","optionGroupName","optionGroup","existingParent","existingOptions","existingOption","modelValue","valuesFn","keyName","groupIndex","selectedSet","trackFn","trackIndex","valueName","lastElement","groupByFn","modelCast","label","displayFn","nullOption","groupLength","optionGroupsCache","optGroupTemplate","optionTemplate","optionsExp","track","optionElement","toDisplay","ngOptions","ngModelCtrl.$isEmpty","nullSelectCtrl","selectCtrlName","interpolateWatchAction","$$csp"] +} diff --git a/glances/outputs/static/js/vendors/lodash.min.js b/glances/outputs/static/js/vendors/lodash.min.js new file mode 100644 index 00000000..0d0fd334 --- /dev/null +++ b/glances/outputs/static/js/vendors/lodash.min.js @@ -0,0 +1,137 @@ +/** + * @license + * lodash 3.8.0 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE + * Build: `lodash modern -o ./lodash.js` + */ +;(function(){function n(n,t){if(n!==t){var r=n===n,e=t===t;if(n>t||!r||n===w&&e)return 1;if(n=n&&9<=n&&13>=n||32==n||160==n||5760==n||6158==n||8192<=n&&(8202>=n||8232==n||8233==n||8239==n||8287==n||12288==n||65279==n); + +}function v(n,t){for(var r=-1,e=n.length,u=-1,o=[];++ri(t,a,0)&&u.push(a);return u}function at(n,t){var r=true;return zu(n,function(n,e,u){return r=!!t(n,e,u)}),r}function ct(n,t){var r=[];return zu(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function lt(n,t,r,e){var u;return r(n,function(n,r,o){return t(n,r,o)?(u=e?r:n,false):void 0}),u}function st(n,t,r){ +for(var e=-1,u=n.length,o=-1,i=[];++et&&(t=-t>u?0:u+t),r=r===w||r>u?u:+r||0,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0, +r=Ue(u);++eu(a,s,0)&&((t||f)&&a.push(s),c.push(l))}return c}function Ut(n,t){for(var r=-1,e=t.length,u=Ue(e);++r>>1,i=n[o];(r?i<=t:iu?null:o,u=1);++earguments.length;return typeof e=="function"&&o===w&&To(r)?n(r,e,u,i):Et(r,dr(e,o,4),u,i,t)}}function cr(n,t,r,e,u,o,i,f,a,c){function l(){for(var b=arguments.length,j=b,k=Ue(b);j--;)k[j]=arguments[j];if(e&&(k=Mt(k,e,u)),o&&(k=Dt(k,o,i)),_||y){var j=l.placeholder,O=v(k,j),b=b-O.length;if(bu)||i===e&&i===o)&&(u=i,o=n)}),o}function dr(n,t,r){var e=$n.callback||Ee,e=e===Ee?ut:e;return r?e(n,t,r):e}function mr(n,t,e){var u=$n.indexOf||Dr,u=u===Dr?r:u;return n?u(n,t,e):u}function wr(n){var t=n.length,r=new n.constructor(t); + +return t&&"string"==typeof n[0]&&Ge.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function br(n){return n=n.constructor,typeof n=="function"&&n instanceof n||(n=Be),new n}function xr(n,t,r){var e=n.constructor;switch(t){case J:return Bt(n);case D:case P:return new e(+n);case X:case H:case Q:case nn:case tn:case rn:case en:case un:case on:return t=n.buffer,new e(r?Bt(t):t,n.byteOffset,n.length);case V:case G:return new e(n);case Z:var u=new e(n.source,kn.exec(n));u.lastIndex=n.lastIndex}return u; + +}function Ar(n,t,r){return null==n||Er(t,n)||(t=$r(t),n=1==t.length?n:gt(n,It(t,0,-1)),t=Pr(t)),t=null==n?n:n[t],null==t?w:t.apply(n,r)}function jr(n){return null!=n&&Rr(Yu(n))}function kr(n,t){return n=+n,t=null==t?Tu:t,-1t?0:t)):[]}function Br(n,t,r){var e=n?n.length:0;return e?((r?Or(n,t,r):null==t)&&(t=1),t=e-(+t||0),It(n,0,0>t?0:t)):[]}function Mr(n){return n?n[0]:w}function Dr(n,t,e){var u=n?n.length:0;if(!u)return-1;if(typeof e=="number")e=0>e?bu(u+e,0):e;else if(e)return e=$t(n,t),n=n[e],(t===t?t===n:n!==n)?e:-1;return r(n,t,e||0)}function Pr(n){var t=n?n.length:0;return t?n[t-1]:w}function qr(n){return zr(n,1)}function Kr(n,t,e,u){ +if(!n||!n.length)return[];null!=t&&typeof t!="boolean"&&(u=e,e=Or(n,t,u)?null:t,t=false);var o=dr();if((o!==ut||null!=e)&&(e=o(e,u,3)),t&&mr()==r){t=e;var i;e=-1,u=n.length;for(var o=-1,f=[];++er?bu(u+r,0):r||0,typeof n=="string"||!To(n)&&ve(n)?rt?0:+t||0,n.length),n)}function re(n){n=Nr(n);for(var t=-1,r=n.length,e=Ue(r);++t=n&&(t=null),r}}function oe(n,t,r){function e(){var r=t-(wo()-c);0>=r||r>t?(f&&eu(f),r=p,f=s=p=w,r&&(h=wo(),a=n.apply(l,i),s||f||(i=l=null))):s=su(e,r)}function u(){s&&eu(s),f=s=p=w,(v||_!==t)&&(h=wo(),a=n.apply(l,i),s||f||(i=l=null))}function o(){if(i=arguments,c=wo(),l=this,p=v&&(s||!g), +!1===_)var r=g&&!s;else{f||g||(h=c);var o=_-(c-h),y=0>=o||o>_;y?(f&&(f=eu(f)),h=c,a=n.apply(l,i)):f||(f=su(u,o))}return y&&s?s=eu(s):s||t===_||(s=su(e,t)),r&&(y=true,a=n.apply(l,i)),!y||s||f||(i=l=null),a}var i,f,a,c,l,s,p,h=0,_=false,v=true;if(typeof n!="function")throw new Pe(L);if(t=0>t?0:+t||0,true===r)var g=true,v=false;else se(r)&&(g=r.leading,_="maxWait"in r&&bu(+r.maxWait||0,t),v="trailing"in r?r.trailing:v);return o.cancel=function(){s&&eu(s),f&&eu(f),f=s=p=w},o}function ie(n,t){function r(){var e=arguments,u=r.cache,o=t?t.apply(this,e):e[0]; + +return u.has(o)?u.get(o):(e=n.apply(this,e),u.set(o,e),e)}if(typeof n!="function"||t&&typeof t!="function")throw new Pe(L);return r.cache=new ie.Cache,r}function fe(n,t){if(typeof n!="function")throw new Pe(L);return t=bu(t===w?n.length-1:+t||0,0),function(){for(var r=arguments,e=-1,u=bu(r.length-t,0),o=Ue(u);++et||!n||!mu(t))return r;do t%2&&(r+=n),t=uu(t/2),n+=n;while(t);return r}function ke(n,t,r){var e=n;return(n=u(n))?(r?Or(e,t,r):null==t)?n.slice(g(n),y(n)+1):(t+="",n.slice(i(n,t),f(n,t)+1)):n}function Oe(n,t,r){return r&&Or(n,t,r)&&(t=null),n=u(n),n.match(t||Wn)||[]}function Ee(n,t,r){return r&&Or(n,t,r)&&(t=null),h(n)?Ce(n):ut(n,t)}function Ie(n){ +return function(){return n}}function Re(n){return n}function Ce(n){return wt(ot(n,true))}function We(n,t,r){if(null==r){var e=se(t),u=e&&Ko(t);((u=u&&u.length&&vt(t,u))?u.length:e)||(u=false,r=t,t=n,n=this)}u||(u=vt(t,Ko(t)));var o=true,e=-1,i=No(n),f=u.length;false===r?o=false:se(r)&&"chain"in r&&(o=r.chain);for(;++e>>1,Su=vu?vu.BYTES_PER_ELEMENT:0,Tu=Le.pow(2,53)-1,Uu=_u&&new _u,Nu={},Fu=$n.support={}; + +!function(n){function t(){this.x=n}var r=arguments,e=[];t.prototype={valueOf:n,y:n};for(var u in new t)e.push(u);Fu.funcDecomp=/\bthis\b/.test(function(){return this}),Fu.funcNames=typeof $e.name=="string";try{Fu.dom=11===Ye.createDocumentFragment().nodeType}catch(o){Fu.dom=false}try{Fu.nonEnumArgs=!cu.call(r,1)}catch(i){Fu.nonEnumArgs=true}}(1,0),$n.templateSettings={escape:_n,evaluate:vn,interpolate:gn,variable:"",imports:{_:$n}};var $u=gu||function(n,t){return null==t?n:et(t,Zu(t),et(t,Ko(t),n))},Lu=function(){ +function n(){}return function(t){if(se(t)){n.prototype=t;var r=new n;n.prototype=null}return r||_.Object()}}(),zu=Kt(ht),Bu=Kt(_t,true),Mu=Vt(),Du=Vt(true),Pu=Uu?function(n,t){return Uu.set(n,t),n}:Re;tu||(Bt=nu&&hu?function(n){var t=n.byteLength,r=vu?uu(t/Su):0,e=r*Su,u=new nu(t);if(r){var o=new vu(u,0,r);o.set(new vu(n,0,r))}return t!=e&&(o=new hu(u,e),o.set(new hu(n,e))),u}:Ie(null));var qu=du&&lu?function(n){return new Dn(n)}:Ie(null),Ku=Uu?function(n){return Uu.get(n)}:Se,Vu=function(){return Fu.funcNames?"constant"==Ie.name?At("name"):function(n){ +for(var t=n.name,r=Nu[t],e=r?r.length:0;e--;){var u=r[e],o=u.func;if(null==o||o==n)return u.name}return t}:Ie("")}(),Yu=At("length"),Zu=ou?function(n){return ou(Fr(n))}:Ie([]),Gu=function(){var n=0,t=0;return function(r,e){var u=wo(),o=U-(u-t);if(t=u,0=T)return r}else n=0;return Pu(r,e)}}(),Ju=fe(function(n,t){return jr(n)?ft(n,st(t,false,true)):[]}),Xu=Qt(),Hu=Qt(true),Qu=fe(function(t,r){r=st(r);var e=rt(t,r);return kt(t,r.sort(n)),e}),no=pr(),to=pr(true),ro=fe(function(n){return Tt(st(n,false,true)); + +}),eo=fe(function(n,t){return jr(n)?ft(n,t):[]}),uo=fe(Vr),oo=fe(function(n){var t=n.length,r=n[t-2],e=n[t-1];return 2e&&(e=u)}return e}),fi=Xt(function(n){for(var t=-1,r=n.length,e=Iu;++t--n?t.apply(this,arguments):void 0}},$n.ary=function(n,t,r){return r&&Or(n,t,r)&&(t=null), +t=n&&null==t?n.length:bu(+t||0,0),hr(n,R,null,null,null,null,t)},$n.assign=$o,$n.at=io,$n.before=ue,$n.bind=bo,$n.bindAll=xo,$n.bindKey=Ao,$n.callback=Ee,$n.chain=Gr,$n.chunk=function(n,t,r){t=(r?Or(n,t,r):null==t)?1:bu(+t||1,1),r=0;for(var e=n?n.length:0,u=-1,o=Ue(ru(e/t));rr&&(r=-r>u?0:u+r),e=e===w||e>u?u:+e||0,0>e&&(e+=u),u=r>e?0:e>>>0,r>>>=0;re)return f;var i=n[0],c=-1,l=i?i.length:0,s=u[0];n:for(;++c(s?Pn(s,a):o(f,a,0))){for(t=e;--t;){var p=u[t];if(0>(p?Pn(p,a):o(n[t],a,0)))continue n}s&&s.push(a),f.push(a)}return f},$n.invert=function(n,t,r){r&&Or(n,t,r)&&(t=null),r=-1;for(var e=Ko(n),u=e.length,o={};++rt?0:t)):[]},$n.takeRight=function(n,t,r){var e=n?n.length:0;return e?((r?Or(n,t,r):null==t)&&(t=1),t=e-(+t||0),It(n,0>t?0:t)):[]},$n.takeRightWhile=function(n,t,r){return n&&n.length?Nt(n,dr(t,r,3),false,true):[]},$n.takeWhile=function(n,t,r){return n&&n.length?Nt(n,dr(t,r,3)):[]},$n.tap=function(n,t,r){return t.call(r,n),n},$n.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new Pe(L);return false===r?e=false:se(r)&&(e="leading"in r?!!r.leading:e, +u="trailing"in r?!!r.trailing:u),Fn.leading=e,Fn.maxWait=+t,Fn.trailing=u,oe(n,t,Fn)},$n.thru=Jr,$n.times=function(n,t,r){if(n=uu(n),1>n||!mu(n))return[];var e=-1,u=Ue(xu(n,Ru));for(t=zt(t,r,1);++er?0:+r||0,e),r-=t.length,0<=r&&n.indexOf(t,r)==r},$n.escape=function(n){return(n=u(n))&&hn.test(n)?n.replace(sn,l):n},$n.escapeRegExp=xe,$n.every=Xr,$n.find=ao,$n.findIndex=Xu,$n.findKey=zo,$n.findLast=co,$n.findLastIndex=Hu,$n.findLastKey=Bo,$n.findWhere=function(n,t){return ao(n,wt(t))},$n.first=Mr,$n.get=function(n,t,r){return n=null==n?w:gt(n,$r(t),t+""),n===w?r:n},$n.has=function(n,t){if(null==n)return false;var r=Ge.call(n,t); + +return r||Er(t)||(t=$r(t),n=1==t.length?n:gt(n,It(t,0,-1)),t=Pr(t),r=null!=n&&Ge.call(n,t)),r},$n.identity=Re,$n.includes=Qr,$n.indexOf=Dr,$n.inRange=function(n,t,r){return t=+t||0,"undefined"===typeof r?(r=t,t=0):r=+r||0,n>=xu(t,r)&&nr?bu(e+r,0):xu(r||0,e-1))+1;else if(r)return u=$t(n,t,true)-1,n=n[u],(t===t?t===n:n!==n)?u:-1;if(t!==t)return p(n,u,true);for(;u--;)if(n[u]===t)return u;return-1},$n.max=ii,$n.min=fi,$n.noConflict=function(){ +return _._=He,this},$n.noop=Se,$n.now=wo,$n.pad=function(n,t,r){n=u(n),t=+t;var e=n.length;return er?0:+r||0,n.length),n.lastIndexOf(t,r)==r},$n.sum=function(n,t,r){r&&Or(n,t,r)&&(t=null); + +var e=dr(),u=null==t;if(e===ut&&u||(u=false,t=e(t,r,3)),u){for(n=To(n)?n:Nr(n),t=n.length,r=0;t--;)r+=+n[t]||0;n=r}else n=St(n,t);return n},$n.template=function(n,t,r){var e=$n.templateSettings;r&&Or(n,t,r)&&(t=r=null),n=u(n),t=tt($u({},r||t),e,nt),r=tt($u({},t.imports),e.imports,nt);var o,i,f=Ko(r),a=Ut(r,f),c=0;r=t.interpolate||Rn;var l="__p+='";r=Me((t.escape||Rn).source+"|"+r.source+"|"+(r===gn?jn:Rn).source+"|"+(t.evaluate||Rn).source+"|$","g");var p="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":""; + +if(n.replace(r,function(t,r,e,u,f,a){return e||(e=u),l+=n.slice(c,a).replace(Cn,s),r&&(o=true,l+="'+__e("+r+")+'"),f&&(i=true,l+="';"+f+";\n__p+='"),e&&(l+="'+((__t=("+e+"))==null?'':__t)+'"),c=a+t.length,t}),l+="';",(t=t.variable)||(l="with(obj){"+l+"}"),l=(i?l.replace(fn,""):l).replace(an,"$1").replace(cn,"$1;"),l="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(o?",__e=_.escape":"")+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+l+"return __p}", +t=ei(function(){return $e(f,p+"return "+l).apply(w,a)}),t.source=l,le(t))throw t;return t},$n.trim=ke,$n.trimLeft=function(n,t,r){var e=n;return(n=u(n))?n.slice((r?Or(e,t,r):null==t)?g(n):i(n,t+"")):n},$n.trimRight=function(n,t,r){var e=n;return(n=u(n))?(r?Or(e,t,r):null==t)?n.slice(0,y(n)+1):n.slice(0,f(n,t+"")+1):n},$n.trunc=function(n,t,r){r&&Or(n,t,r)&&(t=null);var e=W;if(r=S,null!=t)if(se(t)){var o="separator"in t?t.separator:o,e="length"in t?+t.length||0:e;r="omission"in t?u(t.omission):r}else e=+t||0; + +if(n=u(n),e>=n.length)return n;if(e-=r.length,1>e)return r;if(t=n.slice(0,e),null==o)return t+r;if(_e(o)){if(n.slice(e).search(o)){var i,f=n.slice(0,e);for(o.global||(o=Me(o.source,(kn.exec(o)||"")+"g")),o.lastIndex=0;n=o.exec(f);)i=n.index;t=t.slice(0,null==i?e:i)}}else n.indexOf(o,e)!=e&&(o=t.lastIndexOf(o),-1u.__dir__?"Right":"") +}),u},Bn.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()},Bn.prototype[n+"RightWhile"]=function(n,t){return this.reverse()[r](n,t).reverse()}}),Kn(["first","last"],function(n,t){var r="take"+(t?"Right":"");Bn.prototype[n]=function(){return this[r](1).value()[0]}}),Kn(["initial","rest"],function(n,t){var r="drop"+(t?"":"Right");Bn.prototype[n]=function(){return this[r](1)}}),Kn(["pluck","where"],function(n,t){var r=t?"filter":"map",e=t?wt:Te;Bn.prototype[n]=function(n){return this[r](e(n)); + +}}),Bn.prototype.compact=function(){return this.filter(Re)},Bn.prototype.reject=function(n,t){return n=dr(n,t,1),this.filter(function(t){return!n(t)})},Bn.prototype.slice=function(n,t){n=null==n?0:+n||0;var r=this;return 0>n?r=this.takeRight(-n):n&&(r=this.drop(n)),t!==w&&(t=+t||0,r=0>t?r.dropRight(-t):r.take(t-n)),r},Bn.prototype.toArray=function(){return this.drop(0)},ht(Bn.prototype,function(n,t){var r=$n[t];if(r){var e=/^(?:filter|map|reject)|While$/.test(t),u=/^(?:first|last)$/.test(t);$n.prototype[t]=function(){ +function t(n){return n=[n],fu.apply(n,o),r.apply($n,n)}var o=arguments,i=this.__chain__,f=this.__wrapped__,a=!!this.__actions__.length,c=f instanceof Bn,l=o[0],s=c||To(f);return s&&e&&typeof l=="function"&&1!=l.length&&(c=s=false),c=c&&!a,u&&!i?c?n.call(f):r.call($n,this.value()):s?(f=n.apply(c?f:new Bn(this),o),u||!a&&!f.__actions__||(f.__actions__||(f.__actions__=[])).push({func:Jr,args:[t],thisArg:$n}),new zn(f,i)):this.thru(t)}}}),Kn("concat join pop push replace shift sort splice split unshift".split(" "),function(n){ +var t=(/^(?:replace|split)$/.test(n)?Ve:qe)[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:join|pop|replace|shift)$/.test(n);$n.prototype[n]=function(){var n=arguments;return e&&!this.__chain__?t.apply(this.value(),n):this[r](function(r){return t.apply(r,n)})}}),ht(Bn.prototype,function(n,t){var r=$n[t];if(r){var e=r.name;(Nu[e]||(Nu[e]=[])).push({name:t,func:r})}}),Nu[cr(null,A).name]=[{name:"wrapper",func:null}],Bn.prototype.clone=function(){var n=this.__actions__,t=this.__iteratees__,r=this.__views__,e=new Bn(this.__wrapped__); + +return e.__actions__=n?qn(n):null,e.__dir__=this.__dir__,e.__filtered__=this.__filtered__,e.__iteratees__=t?qn(t):null,e.__takeCount__=this.__takeCount__,e.__views__=r?qn(r):null,e},Bn.prototype.reverse=function(){if(this.__filtered__){var n=new Bn(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},Bn.prototype.value=function(){var n=this.__wrapped__.value();if(!To(n))return Ft(n,this.__actions__);var t,r=this.__dir__,e=0>r;t=n.length;for(var u=this.__views__,o=0,i=-1,f=u?u.length:0;++ip.index:u=_:!h(s))))continue n}else if(p=h(s), +_==$)s=p;else if(!p){if(_==F)continue n;break n}}c[a++]=s}return c},$n.prototype.chain=function(){return Gr(this)},$n.prototype.commit=function(){return new zn(this.value(),this.__chain__)},$n.prototype.plant=function(n){for(var t,r=this;r instanceof Ln;){var e=Lr(r);t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},$n.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof Bn?(this.__actions__.length&&(n=new Bn(this)),new zn(n.reverse(),this.__chain__)):this.thru(function(n){ +return n.reverse()})},$n.prototype.toString=function(){return this.value()+""},$n.prototype.run=$n.prototype.toJSON=$n.prototype.valueOf=$n.prototype.value=function(){return Ft(this.__wrapped__,this.__actions__)},$n.prototype.collect=$n.prototype.map,$n.prototype.head=$n.prototype.first,$n.prototype.select=$n.prototype.filter,$n.prototype.tail=$n.prototype.rest,$n}var w,b="3.8.0",x=1,A=2,j=4,k=8,O=16,E=32,I=64,R=128,C=256,W=30,S="...",T=150,U=16,N=0,F=1,$=2,L="Expected a function",z="__lodash_placeholder__",B="[object Arguments]",M="[object Array]",D="[object Boolean]",P="[object Date]",q="[object Error]",K="[object Function]",V="[object Number]",Y="[object Object]",Z="[object RegExp]",G="[object String]",J="[object ArrayBuffer]",X="[object Float32Array]",H="[object Float64Array]",Q="[object Int8Array]",nn="[object Int16Array]",tn="[object Int32Array]",rn="[object Uint8Array]",en="[object Uint8ClampedArray]",un="[object Uint16Array]",on="[object Uint32Array]",fn=/\b__p\+='';/g,an=/\b(__p\+=)''\+/g,cn=/(__e\(.*?\)|\b__t\))\+'';/g,ln=/&(?:amp|lt|gt|quot|#39|#96);/g,sn=/[&<>"'`]/g,pn=RegExp(ln.source),hn=RegExp(sn.source),_n=/<%-([\s\S]+?)%>/g,vn=/<%([\s\S]+?)%>/g,gn=/<%=([\s\S]+?)%>/g,yn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,dn=/^\w*$/,mn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g,wn=/[.*+?^${}()|[\]\/\\]/g,bn=RegExp(wn.source),xn=/[\u0300-\u036f\ufe20-\ufe23]/g,An=/\\(\\)?/g,jn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,kn=/\w*$/,On=/^0[xX]/,En=/^\[object .+?Constructor\]$/,In=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,Rn=/($^)/,Cn=/['\n\r\u2028\u2029\\]/g,Wn=RegExp("[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?=[A-Z\\xc0-\\xd6\\xd8-\\xde][a-z\\xdf-\\xf6\\xf8-\\xff]+)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+|[A-Z\\xc0-\\xd6\\xd8-\\xde]+|[0-9]+","g"),Sn=" \t\x0b\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000",Tn="Array ArrayBuffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Math Number Object RegExp Set String _ clearTimeout document isFinite parseInt setTimeout TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap window".split(" "),Un={}; + +Un[X]=Un[H]=Un[Q]=Un[nn]=Un[tn]=Un[rn]=Un[en]=Un[un]=Un[on]=true,Un[B]=Un[M]=Un[J]=Un[D]=Un[P]=Un[q]=Un[K]=Un["[object Map]"]=Un[V]=Un[Y]=Un[Z]=Un["[object Set]"]=Un[G]=Un["[object WeakMap]"]=false;var Nn={};Nn[B]=Nn[M]=Nn[J]=Nn[D]=Nn[P]=Nn[X]=Nn[H]=Nn[Q]=Nn[nn]=Nn[tn]=Nn[V]=Nn[Y]=Nn[Z]=Nn[G]=Nn[rn]=Nn[en]=Nn[un]=Nn[on]=true,Nn[q]=Nn[K]=Nn["[object Map]"]=Nn["[object Set]"]=Nn["[object WeakMap]"]=false;var Fn={leading:false,maxWait:0,trailing:false},$n={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A", +"\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u", +"\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss"},Ln={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},zn={"&":"&","<":"<",">":">",""":'"',"'":"'","`":"`"},Bn={"function":true,object:true},Mn={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Dn=Bn[typeof exports]&&exports&&!exports.nodeType&&exports,Pn=Bn[typeof module]&&module&&!module.nodeType&&module,qn=Bn[typeof self]&&self&&self.Object&&self,Kn=Bn[typeof window]&&window&&window.Object&&window,Vn=Pn&&Pn.exports===Dn&&Dn,Yn=Dn&&Pn&&typeof global=="object"&&global&&global.Object&&global||Kn!==(this&&this.window)&&Kn||qn||this,Zn=m(); + +typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Yn._=Zn, define(function(){return Zn})):Dn&&Pn?Vn?(Pn.exports=Zn)._=Zn:Dn._=Zn:Yn._=Zn}).call(this); \ No newline at end of file diff --git a/glances/plugins/glances_alert.py b/glances/plugins/glances_alert.py index 78c6c45a..660ba01a 100644 --- a/glances/plugins/glances_alert.py +++ b/glances/plugins/glances_alert.py @@ -29,7 +29,7 @@ from glances.plugins.glances_plugin import GlancesPlugin class Plugin(GlancesPlugin): - """Glances' alert plugin. + """Glances alert plugin. Only for display. """ @@ -42,7 +42,7 @@ class Plugin(GlancesPlugin): self.display_curse = True # Set the message position - self.set_align('bottom') + self.align = 'bottom' # Init the stats self.reset() @@ -68,17 +68,17 @@ class Plugin(GlancesPlugin): # Build the string message # Header if not self.stats: - msg = _("No warning or critical alert detected") + msg = 'No warning or critical alert detected' ret.append(self.curse_add_line(msg, "TITLE")) else: # Header - msg = _("Warning or critical alerts") + msg = 'Warning or critical alerts' ret.append(self.curse_add_line(msg, "TITLE")) logs_len = glances_logs.len() if logs_len > 1: - msg = _(" (lasts {0} entries)").format(logs_len) + msg = ' (lasts {0} entries)'.format(logs_len) else: - msg = _(" (one entry)") + msg = ' (one entry)' ret.append(self.curse_add_line(msg, "TITLE")) # Loop over alerts for alert in self.stats: @@ -90,15 +90,16 @@ class Plugin(GlancesPlugin): # Duration if alert[1] > 0: # If finished display duration - msg = ' ({0})'.format(datetime.fromtimestamp(alert[1]) - datetime.fromtimestamp(alert[0])) + msg = ' ({0})'.format(datetime.fromtimestamp(alert[1]) - + datetime.fromtimestamp(alert[0])) else: - msg = _(" (ongoing)") + msg = ' (ongoing)' ret.append(self.curse_add_line(msg)) ret.append(self.curse_add_line(" - ")) # Infos if alert[1] > 0: # If finished do not display status - msg = _("{0} on {1}").format(alert[2], alert[3]) + msg = '{0} on {1}'.format(alert[2], alert[3]) ret.append(self.curse_add_line(msg)) else: msg = str(alert[3]) @@ -107,11 +108,12 @@ class Plugin(GlancesPlugin): if self.approx_equal(alert[6], alert[4], tolerance=0.1): msg = ' ({0:.1f})'.format(alert[5]) else: - msg = _(" (Min:{0:.1f} Mean:{1:.1f} Max:{2:.1f})").format(alert[6], alert[5], alert[4]) + msg = ' (Min:{0:.1f} Mean:{1:.1f} Max:{2:.1f})'.format( + alert[6], alert[5], alert[4]) ret.append(self.curse_add_line(msg)) # else: - # msg = _(" Running...") + # msg = ' Running...' # ret.append(self.curse_add_line(msg)) # !!! Debug only @@ -121,9 +123,7 @@ class Plugin(GlancesPlugin): return ret def approx_equal(self, a, b, tolerance=0.0): - """ - Compare a with b using the tolerance (if numerical) - """ + """Compare a with b using the tolerance (if numerical).""" if str(int(a)).isdigit() and str(int(b)).isdigit(): return abs(a - b) <= max(abs(a), abs(b)) * tolerance else: diff --git a/glances/plugins/glances_batpercent.py b/glances/plugins/glances_batpercent.py index e2ced95c..1778ff95 100644 --- a/glances/plugins/glances_batpercent.py +++ b/glances/plugins/glances_batpercent.py @@ -28,12 +28,11 @@ try: import batinfo except ImportError: logger.debug("Batinfo library not found. Glances cannot grab battery info.") - pass class Plugin(GlancesPlugin): - """Glances' battery capacity plugin. + """Glances battery capacity plugin. stats is a list """ @@ -62,12 +61,12 @@ class Plugin(GlancesPlugin): # Reset stats self.reset() - if self.get_input() == 'local': + if self.input_method == 'local': # Update stats self.glancesgrabbat.update() self.stats = self.glancesgrabbat.get() - elif self.get_input() == 'snmp': + elif self.input_method == 'snmp': # Update stats using SNMP # Not avalaible pass @@ -94,7 +93,10 @@ class GlancesGrabBat(object): """Update the stats.""" if self.initok: self.bat.update() - self.bat_list = [{'label': _("Battery (%)"), 'value': self.getcapacitypercent()}] + self.bat_list = [{ + 'label': 'Battery', + 'value': self.battery_percent, + 'unit': '%'}] else: self.bat_list = [] @@ -102,7 +104,8 @@ class GlancesGrabBat(object): """Get the stats.""" return self.bat_list - def getcapacitypercent(self): + @property + def battery_percent(self): """Get batteries capacity percent.""" if not self.initok or not self.bat.stat: return [] @@ -112,7 +115,7 @@ class GlancesGrabBat(object): bsum = 0 for b in self.bat.stat: try: - bsum = bsum + int(b.capacity) + bsum += int(b.capacity) except ValueError: return [] diff --git a/glances/plugins/glances_core.py b/glances/plugins/glances_core.py index 20127c8b..4dce71c5 100644 --- a/glances/plugins/glances_core.py +++ b/glances/plugins/glances_core.py @@ -19,14 +19,14 @@ """CPU core plugin.""" -import psutil - from glances.plugins.glances_plugin import GlancesPlugin +import psutil + class Plugin(GlancesPlugin): - """Glances' CPU core plugin. + """Glances CPU core plugin. Get stats about CPU core number. @@ -56,7 +56,7 @@ class Plugin(GlancesPlugin): # Reset the stats self.reset() - if self.get_input() == 'local': + if self.input_method == 'local': # Update stats using the standard system lib # The PSUtil 2.0 include psutil.cpu_count() and psutil.cpu_count(logical=False) @@ -70,7 +70,7 @@ class Plugin(GlancesPlugin): except NameError: self.reset() - elif self.get_input() == 'snmp': + elif self.input_method == 'snmp': # Update stats using SNMP # http://stackoverflow.com/questions/5662467/how-to-find-out-the-number-of-cpus-using-snmp pass diff --git a/glances/plugins/glances_cpu.py b/glances/plugins/glances_cpu.py index 44d1c824..52e81a62 100644 --- a/glances/plugins/glances_cpu.py +++ b/glances/plugins/glances_cpu.py @@ -19,10 +19,10 @@ """CPU plugin.""" -import psutil - +from glances.core.glances_cpu_percent import cpu_percent from glances.plugins.glances_plugin import GlancesPlugin -# from glances.core.glances_logging import logger + +import psutil # SNMP OID # percentage of user CPU time: .1.3.6.1.4.1.2021.11.9.0 @@ -77,25 +77,25 @@ class Plugin(GlancesPlugin): # Grab CPU stats using psutil's cpu_percent and cpu_times_percent # methods - if self.get_input() == 'local': + if self.input_method == 'local': # Get all possible values for CPU stats: user, system, idle, # nice (UNIX), iowait (Linux), irq (Linux, FreeBSD), steal (Linux 2.6.11+) # The following stats are returned by the API but not displayed in the UI: # softirq (Linux), guest (Linux 2.6.24+), guest_nice (Linux 3.2.0+) - self.stats['total'] = psutil.cpu_percent(interval=0.0) + self.stats['total'] = cpu_percent.get() cpu_times_percent = psutil.cpu_times_percent(interval=0.0) for stat in ['user', 'system', 'idle', 'nice', 'iowait', 'irq', 'softirq', 'steal', 'guest', 'guest_nice']: if hasattr(cpu_times_percent, stat): self.stats[stat] = getattr(cpu_times_percent, stat) - elif self.get_input() == 'snmp': + elif self.input_method == 'snmp': # Update stats using SNMP - if self.get_short_system_name() in ('windows', 'esxi'): + if self.short_system_name in ('windows', 'esxi'): # Windows or VMWare ESXi # You can find the CPU utilization of windows system by querying the oid # Give also the number of core (number of element in the table) try: - cpu_stats = self.set_stats_snmp(snmp_oid=snmp_oid[self.get_short_system_name()], + cpu_stats = self.get_stats_snmp(snmp_oid=snmp_oid[self.short_system_name], bulk=True) except KeyError: self.reset() @@ -116,10 +116,10 @@ class Plugin(GlancesPlugin): else: # Default behavor try: - self.stats = self.set_stats_snmp( - snmp_oid=snmp_oid[self.get_short_system_name()]) + self.stats = self.get_stats_snmp( + snmp_oid=snmp_oid[self.short_system_name]) except KeyError: - self.stats = self.set_stats_snmp( + self.stats = self.get_stats_snmp( snmp_oid=snmp_oid['default']) if self.stats['idle'] == '': @@ -140,7 +140,7 @@ class Plugin(GlancesPlugin): return self.stats def update_views(self): - """Update stats views""" + """Update stats views.""" # Call the father's method GlancesPlugin.update_views(self) @@ -149,9 +149,8 @@ class Plugin(GlancesPlugin): for key in ['user', 'system', 'iowait']: if key in self.stats: self.views[key]['decoration'] = self.get_alert_log(self.stats[key], header=key) - self.views['total']['decoration'] = self.get_alert_log(self.stats['total'], header="system") # Alert only - for key in ['steal']: + for key in ['steal', 'total']: if key in self.stats: self.views[key]['decoration'] = self.get_alert(self.stats[key], header=key) # Optional @@ -160,12 +159,12 @@ class Plugin(GlancesPlugin): self.views[key]['optional'] = True def msg_curse(self, args=None): - """Return the list to display in the UI""" + """Return the list to display in the UI.""" # Init the return message ret = [] # Only process if stats exist... - if self.stats == {}: + if not self.stats: return ret # Build the string message @@ -173,7 +172,7 @@ class Plugin(GlancesPlugin): # exemple on Windows OS) idle_tag = 'user' not in self.stats # Header - msg = '{0:8}'.format(_("CPU")) + msg = '{0:8}'.format('CPU') ret.append(self.curse_add_line(msg, "TITLE")) # Total CPU usage msg = '{0:>5}%'.format(self.stats['total']) @@ -184,7 +183,7 @@ class Plugin(GlancesPlugin): ret.append(self.curse_add_line(msg)) # Nice CPU if 'nice' in self.stats: - msg = ' {0:8}'.format(_("nice:")) + msg = ' {0:8}'.format('nice:') ret.append(self.curse_add_line(msg, optional=self.get_views(key='nice', option='optional'))) msg = '{0:>5}%'.format(self.stats['nice']) ret.append(self.curse_add_line(msg, optional=self.get_views(key='nice', option='optional'))) @@ -192,19 +191,19 @@ class Plugin(GlancesPlugin): ret.append(self.curse_new_line()) # User CPU if 'user' in self.stats: - msg = '{0:8}'.format(_("user:")) + msg = '{0:8}'.format('user:') ret.append(self.curse_add_line(msg)) msg = '{0:>5}%'.format(self.stats['user']) ret.append(self.curse_add_line( msg, self.get_views(key='user', option='decoration'))) elif 'idle' in self.stats: - msg = '{0:8}'.format(_("idle:")) + msg = '{0:8}'.format('idle:') ret.append(self.curse_add_line(msg)) msg = '{0:>5}%'.format(self.stats['idle']) ret.append(self.curse_add_line(msg)) # IRQ CPU if 'irq' in self.stats: - msg = ' {0:8}'.format(_("irq:")) + msg = ' {0:8}'.format('irq:') ret.append(self.curse_add_line(msg, optional=self.get_views(key='irq', option='optional'))) msg = '{0:>5}%'.format(self.stats['irq']) ret.append(self.curse_add_line(msg, optional=self.get_views(key='irq', option='optional'))) @@ -212,19 +211,19 @@ class Plugin(GlancesPlugin): ret.append(self.curse_new_line()) # System CPU if 'system' in self.stats and not idle_tag: - msg = '{0:8}'.format(_("system:")) + msg = '{0:8}'.format('system:') ret.append(self.curse_add_line(msg)) msg = '{0:>5}%'.format(self.stats['system']) ret.append(self.curse_add_line( msg, self.get_views(key='system', option='decoration'))) else: - msg = '{0:8}'.format(_("core:")) + msg = '{0:8}'.format('core:') ret.append(self.curse_add_line(msg)) msg = '{0:>6}'.format(self.stats['nb_log_core']) ret.append(self.curse_add_line(msg)) # IOWait CPU if 'iowait' in self.stats: - msg = ' {0:8}'.format(_("iowait:")) + msg = ' {0:8}'.format('iowait:') ret.append(self.curse_add_line(msg, optional=self.get_views(key='iowait', option='optional'))) msg = '{0:>5}%'.format(self.stats['iowait']) ret.append(self.curse_add_line( @@ -234,13 +233,13 @@ class Plugin(GlancesPlugin): ret.append(self.curse_new_line()) # Idle CPU if 'idle' in self.stats and not idle_tag: - msg = '{0:8}'.format(_("idle:")) + msg = '{0:8}'.format('idle:') ret.append(self.curse_add_line(msg)) msg = '{0:>5}%'.format(self.stats['idle']) ret.append(self.curse_add_line(msg)) # Steal CPU usage if 'steal' in self.stats: - msg = ' {0:8}'.format(_("steal:")) + msg = ' {0:8}'.format('steal:') ret.append(self.curse_add_line(msg, optional=self.get_views(key='steal', option='optional'))) msg = '{0:>5}%'.format(self.stats['steal']) ret.append(self.curse_add_line( diff --git a/glances/plugins/glances_diskio.py b/glances/plugins/glances_diskio.py index e0ee3cb5..25b2bfe7 100644 --- a/glances/plugins/glances_diskio.py +++ b/glances/plugins/glances_diskio.py @@ -21,12 +21,13 @@ import operator -import psutil - # Import Glances libs from glances.core.glances_timer import getTimeSinceLastUpdate from glances.plugins.glances_plugin import GlancesPlugin +import psutil + + # Define the history items list # All items in this list will be historised if the --enable-history tag is set # 'color' define the graph color in #RGB format @@ -36,7 +37,7 @@ items_history_list = [{'name': 'read_bytes', 'color': '#00FF00', 'y_unit': 'B/s' class Plugin(GlancesPlugin): - """Glances' disks I/O plugin. + """Glances disks I/O plugin. stats is a list """ @@ -53,7 +54,7 @@ class Plugin(GlancesPlugin): self.reset() def get_key(self): - """Return the key of the list""" + """Return the key of the list.""" return 'disk_name' def reset(self): @@ -66,7 +67,7 @@ class Plugin(GlancesPlugin): # Reset stats self.reset() - if self.get_input() == 'local': + if self.input_method == 'local': # Update stats using the standard system lib # Grab the stat using the PsUtil disk_io_counters method # read_count: number of reads @@ -96,16 +97,15 @@ class Plugin(GlancesPlugin): diskio_new = diskiocounters for disk in diskio_new: try: - # Try necessary to manage dynamic disk creation/del - diskstat = {} - diskstat['time_since_update'] = time_since_update - diskstat['disk_name'] = disk - diskstat['read_bytes'] = ( - diskio_new[disk].read_bytes - - self.diskio_old[disk].read_bytes) - diskstat['write_bytes'] = ( - diskio_new[disk].write_bytes - - self.diskio_old[disk].write_bytes) + read_bytes = (diskio_new[disk].read_bytes - + self.diskio_old[disk].read_bytes) + write_bytes = (diskio_new[disk].write_bytes - + self.diskio_old[disk].write_bytes) + diskstat = { + 'time_since_update': time_since_update, + 'disk_name': disk, + 'read_bytes': read_bytes, + 'write_bytes': write_bytes} except KeyError: continue else: @@ -114,7 +114,7 @@ class Plugin(GlancesPlugin): # Save stats to compute next bitrate self.diskio_old = diskio_new - elif self.get_input() == 'snmp': + elif self.input_method == 'snmp': # Update stats using SNMP # No standard way for the moment... pass @@ -128,7 +128,7 @@ class Plugin(GlancesPlugin): return self.stats def update_views(self): - """Update stats views""" + """Update stats views.""" # Call the father's method GlancesPlugin.update_views(self) @@ -152,11 +152,11 @@ class Plugin(GlancesPlugin): # Build the string message # Header - msg = '{0:9}'.format(_("DISK I/O")) + msg = '{0:9}'.format('DISK I/O') ret.append(self.curse_add_line(msg, "TITLE")) - msg = '{0:>7}'.format(_("R/s")) + msg = '{0:>7}'.format('R/s') ret.append(self.curse_add_line(msg)) - msg = '{0:>7}'.format(_("W/s")) + msg = '{0:>7}'.format('W/s') ret.append(self.curse_add_line(msg)) # Disk list (sorted by name) for i in sorted(self.stats, key=operator.itemgetter(self.get_key())): diff --git a/glances/plugins/glances_docker.py b/glances/plugins/glances_docker.py index 692ac541..5ee72b33 100644 --- a/glances/plugins/glances_docker.py +++ b/glances/plugins/glances_docker.py @@ -19,8 +19,13 @@ """Docker plugin.""" +import numbers +import os +import re + # Import Glances libs from glances.core.glances_logging import logger +from glances.core.glances_timer import getTimeSinceLastUpdate from glances.plugins.glances_plugin import GlancesPlugin # Docker-py library (optional and Linux-only) @@ -33,14 +38,11 @@ except ImportError as e: docker_tag = False else: docker_tag = True -import os -import re -import numbers class Plugin(GlancesPlugin): - """Glances' Docker plugin. + """Glances Docker plugin. stats is a list """ @@ -59,7 +61,7 @@ class Plugin(GlancesPlugin): self.docker_client = False def connect(self, version=None): - """Connect to the Docker server""" + """Connect to the Docker server.""" # Init connection to the Docker API try: if version is None: @@ -82,7 +84,6 @@ class Plugin(GlancesPlugin): # 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)) if version: logger.debug("Try connection with Docker API version %s" % version.group(1)) @@ -112,8 +113,7 @@ class Plugin(GlancesPlugin): @GlancesPlugin._log_result_decorator def update(self): - """Update Docker stats using the input method. - """ + """Update Docker stats using the input method.""" # Reset stats self.reset() @@ -129,7 +129,7 @@ class Plugin(GlancesPlugin): if not docker_tag or (self.args is not None and self.args.disable_docker): return self.stats - if self.get_input() == 'local': + if self.input_method == 'local': # Update stats # Exemple: { # "KernelVersion": "3.16.4-tinycore64", @@ -150,26 +150,52 @@ class Plugin(GlancesPlugin): # u'Names': [u'/webstack_nginx_1'], # u'Id': u'b0da859e84eb4019cf1d965b15e9323006e510352c402d2f442ea632d61faaa5'}] self.stats['containers'] = self.docker_client.containers() - # Get CPU and MEMORY stats for containers + # Get stats for all containers for c in self.stats['containers']: - c['cpu'] = self.get_docker_cpu(c['Id']) - c['memory'] = self.get_docker_memory(c['Id']) + if not hasattr(self, 'docker_stats'): + # Create a dict with all the containers' stats instance + self.docker_stats = {} - elif self.get_input() == 'snmp': + # 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: + self.docker_stats[c['Id']] = self.docker_client.stats(c['Id'], decode=True) + logger.debug("Create Docker stats object for container {}".format(c['Id'])) + except (AttributeError, docker.errors.InvalidVersion) as e: + logger.error("Can not call Docker stats method {}".format(e)) + + # 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 Exception: + all_stats = {} + + c['cpu'] = self.get_docker_cpu(c['Id'], all_stats) + c['memory'] = self.get_docker_memory(c['Id'], all_stats) + # c['network'] = self.get_docker_network(c['Id'], all_stats) + + elif self.input_method == 'snmp': # Update stats using SNMP # Not available pass return self.stats - def get_docker_cpu(self, id): - """Return the container CPU usage by reading /sys/fs/cgroup/... + def get_docker_cpu_old(self, container_id): + """Return the container CPU usage by reading /sys/fs/cgroup/. + Input: id is the full container id - Output: a dict {'total': 1.49, 'user': 0.65, 'system': 0.84}""" + 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: + with open('/sys/fs/cgroup/cpuacct/docker/' + container_id + '/cpuacct.stat', 'r') as f: for line in f: m = re.search(r"(system|user)\s+(\d+)", line) if m: @@ -177,23 +203,77 @@ class Plugin(GlancesPlugin): 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): ret["total"] = ret["system"] + ret["user"] - for k in ret.keys(): - ret[k] = float(ret[k]) / ticks # Return the stats return ret - def get_docker_memory(self, id): - """Return the container MEMORY usage by reading /sys/fs/cgroup/... + def get_docker_cpu(self, container_id, all_stats): + """Return the container CPU usage. + Input: id is the full container id - Output: a dict {'rss': 1015808, 'cache': 356352}""" + all_stats is the output of the stats method of the Docker API + Output: a dict {'total': 1.49} + """ + cpu_new = {} + ret = {'total': 0.0} + + # Read the stats + # 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 + + 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 + + # Return the stats + return ret + + def get_docker_memory_old(self, container_id): + """Return the container MEMORY usage by reading /sys/fs/cgroup/. + + Input: id is the full container id + 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: + with open('/sys/fs/cgroup/memory/docker/' + container_id + '/memory.stat', 'r') as f: for line in f: m = re.search(r"(rss|cache)\s+(\d+)", line) if m: @@ -204,8 +284,78 @@ class Plugin(GlancesPlugin): # Return the stats return ret + def get_docker_memory(self, container_id, all_stats): + """Return the container MEMORY. + + Input: id is the full container id + all_stats is the output of the stats method of the Docker API + Output: a dict {'rss': 1015808, 'cache': 356352, 'usage': ..., 'max_usage': ...} + """ + ret = {} + # Read the stats + try: + ret['rss'] = all_stats['memory_stats']['stats']['rss'] + ret['cache'] = all_stats['memory_stats']['stats']['cache'] + ret['usage'] = all_stats['memory_stats']['usage'] + ret['max_usage'] = all_stats['memory_stats']['max_usage'] + except KeyError as e: + # all_stats do not have MEM information + 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 + return ret + + def get_docker_network(self, container_id, all_stats): + """Return the container network usage using the Docker API (v1.0 or higher). + + Input: id is the full container id + Output: a dict {'time_since_update': 3000, 'rx': 10, 'tx': 65}. + """ + # Init the returned dict + network_new = {} + + # Read the rx/tx stats (in bytes) + try: + netiocounters = all_stats["network"] + except KeyError as e: + # all_stats do not have NETWORK information + logger.debug("Can not grab NET usage for container {0} ({1})".format(container_id, e)) + # No fallback available... + return network_new + + # Previous network interface stats are stored in the network_old variable + if not hasattr(self, 'netiocounters_old'): + # First call, we init the network_old var + self.netiocounters_old = {} + try: + self.netiocounters_old[container_id] = netiocounters + except (IOError, UnboundLocalError): + pass + + if container_id not in self.netiocounters_old: + try: + self.netiocounters_old[container_id] = netiocounters + except (IOError, UnboundLocalError): + pass + else: + # 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_{}'.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"] + network_new['cumulative_tx'] = netiocounters["tx_bytes"] + + # Save stats to compute next bitrate + self.netiocounters_old[container_id] = netiocounters + + # Return the stats + return network_new + def get_user_ticks(self): - """return the user ticks by reading the environment variable""" + """Return the user ticks by reading the environment variable.""" return os.sysconf(os.sysconf_names['SC_CLK_TCK']) def msg_curse(self, args=None): @@ -214,32 +364,36 @@ class Plugin(GlancesPlugin): ret = [] # Only process if stats exist (and non null) and display plugin enable... - if self.stats == {} or args.disable_docker or len(self.stats['containers']) == 0: + if not self.stats or args.disable_docker or len(self.stats['containers']) == 0: return ret # Build the string message # Title - msg = '{0}'.format(_("CONTAINERS")) + msg = '{0}'.format('CONTAINERS') ret.append(self.curse_add_line(msg, "TITLE")) msg = ' {0}'.format(len(self.stats['containers'])) ret.append(self.curse_add_line(msg)) - msg = ' ({0} {1})'.format(_("served by Docker"), + msg = ' ({0} {1})'.format('served by Docker', self.stats['version']["Version"]) ret.append(self.curse_add_line(msg)) ret.append(self.curse_new_line()) # Header ret.append(self.curse_new_line()) - msg = '{0:>14}'.format(_("Id")) + msg = '{0:>14}'.format('Id') ret.append(self.curse_add_line(msg)) - msg = ' {0:20}'.format(_("Name")) + msg = ' {0:20}'.format('Name') ret.append(self.curse_add_line(msg)) - msg = '{0:>26}'.format(_("Status")) + msg = '{0:>26}'.format('Status') ret.append(self.curse_add_line(msg)) - msg = '{0:>6}'.format(_("CPU%")) + msg = '{0:>6}'.format('CPU%') ret.append(self.curse_add_line(msg)) - msg = '{0:>6}'.format(_("MEM")) + msg = '{0:>7}'.format('MEM') ret.append(self.curse_add_line(msg)) - msg = ' {0:8}'.format(_("Command")) + # msg = '{0:>6}'.format('Rx/s') + # ret.append(self.curse_add_line(msg)) + # msg = '{0:>6}'.format('Tx/s') + # ret.append(self.curse_add_line(msg)) + msg = ' {0:8}'.format('Command') ret.append(self.curse_add_line(msg)) # Data for container in self.stats['containers']: @@ -252,7 +406,7 @@ class Plugin(GlancesPlugin): if len(name) > 20: name = '_' + name[:-19] else: - name[0:20] + name = name[:20] msg = ' {0:20}'.format(name) ret.append(self.curse_add_line(msg)) # Status @@ -268,10 +422,18 @@ class Plugin(GlancesPlugin): ret.append(self.curse_add_line(msg)) # MEM try: - msg = '{0:>6}'.format(self.auto_unit(container['memory']['rss'])) + msg = '{0:>7}'.format(self.auto_unit(container['memory']['usage'])) except KeyError: - msg = '{0:>6}'.format('?') + msg = '{0:>7}'.format('?') ret.append(self.curse_add_line(msg)) + # NET RX/TX + # for r in ['rx', 'tx']: + # try: + # value = self.auto_unit(int(container['network'][r] // container['network']['time_since_update'] * 8)) + "b" + # msg = '{0:>6}'.format(value) + # except KeyError: + # msg = '{0:>6}'.format('?') + # ret.append(self.curse_add_line(msg)) # Command msg = ' {0}'.format(container['Command']) ret.append(self.curse_add_line(msg)) @@ -279,7 +441,7 @@ class Plugin(GlancesPlugin): return ret def container_alert(self, status): - """Analyse the container status""" + """Analyse the container status.""" if "Paused" in status: return 'CAREFUL' else: diff --git a/glances/plugins/glances_fs.py b/glances/plugins/glances_fs.py index 57719ced..cb488143 100644 --- a/glances/plugins/glances_fs.py +++ b/glances/plugins/glances_fs.py @@ -21,10 +21,10 @@ import operator +from glances.plugins.glances_plugin import GlancesPlugin + 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. @@ -64,7 +64,7 @@ items_history_list = [{'name': 'percent', 'color': '#00FF00'}] class Plugin(GlancesPlugin): - """Glances' file system plugin. + """Glances file system plugin. stats is a list """ @@ -81,7 +81,7 @@ class Plugin(GlancesPlugin): self.reset() def get_key(self): - """Return the key of the list""" + """Return the key of the list.""" return 'mnt_point' def reset(self): @@ -94,7 +94,7 @@ class Plugin(GlancesPlugin): # Reset the list self.reset() - if self.get_input() == 'local': + if self.input_method == 'local': # Update stats using the standard system lib # Grab the stats using the PsUtil disk_partitions @@ -105,12 +105,17 @@ class Plugin(GlancesPlugin): except UnicodeDecodeError: return self.stats + # Optionnal hack to allow logicals mounts points (issue #448) + # Ex: Had to put 'allow=zfs' in the [fs] section of the conf file + # to allow zfs monitoring + for fstype in self.get_conf_value('allow'): + try: + fs_stat += [f for f in psutil.disk_partitions(all=True) if f.fstype.find(fstype) >= 0] + except UnicodeDecodeError: + return self.stats + # Loop over fs for fs in fs_stat: - fs_current = {} - fs_current['device_name'] = fs.device - fs_current['fs_type'] = fs.fstype - fs_current['mnt_point'] = fs.mountpoint # Grab the disk usage try: fs_usage = psutil.disk_usage(fs.mountpoint) @@ -118,52 +123,56 @@ class Plugin(GlancesPlugin): # Correct issue #346 # Disk is ejected during the command continue - fs_current['size'] = fs_usage.total - fs_current['used'] = fs_usage.used - fs_current['free'] = fs_usage.total - fs_usage.used - fs_current['percent'] = fs_usage.percent - fs_current['key'] = self.get_key() + fs_current = { + 'device_name': fs.device, + 'fs_type': fs.fstype, + 'mnt_point': fs.mountpoint, + 'size': fs_usage.total, + 'used': fs_usage.used, + 'free': fs_usage.total - fs_usage.used, + 'percent': fs_usage.percent, + 'key': self.get_key()} self.stats.append(fs_current) - elif self.get_input() == 'snmp': + elif self.input_method == 'snmp': # Update stats using SNMP # SNMP bulk command to get all file system in one shot try: - fs_stat = self.set_stats_snmp(snmp_oid=snmp_oid[self.get_short_system_name()], + fs_stat = self.get_stats_snmp(snmp_oid=snmp_oid[self.short_system_name], bulk=True) except KeyError: - fs_stat = self.set_stats_snmp(snmp_oid=snmp_oid['default'], + fs_stat = self.get_stats_snmp(snmp_oid=snmp_oid['default'], bulk=True) # Loop over fs - if self.get_short_system_name() in ('windows', 'esxi'): + if self.short_system_name in ('windows', 'esxi'): # Windows or ESXi tips for fs in fs_stat: - # Memory stats are grabed in the same OID table (ignore it) + # Memory stats are grabbed in the same OID table (ignore it) if fs == 'Virtual Memory' or fs == 'Physical Memory' or fs == 'Real Memory': continue - fs_current = {} - fs_current['device_name'] = '' - fs_current['mnt_point'] = fs.partition(' ')[0] - fs_current['size'] = int( - fs_stat[fs]['size']) * int(fs_stat[fs]['alloc_unit']) - fs_current['used'] = int( - fs_stat[fs]['used']) * int(fs_stat[fs]['alloc_unit']) - fs_current['percent'] = float( - fs_current['used'] * 100 / fs_current['size']) - fs_current['key'] = self.get_key() + size = int(fs_stat[fs]['size']) * int(fs_stat[fs]['alloc_unit']) + used = int(fs_stat[fs]['used']) * int(fs_stat[fs]['alloc_unit']) + percent = float(used * 100 / size) + fs_current = { + 'device_name': '', + 'mnt_point': fs.partition(' ')[0], + 'size': size, + 'used': used, + 'percent': percent, + 'key': self.get_key()} self.stats.append(fs_current) else: - # Default behavor + # Default behavior for fs in fs_stat: - fs_current = {} - fs_current['device_name'] = fs_stat[fs]['device_name'] - fs_current['mnt_point'] = fs - fs_current['size'] = int(fs_stat[fs]['size']) * 1024 - fs_current['used'] = int(fs_stat[fs]['used']) * 1024 - fs_current['percent'] = float(fs_stat[fs]['percent']) - fs_current['key'] = self.get_key() + fs_current = { + 'device_name': fs_stat[fs]['device_name'], + 'mnt_point': fs, + 'size': int(fs_stat[fs]['size']) * 1024, + 'used': int(fs_stat[fs]['used']) * 1024, + 'percent': float(fs_stat[fs]['percent']), + 'key': self.get_key()} self.stats.append(fs_current) # Update the history list @@ -175,14 +184,15 @@ class Plugin(GlancesPlugin): return self.stats def update_views(self): - """Update stats views""" + """Update stats views.""" # Call the father's method GlancesPlugin.update_views(self) # Add specifics informations # Alert for i in self.stats: - self.views[i[self.get_key()]]['used']['decoration'] = self.get_alert(i['used'], max=i['size'], header=i['mnt_point']) + self.views[i[self.get_key()]]['used']['decoration'] = self.get_alert( + i['used'], maximum=i['size'], header=i['mnt_point']) def msg_curse(self, args=None, max_width=None): """Return the dict to display in the curse interface.""" @@ -202,14 +212,14 @@ class Plugin(GlancesPlugin): # Build the string message # Header - msg = '{0:{width}}'.format(_("FILE SYS"), width=fsname_max_width) + msg = '{0:{width}}'.format('FILE SYS', width=fsname_max_width) ret.append(self.curse_add_line(msg, "TITLE")) if args.fs_free_space: - msg = '{0:>7}'.format(_("Free")) + msg = '{0:>7}'.format('Free') else: - msg = '{0:>7}'.format(_("Used")) + msg = '{0:>7}'.format('Used') ret.append(self.curse_add_line(msg)) - msg = '{0:>7}'.format(_("Total")) + msg = '{0:>7}'.format('Total') ret.append(self.curse_add_line(msg)) # Disk list (sorted by name) diff --git a/glances/plugins/glances_hddtemp.py b/glances/plugins/glances_hddtemp.py index 82f29f1b..972dba4f 100644 --- a/glances/plugins/glances_hddtemp.py +++ b/glances/plugins/glances_hddtemp.py @@ -24,12 +24,13 @@ import os import socket # Import Glances libs +from glances.core.glances_logging import logger from glances.plugins.glances_plugin import GlancesPlugin class Plugin(GlancesPlugin): - """Glances' HDD temperature sensors plugin. + """Glances HDD temperature sensors plugin. stats is a list """ @@ -39,7 +40,7 @@ class Plugin(GlancesPlugin): GlancesPlugin.__init__(self, args=args) # Init the sensor class - self.glancesgrabhddtemp = GlancesGrabHDDTemp() + self.glancesgrabhddtemp = GlancesGrabHDDTemp(args=args) # We do not want to display the stat in a dedicated area # The HDD temp is displayed within the sensors plugin @@ -57,7 +58,7 @@ class Plugin(GlancesPlugin): # Reset stats self.reset() - if self.get_input() == 'local': + if self.input_method == 'local': # Update stats using the standard system lib self.stats = self.glancesgrabhddtemp.get() @@ -73,8 +74,9 @@ class GlancesGrabHDDTemp(object): """Get hddtemp stats using a socket connection.""" - def __init__(self, host='127.0.0.1', port=7634): + def __init__(self, host='127.0.0.1', port=7634, args=None): """Init hddtemp stats.""" + self.args = args self.host = host self.port = port self.cache = "" @@ -89,6 +91,10 @@ class GlancesGrabHDDTemp(object): # Reset the list self.reset() + # Only update if --disable-hddtemp is not set + if self.args is None or self.args.disable_hddtemp: + return + # Fetch the data data = self.fetch() @@ -125,7 +131,10 @@ class GlancesGrabHDDTemp(object): sck.connect((self.host, self.port)) data = sck.recv(4096) sck.close() - except socket.error: + except socket.error as e: + logger.warning("Can not connect to an HDDtemp server ({0}:{1} => {2})".format(self.host, self.port, e)) + logger.debug("Disable the HDDtemp module. Use the --disable-hddtemp to hide the previous message.") + self.args.disable_hddtemp = True data = "" return data diff --git a/glances/plugins/glances_help.py b/glances/plugins/glances_help.py index bf1f18f6..333c3a89 100644 --- a/glances/plugins/glances_help.py +++ b/glances/plugins/glances_help.py @@ -30,7 +30,7 @@ from glances.plugins.glances_plugin import GlancesPlugin class Plugin(GlancesPlugin): - """Glances' help plugin.""" + """Glances help plugin.""" def __init__(self, args=None, config=None): """Init the plugin.""" @@ -42,10 +42,60 @@ class Plugin(GlancesPlugin): # We want to display the stat in the curse interface self.display_curse = True + # init data dictionary + self.view_data = {} + self.generate_view_data() + def update(self): """No stats. It is just a plugin to display the help.""" pass + def generate_view_data(self): + self.view_data['version'] = '{0} {1}'.format(appname.title(), version) + self.view_data['psutil_version'] = ' with PSutil {0}'.format(psutil_version) + + try: + self.view_data['configuration_file'] = 'Configuration file: {0}'.format(self.config.loaded_config_file) + except AttributeError: + pass + + msg_col = ' {0:1} {1:35}' + msg_col2 = ' {0:1} {1:35}' + self.view_data['sort_auto'] = msg_col.format('a', 'Sort processes automatically') + self.view_data['sort_network'] = msg_col2.format('b', 'Bytes or bits for network I/O') + self.view_data['sort_cpu'] = msg_col.format('c', 'Sort processes by CPU%') + self.view_data['show_hide_alert'] = msg_col2.format('l', 'Show/hide alert logs') + self.view_data['sort_mem'] = msg_col.format('m', 'Sort processes by MEM%') + self.view_data['sort_user'] = msg_col.format('u', 'Sort processes by USER') + self.view_data['delete_warning_alerts'] = msg_col2.format('w', 'Delete warning alerts') + self.view_data['sort_proc'] = msg_col.format('p', 'Sort processes by name') + self.view_data['delete_warning_critical_alerts'] = msg_col2.format('x', 'Delete warning and critical alerts') + self.view_data['sort_io'] = msg_col.format('i', 'Sort processes by I/O rate') + self.view_data['percpu'] = msg_col2.format('1', 'Global CPU or per-CPU stats') + self.view_data['sort_cpu_times'] = msg_col.format('t', 'Sort processes by TIME') + self.view_data['show_hide_help'] = msg_col2.format('h', 'Show/hide this help screen') + self.view_data['show_hide_diskio'] = msg_col.format('d', 'Show/hide disk I/O stats') + self.view_data['view_network_io_combination'] = msg_col2.format('T', 'View network I/O as combination') + self.view_data['show_hide_filesystem'] = msg_col.format('f', 'Show/hide filesystem stats') + self.view_data['view_cumulative_network'] = msg_col2.format('U', 'View cumulative network I/O') + self.view_data['show_hide_network'] = msg_col.format('n', 'Show/hide network stats') + self.view_data['show_hide_filesytem_freespace'] = msg_col2.format('F', 'Show filesystem free space') + self.view_data['show_hide_sensors'] = msg_col.format('s', 'Show/hide sensors stats') + self.view_data['generate_graphs'] = msg_col2.format('g', 'Generate graphs for current history') + self.view_data['show_hide_left_sidebar'] = msg_col.format('2', 'Show/hide left sidebar') + self.view_data['reset_history'] = msg_col2.format('r', 'Reset history') + self.view_data['enable_disable_process_stats'] = msg_col.format('z', 'Enable/disable processes stats') + self.view_data['quit'] = msg_col2.format('q', 'Quit (Esc and Ctrl-C also work)') + self.view_data['enable_disable_top_extends_stats'] = msg_col.format('e', 'Enable/disable top extended stats') + self.view_data['enable_disable_short_processname'] = msg_col.format('/', 'Enable/disable short processes name') + self.view_data['enable_disable_docker'] = msg_col2.format('D', 'Enable/disable Docker stats') + self.view_data['enable_disable_quick_look'] = msg_col.format('3', 'Enable/disable quick look plugin') + self.view_data['show_hide_ip'] = msg_col2.format('I', 'Show/hide IP module') + self.view_data['edit_pattern_filter'] = 'ENTER: Edit the process filter pattern' + + def get_view_data(self, args=None): + return self.view_data + def msg_curse(self, args=None): """Return the list to display in the curse interface.""" # Init the return message @@ -53,101 +103,69 @@ class Plugin(GlancesPlugin): # Build the string message # Header - msg = '{0} {1}'.format(appname.title(), version) - ret.append(self.curse_add_line(msg, "TITLE")) - msg = _(" with PSutil {0}").format(psutil_version) - ret.append(self.curse_add_line(msg)) + ret.append(self.curse_add_line(self.view_data['version'], 'TITLE')) + ret.append(self.curse_add_line(self.view_data['psutil_version'])) ret.append(self.curse_new_line()) # Configuration file path - try: - msg = '{0}: {1}'.format(_("Configuration file"), self.config.get_loaded_config_file()) - except AttributeError: - pass - else: + if 'configuration_file' in self.view_data: ret.append(self.curse_new_line()) - ret.append(self.curse_add_line(msg)) + ret.append(self.curse_add_line(self.view_data['configuration_file'])) ret.append(self.curse_new_line()) # Keys - msg_col = ' {0:1} {1:35}' - msg_col2 = ' {0:1} {1:35}' + ret.append(self.curse_new_line()) + ret.append(self.curse_add_line(self.view_data['sort_auto'])) + ret.append(self.curse_add_line(self.view_data['sort_network'])) + ret.append(self.curse_new_line()) + ret.append(self.curse_add_line(self.view_data['sort_cpu'])) + ret.append(self.curse_add_line(self.view_data['show_hide_alert'])) + ret.append(self.curse_new_line()) + + ret.append(self.curse_add_line(self.view_data['sort_mem'])) + ret.append(self.curse_add_line(self.view_data['delete_warning_alerts'])) + ret.append(self.curse_new_line()) + ret.append(self.curse_add_line(self.view_data['sort_user'])) + ret.append(self.curse_add_line(self.view_data['delete_warning_critical_alerts'])) + ret.append(self.curse_new_line()) + ret.append(self.curse_add_line(self.view_data['sort_proc'])) + ret.append(self.curse_add_line(self.view_data['percpu'])) + ret.append(self.curse_new_line()) + ret.append(self.curse_add_line(self.view_data['sort_io'])) + ret.append(self.curse_add_line(self.view_data['show_hide_ip'])) + ret.append(self.curse_new_line()) + ret.append(self.curse_add_line(self.view_data['sort_cpu_times'])) + ret.append(self.curse_add_line(self.view_data['enable_disable_docker'])) + ret.append(self.curse_new_line()) + ret.append(self.curse_add_line(self.view_data['show_hide_diskio'])) + ret.append(self.curse_add_line(self.view_data['view_network_io_combination'])) + ret.append(self.curse_new_line()) + ret.append(self.curse_add_line(self.view_data['show_hide_filesystem'])) + ret.append(self.curse_add_line(self.view_data['view_cumulative_network'])) + ret.append(self.curse_new_line()) + ret.append(self.curse_add_line(self.view_data['show_hide_network'])) + ret.append(self.curse_add_line(self.view_data['show_hide_filesytem_freespace'])) + ret.append(self.curse_new_line()) + ret.append(self.curse_add_line(self.view_data['show_hide_sensors'])) + ret.append(self.curse_add_line(self.view_data['generate_graphs'])) + ret.append(self.curse_new_line()) + ret.append(self.curse_add_line(self.view_data['show_hide_left_sidebar'])) + ret.append(self.curse_add_line(self.view_data['reset_history'])) + ret.append(self.curse_new_line()) + ret.append(self.curse_add_line(self.view_data['enable_disable_process_stats'])) + ret.append(self.curse_add_line(self.view_data['show_hide_help'])) + ret.append(self.curse_new_line()) + ret.append(self.curse_add_line(self.view_data['enable_disable_quick_look'])) + ret.append(self.curse_add_line(self.view_data['quit'])) + ret.append(self.curse_new_line()) + ret.append(self.curse_add_line(self.view_data['enable_disable_top_extends_stats'])) + ret.append(self.curse_new_line()) + ret.append(self.curse_add_line(self.view_data['enable_disable_short_processname'])) + ret.append(self.curse_new_line()) ret.append(self.curse_new_line()) - msg = msg_col.format("a", _("Sort processes automatically")) - ret.append(self.curse_add_line(msg)) - msg = msg_col2.format("b", _("Bytes or bits for network I/O")) - ret.append(self.curse_add_line(msg)) - ret.append(self.curse_new_line()) - msg = msg_col.format("c", _("Sort processes by CPU%")) - ret.append(self.curse_add_line(msg)) - msg = msg_col2.format("l", _("Show/hide alert logs")) - ret.append(self.curse_add_line(msg)) - ret.append(self.curse_new_line()) - msg = msg_col.format("m", _("Sort processes by MEM%")) - ret.append(self.curse_add_line(msg)) - msg = msg_col2.format("w", _("Delete warning alerts")) - ret.append(self.curse_add_line(msg)) - ret.append(self.curse_new_line()) - msg = msg_col.format("p", _("Sort processes by name")) - ret.append(self.curse_add_line(msg)) - msg = msg_col2.format("x", _("Delete warning and critical alerts")) - ret.append(self.curse_add_line(msg)) - ret.append(self.curse_new_line()) - msg = msg_col.format("i", _("Sort processes by I/O rate")) - ret.append(self.curse_add_line(msg)) - msg = msg_col2.format("1", _("Global CPU or per-CPU stats")) - ret.append(self.curse_add_line(msg)) - ret.append(self.curse_new_line()) - msg = msg_col.format("t", _("Sort processes by CPU times")) - ret.append(self.curse_add_line(msg)) - msg = msg_col2.format("h", _("Show/hide this help screen")) - ret.append(self.curse_add_line(msg)) - ret.append(self.curse_new_line()) - msg = msg_col.format("d", _("Show/hide disk I/O stats")) - ret.append(self.curse_add_line(msg)) - msg = msg_col2.format("T", _("View network I/O as combination")) - ret.append(self.curse_add_line(msg)) - ret.append(self.curse_new_line()) - msg = msg_col.format("f", _("Show/hide filesystem stats")) - ret.append(self.curse_add_line(msg)) - msg = msg_col2.format("u", _("View cumulative network I/O")) - ret.append(self.curse_add_line(msg)) - ret.append(self.curse_new_line()) - msg = msg_col.format("n", _("Show/hide network stats")) - ret.append(self.curse_add_line(msg)) - msg = msg_col2.format("F", _("Show filesystem free space")) - ret.append(self.curse_add_line(msg)) - ret.append(self.curse_new_line()) - msg = msg_col.format("s", _("Show/hide sensors stats")) - ret.append(self.curse_add_line(msg)) - msg = msg_col2.format("g", _("Generate graphs for current history")) - ret.append(self.curse_add_line(msg)) - ret.append(self.curse_new_line()) - msg = msg_col.format("2", _("Show/hide left sidebar")) - ret.append(self.curse_add_line(msg)) - msg = msg_col2.format("r", _("Reset history")) - ret.append(self.curse_add_line(msg)) - ret.append(self.curse_new_line()) - msg = msg_col.format("z", _("Enable/disable processes stats")) - ret.append(self.curse_add_line(msg)) - msg = msg_col2.format("q", _("Quit (Esc and Ctrl-C also work)")) - ret.append(self.curse_add_line(msg)) - ret.append(self.curse_new_line()) - msg = msg_col.format("e", _("Enable/disable top extended stats")) - ret.append(self.curse_add_line(msg)) - ret.append(self.curse_new_line()) - msg = msg_col.format("/", _("Enable/disable short processes name")) - ret.append(self.curse_add_line(msg)) - ret.append(self.curse_new_line()) - msg = msg_col.format("D", _("Enable/disable Docker stats")) - ret.append(self.curse_add_line(msg)) - - ret.append(self.curse_new_line()) - ret.append(self.curse_new_line()) - msg = '{0}: {1}'.format("ENTER", _("Edit the process filter pattern")) - ret.append(self.curse_add_line(msg)) + ret.append(self.curse_add_line(self.view_data['edit_pattern_filter'])) # Return the message with decoration return ret diff --git a/glances/plugins/glances_ip.py b/glances/plugins/glances_ip.py new file mode 100644 index 00000000..e3491ac7 --- /dev/null +++ b/glances/plugins/glances_ip.py @@ -0,0 +1,123 @@ +# -*- coding: utf-8 -*- +# +# This file is part of Glances. +# +# Copyright (C) 2015 Nicolargo +# +# 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 . + +"""IP plugin.""" + +# Import system libs +try: + import netifaces + netifaces_tag = True +except ImportError: + netifaces_tag = False + +# Import Glances libs +from glances.core.glances_logging import logger +from glances.plugins.glances_plugin import GlancesPlugin + + +class Plugin(GlancesPlugin): + + """Glances IP Plugin. + + stats is a dict + """ + + def __init__(self, args=None): + """Init the plugin.""" + GlancesPlugin.__init__(self, args=args) + + # We want to display the stat in the curse interface + self.display_curse = True + + # Init the stats + self.reset() + + def reset(self): + """Reset/init the stats.""" + self.stats = {} + + @GlancesPlugin._log_result_decorator + def update(self): + """Update IP stats using the input method. + + Stats is dict + """ + # Reset stats + self.reset() + + if self.input_method == 'local' and netifaces_tag: + # Update stats using the netifaces lib + try: + default_gw = netifaces.gateways()['default'][netifaces.AF_INET] + except KeyError: + logger.debug("Can not grab the default gateway") + else: + try: + self.stats['address'] = netifaces.ifaddresses(default_gw[1])[netifaces.AF_INET][0]['addr'] + self.stats['mask'] = netifaces.ifaddresses(default_gw[1])[netifaces.AF_INET][0]['netmask'] + self.stats['mask_cidr'] = self.ip_to_cidr(self.stats['mask']) + self.stats['gateway'] = netifaces.gateways()['default'][netifaces.AF_INET][0] + except KeyError as e: + logger.debug("Can not grab IP information (%s)".format(e)) + + elif self.input_method == 'snmp': + # Not implemented yet + pass + + # Update the view + self.update_views() + + return self.stats + + def update_views(self): + """Update stats views.""" + # Call the father's method + GlancesPlugin.update_views(self) + + # Add specifics informations + # Optional + for key in self.stats.keys(): + self.views[key]['optional'] = True + + def msg_curse(self, args=None): + """Return the dict to display in the curse interface.""" + # Init the return message + ret = [] + + # Only process if stats exist and display plugin enable... + if not self.stats or args.disable_ip: + return ret + + # Build the string message + msg = ' - ' + ret.append(self.curse_add_line(msg)) + msg = 'IP ' + ret.append(self.curse_add_line(msg, 'TITLE')) + msg = '{0:}/{1}'.format(self.stats['address'], self.stats['mask_cidr']) + ret.append(self.curse_add_line(msg)) + + return ret + + @staticmethod + def ip_to_cidr(ip): + """Convert IP address to CIDR. + + Example: '255.255.255.0' will return 24 + """ + return sum(map(lambda x: int(x) << 8, ip.split('.'))) // 8128 diff --git a/glances/plugins/glances_load.py b/glances/plugins/glances_load.py index aa6e8a13..8f7ea2e0 100644 --- a/glances/plugins/glances_load.py +++ b/glances/plugins/glances_load.py @@ -44,7 +44,7 @@ items_history_list = [{'name': 'min1', 'color': '#0000FF'}, class Plugin(GlancesPlugin): - """Glances' load plugin. + """Glances load plugin. stats is a dict """ @@ -76,7 +76,7 @@ class Plugin(GlancesPlugin): # Reset stats self.reset() - if self.get_input() == 'local': + if self.input_method == 'local': # Update stats using the standard system lib # Get the load using the os standard lib @@ -89,9 +89,9 @@ class Plugin(GlancesPlugin): 'min5': load[1], 'min15': load[2], 'cpucore': self.nb_log_core} - elif self.get_input() == 'snmp': + elif self.input_method == 'snmp': # Update stats using SNMP - self.stats = self.set_stats_snmp(snmp_oid=snmp_oid) + self.stats = self.get_stats_snmp(snmp_oid=snmp_oid) if self.stats['min1'] == '': self.reset() @@ -117,16 +117,16 @@ class Plugin(GlancesPlugin): return self.stats def update_views(self): - """Update stats views""" + """Update stats views.""" # Call the father's method GlancesPlugin.update_views(self) # Add specifics informations try: # Alert and log - self.views['min15']['decoration'] = self.get_alert_log(self.stats['min15'], max=100 * self.stats['cpucore']) + self.views['min15']['decoration'] = self.get_alert_log(self.stats['min15'], maximum=100 * self.stats['cpucore']) # Alert only - self.views['min5']['decoration'] = self.get_alert(self.stats['min5'], max=100 * self.stats['cpucore']) + self.views['min5']['decoration'] = self.get_alert(self.stats['min5'], maximum=100 * self.stats['cpucore']) except KeyError: # try/except mandatory for Windows compatibility (no load stats) pass @@ -137,28 +137,28 @@ class Plugin(GlancesPlugin): ret = [] # Only process if stats exist... - if self.stats == {}: + if not self.stats: return ret # Build the string message # Header - msg = '{0:8}'.format(_("LOAD")) + msg = '{0:8}'.format('LOAD') ret.append(self.curse_add_line(msg, "TITLE")) # Core number if self.stats['cpucore'] > 0: - msg = _("{0:d}-core").format(int(self.stats['cpucore']), '>1') + msg = '{0}-core'.format(int(self.stats['cpucore'])) ret.append(self.curse_add_line(msg)) # New line ret.append(self.curse_new_line()) # 1min load - msg = '{0:8}'.format(_("1 min:")) + msg = '{0:8}'.format('1 min:') ret.append(self.curse_add_line(msg)) msg = '{0:>6.2f}'.format(self.stats['min1']) ret.append(self.curse_add_line(msg)) # New line ret.append(self.curse_new_line()) # 5min load - msg = '{0:8}'.format(_("5 min:")) + msg = '{0:8}'.format('5 min:') ret.append(self.curse_add_line(msg)) msg = '{0:>6.2f}'.format(self.stats['min5']) ret.append(self.curse_add_line( @@ -166,7 +166,7 @@ class Plugin(GlancesPlugin): # New line ret.append(self.curse_new_line()) # 15min load - msg = '{0:8}'.format(_("15 min:")) + msg = '{0:8}'.format('15 min:') ret.append(self.curse_add_line(msg)) msg = '{0:>6.2f}'.format(self.stats['min15']) ret.append(self.curse_add_line( diff --git a/glances/plugins/glances_mem.py b/glances/plugins/glances_mem.py index cf6ce4c5..6b4ace8c 100644 --- a/glances/plugins/glances_mem.py +++ b/glances/plugins/glances_mem.py @@ -19,10 +19,10 @@ """Virtual memory plugin.""" -import psutil - from glances.plugins.glances_plugin import GlancesPlugin +import psutil + # SNMP OID # Total RAM in machine: .1.3.6.1.4.1.2021.4.5.0 # Total RAM used: .1.3.6.1.4.1.2021.4.6.0 @@ -78,7 +78,7 @@ class Plugin(GlancesPlugin): # Reset stats self.reset() - if self.get_input() == 'local': + if self.input_method == 'local': # Update stats using the standard system lib # Grab MEM using the PSUtil virtual_memory method vm_stats = psutil.virtual_memory() @@ -112,18 +112,18 @@ class Plugin(GlancesPlugin): self.stats['free'] += self.stats['cached'] # used=total-free self.stats['used'] = self.stats['total'] - self.stats['free'] - elif self.get_input() == 'snmp': + elif self.input_method == 'snmp': # Update stats using SNMP - if self.get_short_system_name() in ('windows', 'esxi'): + if self.short_system_name in ('windows', 'esxi'): # Mem stats for Windows|Vmware Esxi are stored in the FS table try: - fs_stat = self.set_stats_snmp(snmp_oid=snmp_oid[self.get_short_system_name()], + fs_stat = self.get_stats_snmp(snmp_oid=snmp_oid[self.short_system_name], bulk=True) except KeyError: self.reset() else: for fs in fs_stat: - # The Physical Memory (Windows) or Real Memory (VmWare) + # The Physical Memory (Windows) or Real Memory (VMware) # gives statistics on RAM usage and availability. if fs in ('Physical Memory', 'Real Memory'): self.stats['total'] = int(fs_stat[fs]['size']) * int(fs_stat[fs]['alloc_unit']) @@ -133,7 +133,7 @@ class Plugin(GlancesPlugin): break else: # Default behavor for others OS - self.stats = self.set_stats_snmp(snmp_oid=snmp_oid['default']) + self.stats = self.get_stats_snmp(snmp_oid=snmp_oid['default']) if self.stats['total'] == '': self.reset() @@ -161,13 +161,13 @@ class Plugin(GlancesPlugin): return self.stats def update_views(self): - """Update stats views""" + """Update stats views.""" # Call the father's method GlancesPlugin.update_views(self) # Add specifics informations # Alert and log - self.views['used']['decoration'] = self.get_alert_log(self.stats['used'], max=self.stats['total']) + self.views['used']['decoration'] = self.get_alert_log(self.stats['used'], maximum=self.stats['total']) # Optional for key in ['active', 'inactive', 'buffers', 'cached']: if key in self.stats: @@ -179,59 +179,59 @@ class Plugin(GlancesPlugin): ret = [] # Only process if stats exist... - if self.stats == {}: + if not self.stats: return ret # Build the string message # Header - msg = '{0:5} '.format(_("MEM")) + msg = '{0:5} '.format('MEM') ret.append(self.curse_add_line(msg, "TITLE")) # Percent memory usage msg = '{0:>7.1%}'.format(self.stats['percent'] / 100) ret.append(self.curse_add_line(msg)) # Active memory usage if 'active' in self.stats: - msg = ' {0:9}'.format(_("active:")) + msg = ' {0:9}'.format('active:') ret.append(self.curse_add_line(msg, optional=self.get_views(key='active', option='optional'))) msg = '{0:>7}'.format(self.auto_unit(self.stats['active'])) ret.append(self.curse_add_line(msg, optional=self.get_views(key='active', option='optional'))) # New line ret.append(self.curse_new_line()) # Total memory usage - msg = '{0:6}'.format(_("total:")) + msg = '{0:6}'.format('total:') ret.append(self.curse_add_line(msg)) msg = '{0:>7}'.format(self.auto_unit(self.stats['total'])) ret.append(self.curse_add_line(msg)) # Inactive memory usage if 'inactive' in self.stats: - msg = ' {0:9}'.format(_("inactive:")) + msg = ' {0:9}'.format('inactive:') ret.append(self.curse_add_line(msg, optional=self.get_views(key='inactive', option='optional'))) msg = '{0:>7}'.format(self.auto_unit(self.stats['inactive'])) ret.append(self.curse_add_line(msg, optional=self.get_views(key='inactive', option='optional'))) # New line ret.append(self.curse_new_line()) # Used memory usage - msg = '{0:6}'.format(_("used:")) + msg = '{0:6}'.format('used:') ret.append(self.curse_add_line(msg)) msg = '{0:>7}'.format(self.auto_unit(self.stats['used'])) ret.append(self.curse_add_line( msg, self.get_views(key='used', option='decoration'))) # Buffers memory usage if 'buffers' in self.stats: - msg = ' {0:9}'.format(_("buffers:")) + msg = ' {0:9}'.format('buffers:') ret.append(self.curse_add_line(msg, optional=self.get_views(key='buffers', option='optional'))) msg = '{0:>7}'.format(self.auto_unit(self.stats['buffers'])) ret.append(self.curse_add_line(msg, optional=self.get_views(key='buffers', option='optional'))) # New line ret.append(self.curse_new_line()) # Free memory usage - msg = '{0:6}'.format(_("free:")) + msg = '{0:6}'.format('free:') ret.append(self.curse_add_line(msg)) msg = '{0:>7}'.format(self.auto_unit(self.stats['free'])) ret.append(self.curse_add_line(msg)) # Cached memory usage if 'cached' in self.stats: - msg = ' {0:9}'.format(_("cached:")) + msg = ' {0:9}'.format('cached:') ret.append(self.curse_add_line(msg, optional=self.get_views(key='cached', option='optional'))) msg = '{0:>7}'.format(self.auto_unit(self.stats['cached'])) ret.append(self.curse_add_line(msg, optional=self.get_views(key='cached', option='optional'))) diff --git a/glances/plugins/glances_memswap.py b/glances/plugins/glances_memswap.py index 084f7596..5164e592 100644 --- a/glances/plugins/glances_memswap.py +++ b/glances/plugins/glances_memswap.py @@ -19,10 +19,10 @@ """Swap memory plugin.""" -import psutil - from glances.plugins.glances_plugin import GlancesPlugin +import psutil + # SNMP OID # Total Swap Size: .1.3.6.1.4.1.2021.4.3.0 # Available Swap Space: .1.3.6.1.4.1.2021.4.4.0 @@ -41,7 +41,7 @@ items_history_list = [{'name': 'percent', 'color': '#00FF00', 'y_unit': '%'}] class Plugin(GlancesPlugin): - """Glances' swap memory plugin. + """Glances swap memory plugin. stats is a dict """ @@ -67,7 +67,7 @@ class Plugin(GlancesPlugin): # Reset stats self.reset() - if self.get_input() == 'local': + if self.input_method == 'local': # Update stats using the standard system lib # Grab SWAP using the PSUtil swap_memory method sm_stats = psutil.swap_memory() @@ -84,20 +84,21 @@ class Plugin(GlancesPlugin): 'sin', 'sout']: if hasattr(sm_stats, swap): self.stats[swap] = getattr(sm_stats, swap) - elif self.get_input() == 'snmp': + elif self.input_method == 'snmp': # Update stats using SNMP - if self.get_short_system_name() == 'windows': + if self.short_system_name == 'windows': # Mem stats for Windows OS are stored in the FS table try: - fs_stat = self.set_stats_snmp(snmp_oid=snmp_oid[self.get_short_system_name()], + fs_stat = self.get_stats_snmp(snmp_oid=snmp_oid[self.short_system_name], bulk=True) except KeyError: self.reset() else: for fs in fs_stat: - # The virtual memory concept is used by the operating system to extend (virtually) the physical - # memory and thus to run more programs by swapping - # unused memory zone (page) to a disk file. + # The virtual memory concept is used by the operating + # system to extend (virtually) the physical memory and + # thus to run more programs by swapping unused memory + # zone (page) to a disk file. if fs == 'Virtual Memory': self.stats['total'] = int( fs_stat[fs]['size']) * int(fs_stat[fs]['alloc_unit']) @@ -109,7 +110,7 @@ class Plugin(GlancesPlugin): 'total'] - self.stats['used'] break else: - self.stats = self.set_stats_snmp(snmp_oid=snmp_oid['default']) + self.stats = self.get_stats_snmp(snmp_oid=snmp_oid['default']) if self.stats['total'] == '': self.reset() @@ -136,13 +137,13 @@ class Plugin(GlancesPlugin): return self.stats def update_views(self): - """Update stats views""" + """Update stats views.""" # Call the father's method GlancesPlugin.update_views(self) # Add specifics informations # Alert and log - self.views['used']['decoration'] = self.get_alert_log(self.stats['used'], max=self.stats['total']) + self.views['used']['decoration'] = self.get_alert_log(self.stats['used'], maximum=self.stats['total']) def msg_curse(self, args=None): """Return the dict to display in the curse interface.""" @@ -150,12 +151,12 @@ class Plugin(GlancesPlugin): ret = [] # Only process if stats exist... - if self.stats == {}: + if not self.stats: return ret # Build the string message # Header - msg = '{0:7} '.format(_("SWAP")) + msg = '{0:7} '.format('SWAP') ret.append(self.curse_add_line(msg, "TITLE")) # Percent memory usage msg = '{0:>6.1%}'.format(self.stats['percent'] / 100) @@ -163,14 +164,14 @@ class Plugin(GlancesPlugin): # New line ret.append(self.curse_new_line()) # Total memory usage - msg = '{0:8}'.format(_("total:")) + msg = '{0:8}'.format('total:') ret.append(self.curse_add_line(msg)) msg = '{0:>6}'.format(self.auto_unit(self.stats['total'])) ret.append(self.curse_add_line(msg)) # New line ret.append(self.curse_new_line()) # Used memory usage - msg = '{0:8}'.format(_("used:")) + msg = '{0:8}'.format('used:') ret.append(self.curse_add_line(msg)) msg = '{0:>6}'.format(self.auto_unit(self.stats['used'])) ret.append(self.curse_add_line( @@ -178,7 +179,7 @@ class Plugin(GlancesPlugin): # New line ret.append(self.curse_new_line()) # Free memory usage - msg = '{0:8}'.format(_("free:")) + msg = '{0:8}'.format('free:') ret.append(self.curse_add_line(msg)) msg = '{0:>6}'.format(self.auto_unit(self.stats['free'])) ret.append(self.curse_add_line(msg)) diff --git a/glances/plugins/glances_monitor.py b/glances/plugins/glances_monitor.py index 66765ea1..5c332787 100644 --- a/glances/plugins/glances_monitor.py +++ b/glances/plugins/glances_monitor.py @@ -20,14 +20,13 @@ """Monitor plugin.""" # Import Glances lib -from glances.core.glances_logging import logger from glances.core.glances_monitor_list import MonitorList as glancesMonitorList from glances.plugins.glances_plugin import GlancesPlugin class Plugin(GlancesPlugin): - """Glances' monitor plugin.""" + """Glances monitor plugin.""" def __init__(self, args=None): """Init the plugin.""" @@ -41,13 +40,12 @@ 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): """Update the monitored list.""" - if self.get_input() == 'local': + if self.input_method == 'local': # Monitor list only available in a full Glances environment # Check if the glances_monitor instance is init if self.glances_monitors is None: @@ -98,7 +96,7 @@ class Plugin(GlancesPlugin): msg, self.get_alert(m['count'], m['countmin'], m['countmax']))) msg = '{0:<3} '.format(m['count'] if m['count'] > 1 else '') ret.append(self.curse_add_line(msg)) - msg = '{0:13} '.format(_("RUNNING") if m['count'] >= 1 else _("NOT RUNNING")) + msg = '{0:13} '.format('RUNNING' if m['count'] >= 1 else 'NOT RUNNING') ret.append(self.curse_add_line(msg)) # Decode to UTF8 (only for Python 3) try: diff --git a/glances/plugins/glances_network.py b/glances/plugins/glances_network.py index 0f311015..c33f0022 100644 --- a/glances/plugins/glances_network.py +++ b/glances/plugins/glances_network.py @@ -22,11 +22,11 @@ import base64 import operator -import psutil - from glances.core.glances_timer import getTimeSinceLastUpdate from glances.plugins.glances_plugin import GlancesPlugin +import psutil + # SNMP OID # http://www.net-snmp.org/docs/mibs/interfaces.html # Dict key = interface_name @@ -43,7 +43,7 @@ items_history_list = [{'name': 'rx', 'color': '#00FF00', 'y_unit': 'bit/s'}, class Plugin(GlancesPlugin): - """Glances' network Plugin. + """Glances network plugin. stats is a list """ @@ -59,7 +59,7 @@ class Plugin(GlancesPlugin): self.reset() def get_key(self): - """Return the key of the list""" + """Return the key of the list.""" return 'interface_name' def reset(self): @@ -75,7 +75,7 @@ class Plugin(GlancesPlugin): # Reset stats self.reset() - if self.get_input() == 'local': + if self.input_method == 'local': # Update stats using the standard system lib # Grab network interface stat using the PsUtil net_io_counter method @@ -101,19 +101,21 @@ class Plugin(GlancesPlugin): network_new = netiocounters for net in network_new: try: - # Try necessary to manage dynamic network interface - netstat = {} - netstat['interface_name'] = net - netstat['time_since_update'] = time_since_update - netstat['cumulative_rx'] = network_new[net].bytes_recv - netstat['rx'] = (network_new[net].bytes_recv - - self.network_old[net].bytes_recv) - netstat['cumulative_tx'] = network_new[net].bytes_sent - netstat['tx'] = (network_new[net].bytes_sent - - self.network_old[net].bytes_sent) - netstat['cumulative_cx'] = (netstat['cumulative_rx'] + - netstat['cumulative_tx']) - netstat['cx'] = netstat['rx'] + netstat['tx'] + cumulative_rx = network_new[net].bytes_recv + cumulative_tx = network_new[net].bytes_sent + cumulative_cx = cumulative_rx + cumulative_tx + rx = cumulative_rx - self.network_old[net].bytes_recv + tx = cumulative_tx - self.network_old[net].bytes_sent + cx = rx + tx + netstat = { + 'interface_name': net, + 'time_since_update': time_since_update, + 'cumulative_rx': cumulative_rx, + 'rx': rx, + 'cumulative_tx': cumulative_tx, + 'tx': tx, + 'cumulative_cx': cumulative_cx, + 'cx': cx} except KeyError: continue else: @@ -123,15 +125,15 @@ class Plugin(GlancesPlugin): # Save stats to compute next bitrate self.network_old = network_new - elif self.get_input() == 'snmp': + elif self.input_method == 'snmp': # Update stats using SNMP # SNMP bulk command to get all network interface in one shot try: - netiocounters = self.set_stats_snmp(snmp_oid=snmp_oid[self.get_short_system_name()], + netiocounters = self.get_stats_snmp(snmp_oid=snmp_oid[self.short_system_name], bulk=True) except KeyError: - netiocounters = self.set_stats_snmp(snmp_oid=snmp_oid['default'], + netiocounters = self.get_stats_snmp(snmp_oid=snmp_oid['default'], bulk=True) # Previous network interface stats are stored in the network_old variable @@ -150,27 +152,30 @@ class Plugin(GlancesPlugin): for net in network_new: try: - # Try necessary to manage dynamic network interface - netstat = {} # Windows: a tips is needed to convert HEX to TXT # http://blogs.technet.com/b/networking/archive/2009/12/18/how-to-query-the-list-of-network-interfaces-using-snmp-via-the-ifdescr-counter.aspx - if self.get_short_system_name() == 'windows': + if self.short_system_name == 'windows': try: - netstat['interface_name'] = str(base64.b16decode(net[2:-2].upper())) + interface_name = str(base64.b16decode(net[2:-2].upper())) except TypeError: - netstat['interface_name'] = net + interface_name = net else: - netstat['interface_name'] = net - netstat['time_since_update'] = time_since_update - netstat['cumulative_rx'] = float(network_new[net]['cumulative_rx']) - netstat['rx'] = (float(network_new[net]['cumulative_rx']) - - float(self.network_old[net]['cumulative_rx'])) - netstat['cumulative_tx'] = float(network_new[net]['cumulative_tx']) - netstat['tx'] = (float(network_new[net]['cumulative_tx']) - - float(self.network_old[net]['cumulative_tx'])) - netstat['cumulative_cx'] = (netstat['cumulative_rx'] + - netstat['cumulative_tx']) - netstat['cx'] = netstat['rx'] + netstat['tx'] + interface_name = net + cumulative_rx = float(network_new[net]['cumulative_rx']) + cumulative_tx = float(network_new[net]['cumulative_tx']) + cumulative_cx = cumulative_rx + cumulative_tx + rx = cumulative_rx - float(self.network_old[net]['cumulative_rx']) + tx = cumulative_tx - float(self.network_old[net]['cumulative_tx']) + cx = rx + tx + netstat = { + 'interface_name': interface_name, + 'time_since_update': time_since_update, + 'cumulative_rx': cumulative_rx, + 'rx': rx, + 'cumulative_tx': cumulative_tx, + 'tx': tx, + 'cumulative_cx': cumulative_cx, + 'cx': cx} except KeyError: continue else: @@ -189,7 +194,7 @@ class Plugin(GlancesPlugin): return self.stats def update_views(self): - """Update stats views""" + """Update stats views.""" # Call the father's method GlancesPlugin.update_views(self) @@ -204,7 +209,6 @@ class Plugin(GlancesPlugin): def msg_curse(self, args=None, max_width=None): """Return the dict to display in the curse interface.""" - # Init the return message ret = [] @@ -221,30 +225,30 @@ class Plugin(GlancesPlugin): # Build the string message # Header - msg = '{0:{width}}'.format(_("NETWORK"), width=ifname_max_width) + msg = '{0:{width}}'.format('NETWORK', width=ifname_max_width) ret.append(self.curse_add_line(msg, "TITLE")) if args.network_cumul: # Cumulative stats if args.network_sum: # Sum stats - msg = '{0:>14}'.format(_("Rx+Tx")) + msg = '{0:>14}'.format('Rx+Tx') ret.append(self.curse_add_line(msg)) else: # Rx/Tx stats - msg = '{0:>7}'.format(_("Rx")) + msg = '{0:>7}'.format('Rx') ret.append(self.curse_add_line(msg)) - msg = '{0:>7}'.format(_("Tx")) + msg = '{0:>7}'.format('Tx') ret.append(self.curse_add_line(msg)) else: # Bitrate stats if args.network_sum: # Sum stats - msg = '{0:>14}'.format(_("Rx+Tx/s")) + msg = '{0:>14}'.format('Rx+Tx/s') ret.append(self.curse_add_line(msg)) else: - msg = '{0:>7}'.format(_("Rx/s")) + msg = '{0:>7}'.format('Rx/s') ret.append(self.curse_add_line(msg)) - msg = '{0:>7}'.format(_("Tx/s")) + msg = '{0:>7}'.format('Tx/s') ret.append(self.curse_add_line(msg)) # Interface list (sorted by name) for i in sorted(self.stats, key=operator.itemgetter(self.get_key())): @@ -265,20 +269,20 @@ class Plugin(GlancesPlugin): if args.network_cumul: rx = self.auto_unit(int(i['cumulative_rx'])) tx = self.auto_unit(int(i['cumulative_tx'])) - sx = self.auto_unit(int(i['cumulative_tx']) - + int(i['cumulative_tx'])) + sx = self.auto_unit(int(i['cumulative_tx']) + + int(i['cumulative_tx'])) else: rx = self.auto_unit(int(i['rx'] // i['time_since_update'])) tx = self.auto_unit(int(i['tx'] // i['time_since_update'])) - sx = self.auto_unit(int(i['rx'] // i['time_since_update']) - + int(i['tx'] // i['time_since_update'])) + sx = self.auto_unit(int(i['rx'] // i['time_since_update']) + + int(i['tx'] // i['time_since_update'])) else: # Bits per second (for real network administrator | Default) if args.network_cumul: rx = self.auto_unit(int(i['cumulative_rx'] * 8)) + "b" tx = self.auto_unit(int(i['cumulative_tx'] * 8)) + "b" - sx = self.auto_unit(int(i['cumulative_rx'] * 8) - + int(i['cumulative_tx'] * 8)) + "b" + sx = self.auto_unit(int(i['cumulative_rx'] * 8) + + int(i['cumulative_tx'] * 8)) + "b" else: rx = self.auto_unit(int(i['rx'] // i['time_since_update'] * 8)) + "b" tx = self.auto_unit(int(i['tx'] // i['time_since_update'] * 8)) + "b" diff --git a/glances/plugins/glances_now.py b/glances/plugins/glances_now.py index b40fa44f..b9e09528 100644 --- a/glances/plugins/glances_now.py +++ b/glances/plugins/glances_now.py @@ -39,12 +39,12 @@ class Plugin(GlancesPlugin): self.display_curse = True # Set the message position - self.set_align('bottom') + self.align = 'bottom' def update(self): """Update current date/time.""" # Had to convert it to string because datetime is not JSON serializable - self.stats = datetime.now().strftime(_("%Y-%m-%d %H:%M:%S")) + self.stats = datetime.now().strftime('%Y-%m-%d %H:%M:%S') return self.stats diff --git a/glances/plugins/glances_percpu.py b/glances/plugins/glances_percpu.py index 93abeab6..8ec38a2c 100644 --- a/glances/plugins/glances_percpu.py +++ b/glances/plugins/glances_percpu.py @@ -19,10 +19,10 @@ """Per-CPU plugin.""" -import psutil - from glances.plugins.glances_plugin import GlancesPlugin +import psutil + class Plugin(GlancesPlugin): @@ -42,6 +42,10 @@ class Plugin(GlancesPlugin): # Init stats self.reset() + def get_key(self): + """Return the key of the list.""" + return 'cpu_number' + def reset(self): """Reset/init the stats.""" self.stats = [] @@ -53,12 +57,15 @@ class Plugin(GlancesPlugin): # Grab per-CPU stats using psutil's cpu_percent(percpu=True) and # cpu_times_percent(percpu=True) methods - if self.get_input() == 'local': + if self.input_method == 'local': percpu_percent = psutil.cpu_percent(interval=0.0, percpu=True) percpu_times_percent = psutil.cpu_times_percent(interval=0.0, percpu=True) + cpu_number = 0 for cputimes in percpu_times_percent: for cpupercent in percpu_percent: - cpu = {'total': cpupercent, + cpu = {'key': self.get_key(), + 'cpu_number': str(cpu_number), + 'total': cpupercent, 'user': cputimes.user, 'system': cputimes.system, 'idle': cputimes.idle} @@ -78,6 +85,7 @@ class Plugin(GlancesPlugin): if hasattr(cputimes, 'guest_nice'): cpu['guest_nice'] = cputimes.guest_nice self.stats.append(cpu) + cpu_number += 1 else: # Update stats using SNMP pass @@ -91,13 +99,13 @@ class Plugin(GlancesPlugin): # No per CPU stat ? Exit... if not self.stats: - msg = _("PER CPU not available") + msg = 'PER CPU not available' ret.append(self.curse_add_line(msg, "TITLE")) return ret # Build the string message # Header - msg = '{0:8}'.format(_("PER CPU")) + msg = '{0:8}'.format('PER CPU') ret.append(self.curse_add_line(msg, "TITLE")) # Total per-CPU usage @@ -107,7 +115,7 @@ class Plugin(GlancesPlugin): # User per-CPU ret.append(self.curse_new_line()) - msg = '{0:8}'.format(_("user:")) + msg = '{0:8}'.format('user:') ret.append(self.curse_add_line(msg)) for cpu in self.stats: msg = '{0:>6}%'.format(cpu['user']) @@ -115,7 +123,7 @@ class Plugin(GlancesPlugin): # System per-CPU ret.append(self.curse_new_line()) - msg = '{0:8}'.format(_("system:")) + msg = '{0:8}'.format('system:') ret.append(self.curse_add_line(msg)) for cpu in self.stats: msg = '{0:>6}%'.format(cpu['system']) @@ -123,7 +131,7 @@ class Plugin(GlancesPlugin): # Idle per-CPU ret.append(self.curse_new_line()) - msg = '{0:8}'.format(_("idle:")) + msg = '{0:8}'.format('idle:') ret.append(self.curse_add_line(msg)) for cpu in self.stats: msg = '{0:>6}%'.format(cpu['idle']) diff --git a/glances/plugins/glances_plugin.py b/glances/plugins/glances_plugin.py index 7ff575f6..cb3e6be0 100644 --- a/glances/plugins/glances_plugin.py +++ b/glances/plugins/glances_plugin.py @@ -29,15 +29,15 @@ from datetime import datetime from operator import itemgetter # Import Glances lib +from glances.core.glances_actions import GlancesActions from glances.core.glances_globals import is_py3 from glances.core.glances_logging import logger from glances.core.glances_logs import glances_logs -from glances.core.glances_actions import GlancesActions class GlancesPlugin(object): - """Main class for Glances' plugin.""" + """Main class for Glances plugin.""" def __init__(self, args=None, items_history_list=None): """Init the plugin of plugins class.""" @@ -49,11 +49,11 @@ class GlancesPlugin(object): self.args = args # Init the default alignement (for curses) - self.set_align('left') + self._align = 'left' # Init the input method - self.input_method = 'local' - self.short_system_name = None + self._input_method = 'local' + self._short_system_name = None # Init the stats list self.stats = None @@ -63,7 +63,7 @@ class GlancesPlugin(object): self.stats_history = self.init_stats_history() # Init the limits dictionnary - self.limits = dict() + self._limits = dict() # Init the actions self.actions = GlancesActions() @@ -80,18 +80,18 @@ class GlancesPlugin(object): return str(self.stats) def get_key(self): - """Return the key of the list""" + """Return the key of the list.""" return None def add_item_history(self, key, value): - """Add an new item (key, value) to the current history""" + """Add an new item (key, value) to the current history.""" try: self.stats_history[key].append(value) except KeyError: self.stats_history[key] = [value] def init_stats_history(self): - """Init the stats history (dict of list)""" + """Init the stats history (dict of list).""" ret = None if self.args is not None and self.args.enable_history and self.get_items_history_list() is not None: init_list = [i['name'] for i in self.get_items_history_list()] @@ -101,20 +101,21 @@ class GlancesPlugin(object): return ret def reset_stats_history(self): - """Reset the stats history (dict of list)""" + """Reset the stats history (dict of list).""" if self.args is not None and self.args.enable_history and self.get_items_history_list() is not None: reset_list = [i['name'] for i in self.get_items_history_list()] logger.debug("Reset history for plugin {0} (items: {0})".format( self.plugin_name, reset_list)) self.stats_history = {} - return self.stats_history def update_stats_history(self, item_name=''): - """Update stats history""" - if self.stats != [] and self.args is not None and self.args.enable_history and self.get_items_history_list() is not None: + """Update stats history.""" + if (self.stats and self.args is not None and + self.args.enable_history and + self.get_items_history_list() is not None): self.add_item_history('date', datetime.now()) for i in self.get_items_history_list(): - if type(self.stats) is list: + if isinstance(self.stats, list): # Stats is a list of data # Iter throught it (for exemple, iter throught network # interface) @@ -125,47 +126,51 @@ class GlancesPlugin(object): # Stats is not a list # Add the item to the history directly self.add_item_history(i['name'], self.stats[i['name']]) - return self.stats_history def get_stats_history(self): - """Return the stats history""" + """Return the stats history.""" return self.stats_history def get_items_history_list(self): - """Return the items history list""" + """Return the items history list.""" return self.items_history_list - def set_input(self, input_method, short_system_name=None): + @property + def input_method(self): + """Get the input method.""" + return self._input_method + + @input_method.setter + def input_method(self, input_method): """Set the input method. * local: system local grab (psutil or direct access) * snmp: Client server mode via SNMP * glances: Client server mode via Glances API - - For SNMP, short_system_name is detected short OS name """ - self.input_method = input_method - self.short_system_name = short_system_name - return self.input_method + self._input_method = input_method - def get_input(self): - """Get the input method.""" - return self.input_method + @property + def short_system_name(self): + """Get the short detected OS name (SNMP).""" + return self._short_system_name - def get_short_system_name(self): - """Get the short detected OS name""" - return self.short_system_name + @short_system_name.setter + def short_system_name(self, short_name): + """Set the short detected OS name (SNMP).""" + self._short_system_name = short_name def set_stats(self, input_stats): """Set the stats to input_stats.""" self.stats = input_stats - return self.stats - def set_stats_snmp(self, bulk=False, snmp_oid={}): + def get_stats_snmp(self, bulk=False, snmp_oid=None): """Update stats using SNMP. If bulk=True, use a bulk request instead of a get request. """ + snmp_oid = snmp_oid or {} + from glances.core.glances_snmp import GlancesSNMPClient # Init the SNMP request @@ -201,7 +206,7 @@ class GlancesPlugin(object): item_key = item[oid] else: item_stats[key] = item[oid] - if item_stats != {}: + if item_stats: ret[item_key] = item_stats index += 1 else: @@ -219,23 +224,21 @@ class GlancesPlugin(object): return self.stats def get_stats(self): - """Return the stats object in JSON format""" + """Return the stats object in JSON format.""" return json.dumps(self.stats) def get_stats_item(self, item): - """ - Return the stats object for a specific item (in JSON format) + """Return the stats object for a specific item in JSON format. + Stats should be a list of dict (processlist, network...) """ - if type(self.stats) is not list: - if type(self.stats) is dict: - try: - return json.dumps({item: self.stats[item]}) - except KeyError as e: - logger.error("Cannot get item {0} ({1})".format(item, e)) - else: + if isinstance(self.stats, dict): + try: + return json.dumps({item: self.stats[item]}) + except KeyError as e: + logger.error("Cannot get item {0} ({1})".format(item, e)) return None - else: + elif isinstance(self.stats, list): try: # Source: # http://stackoverflow.com/questions/4573875/python-get-index-of-dictionary-item-in-list @@ -243,13 +246,15 @@ class GlancesPlugin(object): except (KeyError, ValueError) as e: logger.error("Cannot get item {0} ({1})".format(item, e)) return None + else: + return None def get_stats_value(self, item, value): - """ - Return the stats object for a specific item=value (in JSON format) + """Return the stats object for a specific item=value in JSON format. + Stats should be a list of dict (processlist, network...) """ - if type(self.stats) is not list: + if not isinstance(self.stats, list): return None else: if value.isdigit(): @@ -262,7 +267,8 @@ class GlancesPlugin(object): return None def update_views(self): - """Default builder fo the stats views + """Default builder fo the stats views. + The V of MVC A dict of dict with the needed information to display the stats. Example for the stat xxx: @@ -273,7 +279,9 @@ class GlancesPlugin(object): """ ret = {} - if type(self.get_raw()) is list and self.get_raw() is not None and self.get_key() is not None: + if (isinstance(self.get_raw(), list) and + self.get_raw() is not None and + self.get_key() is not None): # Stats are stored in a list of dict (ex: NETWORK, FS...) for i in self.get_raw(): ret[i[self.get_key()]] = {} @@ -283,7 +291,7 @@ class GlancesPlugin(object): 'additional': False, 'splittable': False} ret[i[self.get_key()]][key] = value - elif type(self.get_raw()) is dict and self.get_raw() is not None: + elif isinstance(self.get_raw(), dict) and self.get_raw() is not None: # Stats are stored in a dict (ex: CPU, LOAD...) for key in self.get_raw().keys(): value = {'decoration': 'DEFAULT', @@ -299,16 +307,16 @@ class GlancesPlugin(object): def set_views(self, input_views): """Set the views to input_views.""" self.views = input_views - return self.views def get_views(self, item=None, key=None, option=None): """Return the views object. + If key is None, return all the view for the current plugin else if option is None return the view for the specific key (all option) else return the view fo the specific key/option - Specify item if the stats are stored in a dict of dict (ex: NETWORK, FS...)""" - + Specify item if the stats are stored in a dict of dict (ex: NETWORK, FS...) + """ if item is None: item_views = self.views else: @@ -323,30 +331,29 @@ 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 s, v in config.items(self.plugin_name): + for level, _ in config.items(self.plugin_name): # Read limits + limit = '_'.join([self.plugin_name, level]) try: - self.limits[ - self.plugin_name + '_' + s] = config.get_option(self.plugin_name, s) + self._limits[limit] = config.get_float_value(self.plugin_name, level) except ValueError: - self.limits[ - self.plugin_name + '_' + s] = config.get_raw_option(self.plugin_name, s).split(",") - logger.debug("Load limit: {0} = {1}".format(self.plugin_name + '_' + s, - self.limits[self.plugin_name + '_' + s])) + self._limits[limit] = config.get_value(self.plugin_name, level).split(",") + logger.debug("Load limit: {0} = {1}".format(limit, self._limits[limit])) - def set_limits(self, input_limits): - """Set the limits to input_limits.""" - self.limits = input_limits - return self.limits - - def get_limits(self): + @property + def limits(self): """Return the limits object.""" - return self.limits + return self._limits - def get_alert(self, current=0, min=0, max=100, header="", log=False): + @limits.setter + def limits(self, input_limits): + """Set the limits to input_limits.""" + self._limits = input_limits + + def get_alert(self, current=0, minimum=0, maximum=100, header="", log=False): """Return the alert status relative to a current value. Use this function for minor stats. @@ -365,7 +372,7 @@ class GlancesPlugin(object): """ # Compute the % try: - value = (current * 100) / max + value = (current * 100) / maximum except ZeroDivisionError: return 'DEFAULT' except TypeError: @@ -386,7 +393,7 @@ class GlancesPlugin(object): ret = 'WARNING' elif value > self.__get_limit('careful', stat_name=stat_name): ret = 'CAREFUL' - elif current < min: + elif current < minimum: ret = 'CAREFUL' except KeyError: return 'DEFAULT' @@ -410,7 +417,7 @@ class GlancesPlugin(object): else: # A command line is available for the current alert, run it # Build the {{mustache}} dictionnary - if type(self.stats) is list: + if isinstance(self.stats, list): # If the stats are stored in a list of dict (fs plugin for exemple) # Return the dict for the current header mustache_dict = {} @@ -428,49 +435,49 @@ class GlancesPlugin(object): # Default is ok return ret + log_str - def get_alert_log(self, current=0, min=0, max=100, header=""): + def get_alert_log(self, current=0, minimum=0, maximum=100, header=""): """Get the alert log.""" - return self.get_alert(current, min, max, header, log=True) + return self.get_alert(current, minimum, maximum, header, log=True) def __get_limit(self, criticity, stat_name=""): - """Return the limit value for the alert""" + """Return the limit value for the alert.""" # Get the limit for stat + header # Exemple: network_wlan0_rx_careful try: - limit = self.limits[stat_name + '_' + criticity] + limit = self._limits[stat_name + '_' + criticity] except KeyError: # Try fallback to plugin default limit # Exemple: network_careful - limit = self.limits[self.plugin_name + '_' + criticity] + limit = self._limits[self.plugin_name + '_' + criticity] # Return the limit return limit def __get_limit_action(self, criticity, stat_name=""): - """Return the action for the alert""" + """Return the action for the alert.""" # Get the action for stat + header # Exemple: network_wlan0_rx_careful_action try: - ret = self.limits[stat_name + '_' + criticity + '_action'] + ret = self._limits[stat_name + '_' + criticity + '_action'] except KeyError: # Try fallback to plugin default limit # Exemple: network_careful_action - ret = self.limits[self.plugin_name + '_' + criticity + '_action'] + ret = self._limits[self.plugin_name + '_' + criticity + '_action'] # Return the action list return ret def __get_limit_log(self, stat_name, default_action=False): - """Return the log tag for the alert""" + """Return the log tag for the alert.""" # Get the log tag for stat + header # Exemple: network_wlan0_rx_log try: - log_tag = self.limits[stat_name + '_log'] + log_tag = self._limits[stat_name + '_log'] except KeyError: # Try fallback to plugin default log # Exemple: network_log try: - log_tag = self.limits[self.plugin_name + '_log'] + log_tag = self._limits[self.plugin_name + '_log'] except KeyError: # By defaukt, log are disabled return default_action @@ -479,28 +486,31 @@ class GlancesPlugin(object): return log_tag[0].lower() == 'true' def get_conf_value(self, value, header="", plugin_name=None): - """Return the configuration (header_) value for the current plugin (or the one given by the plugin_name var)""" + """Return the configuration (header_) value for the current plugin. + + ...or the one given by the plugin_name var. + """ if plugin_name is None: + # If not default use the current plugin name plugin_name = self.plugin_name - if header == "": - try: - return self.limits[plugin_name + '_' + value] - except KeyError: - return [] - else: - try: - return self.limits[plugin_name + '_' + header + '_' + value] - except KeyError: - return [] + + if header != "": + # Add the header + plugin_name = plugin_name + '_' + header + + try: + return self._limits[plugin_name + '_' + value] + except KeyError: + return [] def is_hide(self, value, header=""): """Return True if the value is in the hide configuration list.""" return value in self.get_conf_value('hide', header=header) def has_alias(self, header): - """Return the alias name for the relative header or None if nonexist""" + """Return the alias name for the relative header or None if nonexist.""" try: - return self.limits[self.plugin_name + '_' + header + '_' + 'alias'][0] + return self._limits[self.plugin_name + '_' + header + '_' + 'alias'][0] except (KeyError, IndexError): return None @@ -522,7 +532,7 @@ class GlancesPlugin(object): if hasattr(self, 'display_curse'): display_curse = self.display_curse if hasattr(self, 'align'): - align_curse = self.align + align_curse = self._align if max_width is not None: ret = {'display': display_curse, @@ -538,7 +548,7 @@ class GlancesPlugin(object): def curse_add_line(self, msg, decoration="DEFAULT", optional=False, additional=False, splittable=False): - """Return a dict with + """Return a dict with. Where: msg: string @@ -550,6 +560,7 @@ class GlancesPlugin(object): PROCESS: for process name STATUS: for process status NICE: for process niceness + CPU_TIME: for process cpu time OK: Value is OK and non logged OK_LOG: Value is OK and logged CAREFUL: Value is CAREFUL and non logged @@ -568,16 +579,18 @@ class GlancesPlugin(object): """Go to a new line.""" return self.curse_add_line('\n') - def set_align(self, align='left'): - """Set the Curse align""" - if align in ('left', 'right', 'bottom'): - self.align = align - else: - self.align = 'left' + @property + def align(self): + """Get the curse align.""" + return self._align - def get_align(self): - """Get the Curse align""" - return self.align + @align.setter + def align(self, value): + """Set the curse align. + + value: left, right, bottom. + """ + self._align = value def auto_unit(self, number, low_precision=False): """Make a nice human-readable string out of number. @@ -628,15 +641,19 @@ class GlancesPlugin(object): return '{0!s}'.format(number) def _log_result_decorator(fct): - """Log (DEBUG) the result of the function fct""" + """Log (DEBUG) the result of the function fct.""" def wrapper(*args, **kw): ret = fct(*args, **kw) if is_py3: - logger.debug("%s %s %s return %s" % (args[0].__class__.__name__, args[ - 0].__class__.__module__[len('glances_'):], fct.__name__, ret)) + logger.debug("%s %s %s return %s" % ( + args[0].__class__.__name__, + args[0].__class__.__module__[len('glances_'):], + fct.__name__, ret)) else: - logger.debug("%s %s %s return %s" % (args[0].__class__.__name__, args[ - 0].__class__.__module__[len('glances_'):], fct.func_name, ret)) + logger.debug("%s %s %s return %s" % ( + args[0].__class__.__name__, + args[0].__class__.__module__[len('glances_'):], + fct.func_name, ret)) return ret return wrapper diff --git a/glances/plugins/glances_processcount.py b/glances/plugins/glances_processcount.py index 3248ef1d..2841b791 100644 --- a/glances/plugins/glances_processcount.py +++ b/glances/plugins/glances_processcount.py @@ -29,7 +29,7 @@ from glances.plugins.glances_plugin import GlancesPlugin class Plugin(GlancesPlugin): - """Glances' processes plugin. + """Glances process count plugin. stats is a list """ @@ -52,14 +52,14 @@ class Plugin(GlancesPlugin): # Reset stats self.reset() - if self.get_input() == 'local': + if self.input_method == 'local': # Update stats using the standard system lib # Here, update is call for processcount AND processlist glances_processes.update() # Return the processes count self.stats = glances_processes.getcount() - elif self.get_input() == 'snmp': + elif self.input_method == 'snmp': # Update stats using SNMP # !!! TODO pass @@ -73,57 +73,57 @@ class Plugin(GlancesPlugin): # Only process if stats exist and display plugin enable... if args.disable_process: - msg = _("PROCESSES DISABLED (press 'z' to display)") + msg = "PROCESSES DISABLED (press 'z' to display)" ret.append(self.curse_add_line(msg)) return ret - if self.stats == {}: + if not self.stats: return ret # Display the filter (if it exists) - if glances_processes.get_process_filter() is not None: - msg = _("Processes filter:") + if glances_processes.process_filter is not None: + msg = 'Processes filter:' ret.append(self.curse_add_line(msg, "TITLE")) - msg = _(" {0} ").format(glances_processes.get_process_filter()) + msg = ' {0} '.format(glances_processes.process_filter) ret.append(self.curse_add_line(msg, "FILTER")) - msg = _("(press ENTER to edit)") + msg = '(press ENTER to edit)' ret.append(self.curse_add_line(msg)) ret.append(self.curse_new_line()) # Build the string message # Header - msg = _("TASKS ") + msg = 'TASKS' ret.append(self.curse_add_line(msg, "TITLE")) # Compute processes other = self.stats['total'] - msg = str(self.stats['total']) + msg = '{0:>4}'.format(self.stats['total']) ret.append(self.curse_add_line(msg)) if 'thread' in self.stats: - msg = _(" ({0} thr),").format(self.stats['thread']) + msg = ' ({0} thr),'.format(self.stats['thread']) ret.append(self.curse_add_line(msg)) if 'running' in self.stats: other -= self.stats['running'] - msg = _(" {0} run,").format(self.stats['running']) + msg = ' {0} run,'.format(self.stats['running']) ret.append(self.curse_add_line(msg)) if 'sleeping' in self.stats: other -= self.stats['sleeping'] - msg = _(" {0} slp,").format(self.stats['sleeping']) + msg = ' {0} slp,'.format(self.stats['sleeping']) ret.append(self.curse_add_line(msg)) - msg = _(" {0} oth ").format(other) + msg = ' {0} oth '.format(other) ret.append(self.curse_add_line(msg)) # Display sort information - if glances_processes.getmanualsortkey() is None: - msg = _("sorted automatically") + if glances_processes.auto_sort: + msg = 'sorted automatically' ret.append(self.curse_add_line(msg)) - msg = _(" by {0}").format(glances_processes.getautosortkey()) + msg = ' by {0}'.format(glances_processes.sort_key) ret.append(self.curse_add_line(msg)) else: - msg = _("sorted by {0}").format(glances_processes.getmanualsortkey()) + msg = 'sorted by {0}'.format(glances_processes.sort_key) ret.append(self.curse_add_line(msg)) ret[-1]["msg"] += ", %s view" % ("tree" if glances_processes.is_tree_enabled() else "flat") diff --git a/glances/plugins/glances_processlist.py b/glances/plugins/glances_processlist.py index 50aec76b..4e3198db 100644 --- a/glances/plugins/glances_processlist.py +++ b/glances/plugins/glances_processlist.py @@ -30,6 +30,20 @@ from glances.core.glances_processes import glances_processes from glances.plugins.glances_plugin import GlancesPlugin +def convert_timedelta(delta): + """Convert timedelta to human-readable time.""" + # Python 2.7+: + # total_seconds = delta.total_seconds() + # hours = total_seconds // 3600 + days, total_seconds = delta.days, delta.seconds + hours = days * 24 + total_seconds // 3600 + minutes = (total_seconds % 3600) // 60 + seconds = str(total_seconds % 60).zfill(2) + microseconds = str(delta.microseconds)[:2].zfill(2) + + return hours, minutes, seconds, microseconds + + class Plugin(GlancesPlugin): """Glances' processes plugin. @@ -44,10 +58,13 @@ class Plugin(GlancesPlugin): # We want to display the stat in the curse interface self.display_curse = True + # Trying to display proc time + self.tag_proc_time = True + # Note: 'glances_processes' is already init in the glances_processes.py script def get_key(self): - """Return the key of the list""" + """Return the key of the list.""" return 'pid' def reset(self): @@ -59,7 +76,7 @@ class Plugin(GlancesPlugin): # Reset stats self.reset() - if self.get_input() == 'local': + if self.input_method == 'local': # Update stats using the standard system lib # Note: Update is done in the processcount plugin # Just return the processes list @@ -67,23 +84,23 @@ class Plugin(GlancesPlugin): self.stats = glances_processes.gettree() else: self.stats = glances_processes.getlist() - elif self.get_input() == 'snmp': + elif self.input_method == 'snmp': # No SNMP grab for processes pass return self.stats def get_process_tree_curses_data(self, node, args, first_level=True, max_node_count=None): - """ Get curses data to display for a process tree. """ + """Get curses data to display for a process tree.""" ret = [] node_count = 0 - if (not node.is_root) and ((max_node_count is None) or (max_node_count > 0)): + if not node.is_root and ((max_node_count is None) or (max_node_count > 0)): node_data = self.get_process_curses_data(node.stats, False, args) node_count += 1 ret.extend(node_data) for child in node.iter_children(): # stop if we have enough nodes to display - if (max_node_count is not None) and (node_count >= max_node_count): + if max_node_count is not None and node_count >= max_node_count: break if max_node_count is None: @@ -105,11 +122,11 @@ class Plugin(GlancesPlugin): return ret def add_tree_decoration(self, child_data, is_last_child, first_level): - """ Add tree curses decoration and indentation to a subtree. """ + """Add tree curses decoration and indentation to a subtree.""" # find process command indices in messages pos = [] for i, m in enumerate(child_data): - if (m["msg"] == "\n") and (m is not child_data[-1]): + if m["msg"] == "\n" and m is not child_data[-1]: # new line pos + 12 # TODO find a way to get rid of hardcoded 12 value pos.append(i + 12) @@ -153,9 +170,8 @@ class Plugin(GlancesPlugin): return child_data def get_process_curses_data(self, p, first, args): - """ Get curses data to display for a process. """ - ret = [] - ret.append(self.curse_new_line()) + """Get curses data to display for a process.""" + ret = [self.curse_new_line()] # CPU if 'cpu_percent' in p and p['cpu_percent'] is not None and p['cpu_percent'] != '': msg = '{0:>6.1f}'.format(p['cpu_percent']) @@ -223,18 +239,21 @@ class Plugin(GlancesPlugin): # TIME+ if self.tag_proc_time: try: - dtime = timedelta(seconds=sum(p['cpu_times'])) - except Exception: + delta = timedelta(seconds=sum(p['cpu_times'])) + except OverflowError: # Catched on some Amazon EC2 server # See https://github.com/nicolargo/glances/issues/87 self.tag_proc_time = False else: - msg = '{0}:{1}.{2}'.format(str(dtime.seconds // 60 % 60), - str(dtime.seconds % 60).zfill(2), - str(dtime.microseconds)[:2].zfill(2)) + hours, minutes, seconds, microseconds = convert_timedelta(delta) + if hours: + msg = '{0:>4}h'.format(hours) + ret.append(self.curse_add_line(msg, decoration='CPU_TIME', optional=True)) + msg = '{0}:{1}'.format(str(minutes).zfill(2), seconds) + else: + msg = '{0:>4}:{1}.{2}'.format(minutes, seconds, microseconds) else: - msg = ' ' - msg = '{0:>9}'.format(msg) + msg = '{0:>10}'.format('?') ret.append(self.curse_add_line(msg, optional=True)) # IO read/write if 'io_counters' in p: @@ -290,40 +309,40 @@ class Plugin(GlancesPlugin): # First line is CPU affinity if 'cpu_affinity' in p and p['cpu_affinity'] is not None: ret.append(self.curse_new_line()) - msg = xpad + _('CPU affinity: ') + str(len(p['cpu_affinity'])) + _(' cores') + msg = xpad + 'CPU affinity: ' + str(len(p['cpu_affinity'])) + ' cores' ret.append(self.curse_add_line(msg, splittable=True)) # Second line is memory info if 'memory_info_ex' in p and p['memory_info_ex'] is not None: ret.append(self.curse_new_line()) - msg = xpad + _('Memory info: ') + msg = xpad + 'Memory info: ' for k, v in p['memory_info_ex']._asdict().items(): # Ignore rss and vms (already displayed) if k not in ['rss', 'vms'] and v is not None: msg += k + ' ' + self.auto_unit(v, low_precision=False) + ' ' if 'memory_swap' in p and p['memory_swap'] is not None: - msg += _('swap ') + self.auto_unit(p['memory_swap'], low_precision=False) + msg += 'swap ' + self.auto_unit(p['memory_swap'], low_precision=False) ret.append(self.curse_add_line(msg, splittable=True)) # Third line is for open files/network sessions msg = '' if 'num_threads' in p and p['num_threads'] is not None: - msg += _('threads ') + str(p['num_threads']) + ' ' + msg += 'threads ' + str(p['num_threads']) + ' ' if 'num_fds' in p and p['num_fds'] is not None: - msg += _('files ') + str(p['num_fds']) + ' ' + msg += 'files ' + str(p['num_fds']) + ' ' if 'num_handles' in p and p['num_handles'] is not None: - msg += _('handles ') + str(p['num_handles']) + ' ' + msg += 'handles ' + str(p['num_handles']) + ' ' if 'tcp' in p and p['tcp'] is not None: - msg += _('TCP ') + str(p['tcp']) + ' ' + msg += 'TCP ' + str(p['tcp']) + ' ' if 'udp' in p and p['udp'] is not None: - msg += _('UDP ') + str(p['udp']) + ' ' + msg += 'UDP ' + str(p['udp']) + ' ' if msg != '': ret.append(self.curse_new_line()) - msg = xpad + _('Open: ') + msg + msg = xpad + 'Open: ' + msg ret.append(self.curse_add_line(msg, splittable=True)) # Fouth line is IO nice level (only Linux and Windows OS) if 'ionice' in p and p['ionice'] is not None: ret.append(self.curse_new_line()) - msg = xpad + _('IO nice: ') - k = _('Class is ') + msg = xpad + 'IO nice: ' + k = 'Class is ' v = p['ionice'].ioclass # Linux: The scheduling class. 0 for none, 1 for real time, 2 for best-effort, 3 for idle. # Windows: On Windows only ioclass is used and it can be set to 2 (normal), 1 (low) or 0 (very low). @@ -333,12 +352,12 @@ class Plugin(GlancesPlugin): elif v == 1: msg += k + 'Low' elif v == 2: - msg += _('No specific I/O priority') + msg += 'No specific I/O priority' else: msg += k + str(v) else: if v == 0: - msg += _('No specific I/O priority') + msg += 'No specific I/O priority' elif v == 1: msg += k + 'Real Time' elif v == 2: @@ -350,7 +369,7 @@ class Plugin(GlancesPlugin): # value is a number which goes from 0 to 7. # The higher the value, the lower the I/O priority of the process. if hasattr(p['ionice'], 'value') and p['ionice'].value != 0: - msg += _(' (value %s/7)') % str(p['ionice'].value) + msg += ' (value %s/7)' % str(p['ionice'].value) ret.append(self.curse_add_line(msg, splittable=True)) return ret @@ -365,47 +384,43 @@ class Plugin(GlancesPlugin): return ret # Compute the sort key - process_sort_key = glances_processes.getsortkey() + process_sort_key = glances_processes.sort_key sort_style = 'SORT' # Header - msg = '{0:>6}'.format(_("CPU%")) + msg = '{0:>6}'.format('CPU%') ret.append(self.curse_add_line(msg, sort_style if process_sort_key == 'cpu_percent' else 'DEFAULT')) - msg = '{0:>6}'.format(_("MEM%")) + msg = '{0:>6}'.format('MEM%') ret.append(self.curse_add_line(msg, sort_style if process_sort_key == 'memory_percent' else 'DEFAULT')) - msg = '{0:>6}'.format(_("VIRT")) + msg = '{0:>6}'.format('VIRT') ret.append(self.curse_add_line(msg, optional=True)) - msg = '{0:>6}'.format(_("RES")) + msg = '{0:>6}'.format('RES') ret.append(self.curse_add_line(msg, optional=True)) - msg = '{0:>6}'.format(_("PID")) + msg = '{0:>6}'.format('PID') ret.append(self.curse_add_line(msg)) - msg = ' {0:10}'.format(_("USER")) + msg = ' {0:10}'.format('USER') + 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:>4}'.format(_("NI")) + msg = '{0:>2}'.format('S') ret.append(self.curse_add_line(msg)) - msg = '{0:>2}'.format(_("S")) - ret.append(self.curse_add_line(msg)) - msg = '{0:>9}'.format(_("TIME+")) + msg = '{0:>10}'.format('TIME+') ret.append(self.curse_add_line(msg, sort_style if process_sort_key == 'cpu_times' else 'DEFAULT', optional=True)) - msg = '{0:>6}'.format(_("IOR/s")) + msg = '{0:>6}'.format('IOR/s') ret.append(self.curse_add_line(msg, sort_style if process_sort_key == 'io_counters' else 'DEFAULT', optional=True, additional=True)) - msg = '{0:>6}'.format(_("IOW/s")) + msg = '{0:>6}'.format('IOW/s') ret.append(self.curse_add_line(msg, sort_style if process_sort_key == 'io_counters' else 'DEFAULT', optional=True, additional=True)) - msg = ' {0:8}'.format(_("Command")) - ret.append(self.curse_add_line(msg)) - - # Trying to display proc time - self.tag_proc_time = True + msg = ' {0:8}'.format('Command') + ret.append(self.curse_add_line(msg, sort_style if process_sort_key == 'name' else 'DEFAULT')) 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.get_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 @@ -413,16 +428,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: @@ -433,18 +444,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) diff --git a/glances/plugins/glances_psutilversion.py b/glances/plugins/glances_psutilversion.py index 0c2ffa14..021a0bc5 100644 --- a/glances/plugins/glances_psutilversion.py +++ b/glances/plugins/glances_psutilversion.py @@ -17,10 +17,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -from psutil import __version__ as __psutil_version - from glances.plugins.glances_plugin import GlancesPlugin +from psutil import __version__ as __psutil_version + class Plugin(GlancesPlugin): @@ -45,7 +45,7 @@ class Plugin(GlancesPlugin): self.reset() # Return PsUtil version as a tuple - if self.get_input() == 'local': + if self.input_method == 'local': # PsUtil version only available in local try: self.stats = tuple([int(num) for num in __psutil_version.split('.')]) diff --git a/glances/plugins/glances_quicklook.py b/glances/plugins/glances_quicklook.py new file mode 100644 index 00000000..b6711376 --- /dev/null +++ b/glances/plugins/glances_quicklook.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +# +# This file is part of Glances. +# +# Copyright (C) 2015 Nicolargo +# +# 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 . + +"""Quicklook plugin.""" + +from glances.core.glances_cpu_percent import cpu_percent +from glances.outputs.glances_bars import Bar +from glances.plugins.glances_plugin import GlancesPlugin + +import psutil + + +class Plugin(GlancesPlugin): + + """Glances quicklook plugin. + + 'stats' is a dictionary. + """ + + def __init__(self, args=None): + """Init the quicklook plugin.""" + GlancesPlugin.__init__(self, args=args) + + # We want to display the stat in the curse interface + self.display_curse = True + + # Init stats + self.reset() + + def reset(self): + """Reset/init the stats.""" + self.stats = {} + + @GlancesPlugin._log_result_decorator + def update(self): + """Update quicklook stats using the input method.""" + # Reset stats + self.reset() + + # Grab quicklook stats: CPU, MEM and SWAP + if self.input_method == 'local': + # Get the latest CPU percent value + self.stats['cpu'] = cpu_percent.get() + # Use the PsUtil lib for the memory (virtual and swap) + self.stats['mem'] = psutil.virtual_memory().percent + self.stats['swap'] = psutil.swap_memory().percent + elif self.input_method == 'snmp': + # Not available + pass + + # Update the view + self.update_views() + + return self.stats + + def update_views(self): + """Update stats views.""" + # Call the father's method + GlancesPlugin.update_views(self) + + # Add specifics informations + # Alert only + for key in ['cpu', 'mem', 'swap']: + if key in self.stats: + self.views[key]['decoration'] = self.get_alert(self.stats[key], header=key) + + def msg_curse(self, args=None, max_width=10): + """Return the list to display in the UI.""" + # Init the return message + ret = [] + + # Only process if stats exist... + if not self.stats or args.disable_quicklook: + return ret + + # Define the bar + bar = Bar(max_width, pre_char='|', post_char='|', empty_char=' ') + + # Build the string message + for key in ['cpu', 'mem', 'swap']: + bar.percent = self.stats[key] + msg = '{0:>4} '.format(key.upper()) + ret.append(self.curse_add_line(msg)) + msg = '{0}'.format(bar) + ret.append(self.curse_add_line(msg, + self.get_views(key=key, + option='decoration'))) + ret.append(self.curse_new_line()) + + # Return the message with decoration + return ret diff --git a/glances/plugins/glances_raid.py b/glances/plugins/glances_raid.py index a31baccf..d0482c8d 100644 --- a/glances/plugins/glances_raid.py +++ b/glances/plugins/glances_raid.py @@ -28,12 +28,11 @@ try: from pymdstat import MdStat except ImportError: logger.debug("pymdstat library not found. Glances cannot grab RAID info.") - pass class Plugin(GlancesPlugin): - """Glances' RAID plugin. + """Glances RAID plugin. stats is a dict (see pymdstat documentation) """ @@ -58,7 +57,7 @@ class Plugin(GlancesPlugin): # Reset stats self.reset() - if self.get_input() == 'local': + if self.input_method == 'local': # Update stats using the PyMDstat lib (https://github.com/nicolargo/pymdstat) try: mds = MdStat() @@ -67,7 +66,7 @@ class Plugin(GlancesPlugin): logger.debug("Can not grab RAID stats (%s)" % e) return self.stats - elif self.get_input() == 'snmp': + elif self.input_method == 'snmp': # Update stats using SNMP # No standard way for the moment... pass @@ -88,11 +87,11 @@ class Plugin(GlancesPlugin): # Build the string message # Header - msg = '{0:11}'.format(_('RAID disks')) + msg = '{0:11}'.format('RAID disks') ret.append(self.curse_add_line(msg, "TITLE")) - msg = '{0:>6}'.format(_("Used")) + msg = '{0:>6}'.format('Used') ret.append(self.curse_add_line(msg)) - msg = '{0:>6}'.format(_("Avail")) + msg = '{0:>6}'.format('Avail') ret.append(self.curse_add_line(msg)) # Data arrays = self.stats.keys() @@ -103,7 +102,7 @@ class Plugin(GlancesPlugin): # Display the current status status = self.raid_alert(self.stats[array]['status'], self.stats[array]['used'], self.stats[array]['available']) # Data: RAID type name | disk used | disk available - array_type = self.stats[array]['type'].upper() if self.stats[array]['type'] is not None else _('UNKNOWN') + array_type = self.stats[array]['type'].upper() if self.stats[array]['type'] is not None else 'UNKNOWN' msg = '{0:<5}{1:>6}'.format(array_type, array) ret.append(self.curse_add_line(msg)) if self.stats[array]['status'] == 'active': @@ -140,8 +139,10 @@ class Plugin(GlancesPlugin): return ret def raid_alert(self, status, used, available): - """ - [available/used] means that ideally the array would have _available_ devices however, _used_ devices are in use. + """RAID alert messages. + + [available/used] means that ideally the array may have _available_ + devices however, _used_ devices are in use. Obviously when used >= available then things are good. """ if status == 'inactive': diff --git a/glances/plugins/glances_sensors.py b/glances/plugins/glances_sensors.py index a821880f..45464b74 100644 --- a/glances/plugins/glances_sensors.py +++ b/glances/plugins/glances_sensors.py @@ -33,10 +33,16 @@ from glances.plugins.glances_batpercent import Plugin as BatPercentPlugin from glances.plugins.glances_hddtemp import Plugin as HddTempPlugin from glances.plugins.glances_plugin import GlancesPlugin +if is_py3: + SENSOR_TEMP_UNIT = '°C' +else: + SENSOR_TEMP_UNIT = '°C ' +SENSOR_FAN_UNIT = 'RPM' + class Plugin(GlancesPlugin): - """Glances' sensors plugin. + """Glances sensors plugin. The stats list includes both sensors and hard disks stats, if any. The sensors are already grouped by chip type and then sorted by name. @@ -65,7 +71,7 @@ class Plugin(GlancesPlugin): self.reset() def get_key(self): - """Return the key of the list""" + """Return the key of the list.""" return 'label' def reset(self): @@ -78,13 +84,27 @@ class Plugin(GlancesPlugin): # Reset the stats self.reset() - if self.get_input() == 'local': + if self.input_method == 'local': # Update stats using the dedicated lib + self.stats = [] + # Get the temperature try: - self.stats = self.__set_type(self.glancesgrabsensors.get(), - 'temperature_core') + temperature = self.__set_type(self.glancesgrabsensors.get('temperature_core'), + 'temperature_core') except Exception as e: logger.error("Cannot grab sensors temperatures (%s)" % e) + else: + # Append temperature + self.stats.extend(temperature) + # Get the FAN speed + try: + fan_speed = self.__set_type(self.glancesgrabsensors.get('fan_speed'), + 'fan_speed') + except Exception as e: + logger.error("Cannot grab FAN speed (%s)" % e) + else: + # Append FAN speed + self.stats.extend(fan_speed) # Update HDDtemp stats try: hddtemp = self.__set_type(self.hddtemp_plugin.update(), @@ -104,7 +124,7 @@ class Plugin(GlancesPlugin): # Append Batteries % self.stats.extend(batpercent) - elif self.get_input() == 'snmp': + elif self.input_method == 'snmp': # Update stats using SNMP # No standard: # http://www.net-snmp.org/wiki/index.php/Net-SNMP_and_lm-sensors_on_Ubuntu_10.04 @@ -119,24 +139,25 @@ class Plugin(GlancesPlugin): def __set_type(self, stats, sensor_type): """Set the plugin type. - 3 types of stats is possible in the sensors plugin: - - Core temperature - - HDD temperature - - Battery capacity + 4 types of stats is possible in the sensors plugin: + - Core temperature: 'temperature_core' + - Fan speed: 'fan_speed' + - HDD temperature: 'temperature_hdd' + - Battery capacity: 'battery' """ for i in stats: i.update({'type': sensor_type}) return stats def update_views(self): - """Update stats views""" + """Update stats views.""" # Call the father's method GlancesPlugin.update_views(self) # Add specifics informations # Alert for i in self.stats: - if i['value'] == []: + if not i['value']: continue if i['type'] == 'battery': self.views[i[self.get_key()]]['value']['decoration'] = self.get_alert(100 - i['value'], header=i['type']) @@ -154,26 +175,23 @@ class Plugin(GlancesPlugin): # Build the string message # Header - msg = '{0:18}'.format(_("SENSORS")) + msg = '{0:18}'.format('SENSORS') ret.append(self.curse_add_line(msg, "TITLE")) - if is_py3: - msg = '{0:>5}'.format(_("°C")) - else: - msg = '{0:>6}'.format(_("°C")) - ret.append(self.curse_add_line(msg)) for i in self.stats: - if i['value'] is not None and i['value'] != []: + if i['value']: # New line ret.append(self.curse_new_line()) # Alias for the lable name ? label = self.has_alias(i['label'].lower()) if label is None: label = i['label'] - label = label[:18] - msg = '{0:18}'.format(label) + try: + msg = "{0:12} {1:3}".format(label[:11], i['unit']) + except (KeyError, UnicodeEncodeError): + msg = "{0:16}".format(label[:15]) ret.append(self.curse_add_line(msg)) - msg = '{0:>5}'.format(i['value']) + msg = '{0:>7}'.format(i['value']) ret.append(self.curse_add_line( msg, self.get_views(item=i[self.get_key()], key='value', @@ -207,22 +225,35 @@ class GlancesGrabSensors(object): # Reset the list self.reset() - # grab only temperature stats if self.initok: for chip in sensors.iter_detected_chips(): for feature in chip: sensors_current = {} if feature.name.startswith(b'temp'): + # Temperature sensor + sensors_current['unit'] = SENSOR_TEMP_UNIT + elif feature.name.startswith(b'fan'): + # Fan speed sensor + sensors_current['unit'] = SENSOR_FAN_UNIT + if sensors_current: sensors_current['label'] = feature.label sensors_current['value'] = int(feature.get_value()) self.sensors_list.append(sensors_current) return self.sensors_list - def get(self): + def get(self, sensor_type='temperature_core'): """Get sensors list.""" self.__update__() - return self.sensors_list + if sensor_type == 'temperature_core': + ret = [s for s in self.sensors_list if s['unit'] == SENSOR_TEMP_UNIT] + elif sensor_type == 'fan_speed': + ret = [s for s in self.sensors_list if s['unit'] == SENSOR_FAN_UNIT] + else: + # Unknown type + logger.debug("Unknown sensor type %s" % sensor_type) + ret = [] + return ret def quit(self): """End of connection.""" diff --git a/glances/plugins/glances_system.py b/glances/plugins/glances_system.py index 217a1d0e..11a8209c 100644 --- a/glances/plugins/glances_system.py +++ b/glances/plugins/glances_system.py @@ -47,6 +47,34 @@ snmp_to_human = {'windows': {'Windows Version 6.3': 'Windows 8.1 or Server 2012R 'Windows Version 5.0': 'Windows 2000'}} +def _linux_os_release(): + """Try to determine the name of a Linux distribution. + + This function checks for the /etc/os-release file. + It takes the name from the 'NAME' field and the version from 'VERSION_ID'. + An empty string is returned if the above values cannot be determined. + """ + pretty_name = '' + ashtray = {} + keys = ['NAME', 'VERSION_ID'] + try: + with open(os.path.join('/etc', 'os-release')) as f: + for line in f: + for key in keys: + if line.startswith(key): + ashtray[key] = line.strip().split('=')[1][1:-1] + except (OSError, IOError): + return pretty_name + + if ashtray: + if 'NAME' in ashtray: + pretty_name = ashtray['NAME'] + if 'VERSION_ID' in ashtray: + pretty_name += ' {0}'.format(ashtray['VERSION_ID']) + + return pretty_name + + class Plugin(GlancesPlugin): """Glances' host/system plugin. @@ -68,33 +96,6 @@ class Plugin(GlancesPlugin): """Reset/init the stats.""" self.stats = {} - def _linux_os_release(self): - """This function tries to determine the name of a Linux distribution. - - It checks for the /etc/os-release file. It takes the name from the - 'NAME' field and the version from 'VERSION_ID'. - An empty string is returned if the above values cannot be determined. - """ - pretty_name = '' - ashtray = {} - keys = ['NAME', 'VERSION_ID'] - try: - with open(os.path.join('/etc', 'os-release')) as f: - for line in f: - for key in keys: - if line.startswith(key): - ashtray[key] = line.strip().split('=')[1][1:-1] - except (OSError, IOError): - return pretty_name - - if ashtray: - if 'NAME' in ashtray: - pretty_name = ashtray['NAME'] - if 'VERSION_ID' in ashtray: - pretty_name += ' {0}'.format(ashtray['VERSION_ID']) - - return pretty_name - def update(self): """Update the host/system info using the input method. @@ -103,7 +104,7 @@ class Plugin(GlancesPlugin): # Reset stats self.reset() - if self.get_input() == 'local': + if self.input_method == 'local': # Update stats using the standard system lib self.stats['os_name'] = platform.system() self.stats['hostname'] = platform.node() @@ -111,7 +112,7 @@ class Plugin(GlancesPlugin): if self.stats['os_name'] == "Linux": linux_distro = platform.linux_distribution() if linux_distro[0] == '': - self.stats['linux_distro'] = self._linux_os_release() + self.stats['linux_distro'] = _linux_os_release() else: self.stats['linux_distro'] = ' '.join(linux_distro[:2]) self.stats['os_version'] = platform.release() @@ -124,9 +125,8 @@ class Plugin(GlancesPlugin): self.stats['os_version'] = ' '.join(os_version[::2]) # if the python version is 32 bit perhaps the windows operating # system is 64bit - if self.stats['platform'] == '32bit': - if 'PROCESSOR_ARCHITEW6432' in os.environ: - self.stats['platform'] = '64bit' + if self.stats['platform'] == '32bit' and 'PROCESSOR_ARCHITEW6432' in os.environ: + self.stats['platform'] = '64bit' else: self.stats['os_version'] = "" # Add human readable name @@ -135,19 +135,19 @@ class Plugin(GlancesPlugin): else: self.stats['hr_name'] = '{0} {1}'.format( self.stats['os_name'], self.stats['os_version']) - self.stats['hr_name'] += ' ({0})'.format(self.stats['platform']) + self.stats['hr_name'] += ' {0}'.format(self.stats['platform']) - elif self.get_input() == 'snmp': + elif self.input_method == 'snmp': # Update stats using SNMP try: - self.stats = self.set_stats_snmp( - snmp_oid=snmp_oid[self.get_short_system_name()]) + self.stats = self.get_stats_snmp( + snmp_oid=snmp_oid[self.short_system_name]) except KeyError: - self.stats = self.set_stats_snmp(snmp_oid=snmp_oid['default']) + self.stats = self.get_stats_snmp(snmp_oid=snmp_oid['default']) # Default behavor: display all the information self.stats['os_name'] = self.stats['system_name'] # Windows OS tips - if self.get_short_system_name() == 'windows': + if self.short_system_name == 'windows': try: iteritems = snmp_to_human['windows'].iteritems() except AttributeError: @@ -170,13 +170,13 @@ class Plugin(GlancesPlugin): if args.client: # Client mode if args.cs_status.lower() == "connected": - msg = _("Connected to ") + msg = 'Connected to ' ret.append(self.curse_add_line(msg, 'OK')) elif args.cs_status.lower() == "snmp": - msg = _("SNMP from ") + msg = 'SNMP from ' ret.append(self.curse_add_line(msg, 'OK')) elif args.cs_status.lower() == "disconnected": - msg = _("Disconnected from ") + msg = 'Disconnected from ' ret.append(self.curse_add_line(msg, 'CRITICAL')) # Hostname is mandatory diff --git a/glances/plugins/glances_uptime.py b/glances/plugins/glances_uptime.py index 12e1c22b..17d7871c 100644 --- a/glances/plugins/glances_uptime.py +++ b/glances/plugins/glances_uptime.py @@ -22,19 +22,19 @@ # Import system libs from datetime import datetime, timedelta -# Import psutil -import psutil - # Import Glances libs from glances.plugins.glances_plugin import GlancesPlugin +# Import psutil +import psutil + # SNMP OID snmp_oid = {'_uptime': '1.3.6.1.2.1.1.3.0'} class Plugin(GlancesPlugin): - """Glances' uptime plugin. + """Glances uptime plugin. stats is date (string) """ @@ -47,7 +47,7 @@ class Plugin(GlancesPlugin): self.display_curse = True # Set the message position - self.set_align('right') + self.align = 'right' # Init the stats self.reset() @@ -61,16 +61,15 @@ class Plugin(GlancesPlugin): # Reset stats self.reset() - if self.get_input() == 'local': + if self.input_method == 'local': # Update stats using the standard system lib - uptime = datetime.now() - \ - datetime.fromtimestamp(psutil.boot_time()) + uptime = datetime.now() - datetime.fromtimestamp(psutil.boot_time()) # Convert uptime to string (because datetime is not JSONifi) self.stats = str(uptime).split('.')[0] - elif self.get_input() == 'snmp': + elif self.input_method == 'snmp': # Update stats using SNMP - uptime = self.set_stats_snmp(snmp_oid=snmp_oid)['_uptime'] + uptime = self.get_stats_snmp(snmp_oid=snmp_oid)['_uptime'] try: # In hundredths of seconds self.stats = str(timedelta(seconds=int(uptime) / 100)) @@ -82,11 +81,4 @@ class Plugin(GlancesPlugin): def msg_curse(self, args=None): """Return the string to display in the curse interface.""" - # Init the return message - ret = [] - - # Add the line with decoration - ret.append(self.curse_add_line(_("Uptime: {0}").format(self.stats))) - - # Return the message with decoration - return ret + return [self.curse_add_line('Uptime: {0}'.format(self.stats))] diff --git a/i18n-gen.sh b/i18n-gen.sh deleted file mode 100755 index a530281e..00000000 --- a/i18n-gen.sh +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/bash - -#Calculates the direcory of the script in case it is run from another directory -ROOT="${0%%i18n-gen.sh}" - -function usage() { - cat < language_code - -Available subcommands: - init - creates a new folder for a new language - update - updates an existing language file with new Strings from the sources - gen - generates the parsed language file - -update and gen also accept the wildcard language_code ALL - -Suggested Workflows (with XX as language_code): - New Language - 1. $0 init XX - 2. translation of ${ROOT}i18n/XX/LC_MESSAGES/glances.po - 3. $0 gen XX - Update Language - 1. $0 update XX - 2. update translations of ${ROOT}i18n/XX/LC_MESSAGES/glances.po - 3. $0 gen XX -EOT -exit -} - -function gen_pot() { - xgettext --language=Python --keyword=_ --output=${ROOT}i18n/glances.pot `find ${ROOT}glances/ -name "*.py"` -} - -if [ $# != 2 ]; then - usage -fi - -OPERATION="$1" -shift - -case "$OPERATION" in - init) - # If there is already a language file for specified language there is no need to generate a new one - # doing so would result in a loss of all already translated strings for that language - if [ -f "${ROOT}i18n/$1/LC_MESSAGES/glances.po" ]; then - echo "Error:" - echo "Language file for language $1 already exists" - echo "Please run \"$0 help\" for more information" - exit 1 - fi - # Actual generation - mkdir -p ${ROOT}i18n/$1/LC_MESSAGES/ - gen_pot - msginit --locale="$1" --input=${ROOT}i18n/glances.pot --output=${ROOT}i18n/$1/LC_MESSAGES/glances.po - exit 0 - ;; - update) - # When the language code is ALL fetch all language codes and save them - # else test if the specified language code really exists - if [ "$1" = "ALL" ]; then - LANG_LIST="$(ls -d ${ROOT}i18n/*/ | awk -F / '{print $(NF-1)}')" - else - if [ ! -f "${ROOT}i18n/$1/LC_MESSAGES/glances.po" ]; then - echo "Error:" - echo "Language file for language $1 doesn't exists" - echo "Please run \"$0 help\" for more information" - exit 1 - fi - LANG_LIST="$1" - fi - # regenerate the pot file so that it conatins the new strings and then update the language files accordingly - gen_pot - for i in $LANG_LIST; do - msgmerge --update --no-fuzzy-matching --backup=off ${ROOT}i18n/$i/LC_MESSAGES/glances.po ${ROOT}i18n/glances.pot - echo "Language file for language $i updated" - done - exit 0 - ;; - gen) - # When the language code is ALL fetch all language codes and save them - # else test if the specified language code really exists - if [ "$1" = "ALL" ]; then - LANG_LIST="$(ls -d ${ROOT}i18n/*/ | awk -F / '{print $(NF-1)}')" - else - if [ ! -f "${ROOT}i18n/$1/LC_MESSAGES/glances.po" ]; then - echo "Error:" - echo "Language file for language $1 doesn't exists" - echo "Please run \"$0 help\" for more information" - exit 1 - fi - LANG_LIST="$1" - fi - # compile the language files - for i in $LANG_LIST; do - msgfmt ${ROOT}i18n/$i/LC_MESSAGES/glances.po --output-file ${ROOT}i18n/$i/LC_MESSAGES/glances.mo - echo "Compiled language file for language $i generated" - done - exit 0 - ;; - *) - # if anything other is entered as first argument print the usage overview - # so, the message to run "i18n-gen.sh help" is a LIE but who cares since the cake was a lie in the first place! - usage - ;; -esac diff --git a/i18n/de/LC_MESSAGES/glances.mo b/i18n/de/LC_MESSAGES/glances.mo deleted file mode 100644 index 08e342d2..00000000 Binary files a/i18n/de/LC_MESSAGES/glances.mo and /dev/null differ diff --git a/i18n/de/LC_MESSAGES/glances.po b/i18n/de/LC_MESSAGES/glances.po deleted file mode 100644 index 559bdeb5..00000000 --- a/i18n/de/LC_MESSAGES/glances.po +++ /dev/null @@ -1,947 +0,0 @@ -# German translations for GLANCES package. -# Copyright (C) 2014 THE GLANCES'S COPYRIGHT HOLDER -# This file is distributed under the same license as the GLANCES package. -# David Tiersch , 2014. -# -msgid "" -msgstr "" -"Project-Id-Version: GLANCES 2.0_RC4\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-12-13 22:14+0100\n" -"PO-Revision-Date: 2014-06-03 16:33+0100\n" -"Last-Translator: David Tiersch \n" -"Language-Team: German\n" -"Language: de\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 1.5.4\n" -"X-Poedit-Basepath: ~/dev/glances\n" - -#: glances/__init__.py:166 -#, python-brace-format -msgid "Glances server is running on {0}:{1}" -msgstr "Glances-Server läuft auf {0}:{1}" - -#: glances/plugins/glances_diskio.py:132 -msgid "DISK I/O" -msgstr "DISK I/O" - -#: glances/plugins/glances_diskio.py:134 -msgid "R/s" -msgstr "R/s" - -#: glances/plugins/glances_diskio.py:136 -msgid "W/s" -msgstr "W/s" - -#: glances/plugins/glances_memswap.py:146 -msgid "SWAP" -msgstr "SWAP" - -#: glances/plugins/glances_memswap.py:154 glances/plugins/glances_mem.py:185 -msgid "total:" -msgstr "gesamt:" - -#: glances/plugins/glances_memswap.py:161 glances/plugins/glances_mem.py:198 -msgid "used:" -msgstr "benutzt:" - -#: glances/plugins/glances_memswap.py:169 glances/plugins/glances_mem.py:212 -msgid "free:" -msgstr "frei:" - -#: glances/plugins/glances_batpercent.py:96 -msgid "Battery (%)" -msgstr "Batterie (%)" - -#: glances/plugins/glances_percpu.py:94 -msgid "PER CPU not available" -msgstr "PRO-CPU nicht möglich" - -#: glances/plugins/glances_percpu.py:100 -msgid "PER CPU" -msgstr "PRO CPU" - -#: glances/plugins/glances_percpu.py:110 glances/plugins/glances_cpu.py:159 -msgid "user:" -msgstr "Benutzer:" - -#: glances/plugins/glances_percpu.py:118 glances/plugins/glances_cpu.py:178 -msgid "system:" -msgstr "System:" - -#: glances/plugins/glances_percpu.py:126 glances/plugins/glances_cpu.py:164 -#: glances/plugins/glances_cpu.py:197 -msgid "idle:" -msgstr "Inaktiv:" - -#: glances/plugins/glances_processcount.py:76 -msgid "PROCESSES DISABLED (press 'z' to display)" -msgstr "PROZESS DEAKTIVIERT (drücke 'z' zum anzeigen)" - -#: glances/plugins/glances_processcount.py:85 -msgid "Processes filter:" -msgstr "" - -#: glances/plugins/glances_processcount.py:87 -#, python-brace-format -msgid " {0} " -msgstr "" - -#: glances/plugins/glances_processcount.py:89 -msgid "(press ENTER to edit)" -msgstr "" - -#: glances/plugins/glances_processcount.py:95 -msgid "TASKS " -msgstr "PROZESSE " - -#: glances/plugins/glances_processcount.py:103 -#, python-brace-format -msgid " ({0} thr)," -msgstr " ({0} thr)," - -#: glances/plugins/glances_processcount.py:108 -#, python-brace-format -msgid " {0} run," -msgstr " {0} run," - -#: glances/plugins/glances_processcount.py:113 -#, python-brace-format -msgid " {0} slp," -msgstr " {0} slp," - -#: glances/plugins/glances_processcount.py:116 -#, python-brace-format -msgid " {0} oth " -msgstr " {0} oth " - -#: glances/plugins/glances_processcount.py:121 -msgid "sorted automatically" -msgstr "automatisch sortiert" - -#: glances/plugins/glances_processcount.py:123 -#, python-brace-format -msgid " by {0}" -msgstr " nach {0}" - -#: glances/plugins/glances_processcount.py:126 -#, python-brace-format -msgid "sorted by {0}" -msgstr "sortiert nach {0}" - -#: glances/plugins/glances_fs.py:175 -msgid "FILE SYS" -msgstr "DATEISYSTEM" - -#: glances/plugins/glances_fs.py:178 -msgid "Free" -msgstr "" - -#: glances/plugins/glances_fs.py:180 -msgid "Used" -msgstr "Belegt" - -#: glances/plugins/glances_fs.py:182 -msgid "Total" -msgstr "Gesamt" - -#: glances/plugins/glances_uptime.py:89 -#, python-brace-format -msgid "Uptime: {0}" -msgstr "Betriebszeit: {0}" - -#: glances/plugins/glances_sensors.py:133 -msgid "SENSORS" -msgstr "SENSOREN" - -#: glances/plugins/glances_sensors.py:136 -#: glances/plugins/glances_sensors.py:138 -msgid "°C" -msgstr "°C" - -#: glances/plugins/glances_now.py:47 -msgid "%Y-%m-%d %H:%M:%S" -msgstr "%d.%m.%Y %H:%M:%S" - -#: glances/plugins/glances_processlist.py:288 -msgid "CPU affinity: " -msgstr "" - -#: glances/plugins/glances_processlist.py:288 -msgid " cores" -msgstr "" - -#: glances/plugins/glances_processlist.py:293 -msgid "Memory info: " -msgstr "" - -#: glances/plugins/glances_processlist.py:299 -msgid "swap " -msgstr "" - -#: glances/plugins/glances_processlist.py:304 -msgid "threads " -msgstr "" - -#: glances/plugins/glances_processlist.py:306 -msgid "files " -msgstr "" - -#: glances/plugins/glances_processlist.py:308 -msgid "handles " -msgstr "" - -#: glances/plugins/glances_processlist.py:310 -msgid "TCP " -msgstr "" - -#: glances/plugins/glances_processlist.py:312 -msgid "UDP " -msgstr "" - -#: glances/plugins/glances_processlist.py:315 -msgid "Open: " -msgstr "" - -#: glances/plugins/glances_processlist.py:320 -msgid "IO nice: " -msgstr "" - -#: glances/plugins/glances_processlist.py:321 -msgid "Class is " -msgstr "" - -#: glances/plugins/glances_processlist.py:331 -#: glances/plugins/glances_processlist.py:336 -msgid "No specific I/O priority" -msgstr "" - -#: glances/plugins/glances_processlist.py:348 -#, python-format -msgid " (value %s/7)" -msgstr "" - -#: glances/plugins/glances_processlist.py:367 -#: glances/outputs/glances_curses.py:1012 -msgid "CPU%" -msgstr "CPU %" - -#: glances/plugins/glances_processlist.py:369 -#: glances/outputs/glances_curses.py:1013 -msgid "MEM%" -msgstr "RAM%" - -#: glances/plugins/glances_processlist.py:371 -msgid "VIRT" -msgstr "VIRT" - -#: glances/plugins/glances_processlist.py:373 -msgid "RES" -msgstr "RES" - -#: glances/plugins/glances_processlist.py:375 -msgid "PID" -msgstr "PID" - -#: glances/plugins/glances_processlist.py:377 -msgid "USER" -msgstr "BENUTZER" - -#: glances/plugins/glances_processlist.py:379 -msgid "NI" -msgstr "NI" - -#: glances/plugins/glances_processlist.py:381 -msgid "S" -msgstr "S" - -#: glances/plugins/glances_processlist.py:383 -msgid "TIME+" -msgstr "ZEIT+" - -#: glances/plugins/glances_processlist.py:385 -msgid "IOR/s" -msgstr "IOR/s" - -#: glances/plugins/glances_processlist.py:387 -msgid "IOW/s" -msgstr "IOW/s" - -#: glances/plugins/glances_processlist.py:389 -msgid "Command" -msgstr "Befehl" - -#: glances/plugins/glances_monitor.py:101 -msgid "RUNNING" -msgstr "LAUFEND" - -#: glances/plugins/glances_monitor.py:101 -msgid "NOT RUNNING" -msgstr "NICHT LAUFEND" - -#: glances/plugins/glances_network.py:201 -msgid "NETWORK" -msgstr "NETZWERK" - -#: glances/plugins/glances_network.py:207 -msgid "Rx+Tx" -msgstr "Rx+Tx" - -#: glances/plugins/glances_network.py:211 -msgid "Rx" -msgstr "Rx" - -#: glances/plugins/glances_network.py:213 -msgid "Tx" -msgstr "Tx" - -#: glances/plugins/glances_network.py:219 -msgid "Rx+Tx/s" -msgstr "Rx+Tx/s" - -#: glances/plugins/glances_network.py:222 -msgid "Rx/s" -msgstr "Rx/s" - -#: glances/plugins/glances_network.py:224 -msgid "Tx/s" -msgstr "Tx/s" - -#: glances/plugins/glances_alert.py:71 -msgid "No warning or critical alert detected" -msgstr "Keine (kritische) Warnung entdeckt" - -#: glances/plugins/glances_alert.py:75 -msgid "Warning or critical alerts" -msgstr "(Kritische) Warnungen" - -#: glances/plugins/glances_alert.py:79 -#, python-brace-format -msgid " (lasts {0} entries)" -msgstr " (letzte {0} Einträge)" - -#: glances/plugins/glances_alert.py:81 -msgid " (one entry)" -msgstr " (ein Eintrag)" - -#: glances/plugins/glances_alert.py:95 -msgid " (ongoing)" -msgstr "(laufend)" - -#: glances/plugins/glances_alert.py:101 -#, python-brace-format -msgid "{0} on {1}" -msgstr "{0} auf {1}" - -#: glances/plugins/glances_alert.py:110 -#, python-brace-format -msgid " (Min:{0:.1f} Mean:{1:.1f} Max:{2:.1f})" -msgstr " (Min:{0:.1f} Mittel:{1:.1f} Max:{2:.1f})" - -#: glances/plugins/glances_system.py:158 -msgid "Connected to " -msgstr "Verbunden mit " - -#: glances/plugins/glances_system.py:161 -msgid "SNMP from " -msgstr "SNMP von " - -#: glances/plugins/glances_system.py:164 -msgid "Disconnected from " -msgstr "Getrennt von " - -#: glances/plugins/glances_mem.py:171 -msgid "MEM" -msgstr "RAM" - -#: glances/plugins/glances_mem.py:178 -msgid "active:" -msgstr "aktiv:" - -#: glances/plugins/glances_mem.py:191 -msgid "inactive:" -msgstr "inaktiv:" - -#: glances/plugins/glances_mem.py:205 -msgid "buffers:" -msgstr "Puffer:" - -#: glances/plugins/glances_mem.py:218 -msgid "cached:" -msgstr "cached:" - -#: glances/plugins/glances_help.py:58 -#, python-brace-format -msgid " with PSutil {0}" -msgstr "" - -#: glances/plugins/glances_help.py:64 -msgid "Configuration file" -msgstr "" - -#: glances/plugins/glances_help.py:77 -msgid "Sort processes automatically" -msgstr "Prozesse automatisch sortieren" - -#: glances/plugins/glances_help.py:79 -msgid "Bytes or bits for network I/O" -msgstr "Bytes oder Bits für Netzwerk I/O" - -#: glances/plugins/glances_help.py:82 -msgid "Sort processes by CPU%" -msgstr "Prozesse nach CPU% sortieren" - -#: glances/plugins/glances_help.py:84 -msgid "Show/hide alert logs" -msgstr "" - -#: glances/plugins/glances_help.py:87 -msgid "Sort processes by MEM%" -msgstr "Prozesse nach RAM% sortieren" - -#: glances/plugins/glances_help.py:89 -msgid "Delete warning alerts" -msgstr "Warnungen entfernen" - -#: glances/plugins/glances_help.py:92 -msgid "Sort processes by name" -msgstr "Prozesse nach Name sortieren" - -#: glances/plugins/glances_help.py:94 -msgid "Delete warning and critical alerts" -msgstr "(Kritische) Warnungen entfernen" - -#: glances/plugins/glances_help.py:97 -msgid "Sort processes by I/O rate" -msgstr "Prozesse nach I/O-Geschwindigkeit sortieren" - -#: glances/plugins/glances_help.py:99 -msgid "Global CPU or per-CPU stats" -msgstr "Globale oder pro-CPU-Daten" - -#: glances/plugins/glances_help.py:102 -msgid "Sort processes by CPU times" -msgstr "" - -#: glances/plugins/glances_help.py:104 -msgid "Show/hide this help screen" -msgstr "Diese Hilfe zeigen/verstecken" - -#: glances/plugins/glances_help.py:107 -msgid "Show/hide disk I/O stats" -msgstr "I/O-Daten zeigen/verstecken" - -#: glances/plugins/glances_help.py:109 -msgid "View network I/O as combination" -msgstr "Netzwerk-I/O kombiniert zeigen" - -#: glances/plugins/glances_help.py:112 -msgid "Show/hide filesystem stats" -msgstr "" - -#: glances/plugins/glances_help.py:114 -msgid "View cumulative network I/O" -msgstr "kumulative Netzwerk-I/O zeigen" - -#: glances/plugins/glances_help.py:117 -msgid "Show/hide network stats" -msgstr "Netzwerk-Daten zeigen/verstecken" - -#: glances/plugins/glances_help.py:119 -msgid "Show filesystem free space" -msgstr "" - -#: glances/plugins/glances_help.py:122 -msgid "Show/hide sensors stats" -msgstr "Sensor-Daten zeigen/verstecken" - -#: glances/plugins/glances_help.py:124 -msgid "Generate graphs for current history" -msgstr "" - -#: glances/plugins/glances_help.py:127 -msgid "Show/hide left sidebar" -msgstr "" - -#: glances/plugins/glances_help.py:129 glances/outputs/glances_curses.py:550 -msgid "Reset history" -msgstr "" - -#: glances/plugins/glances_help.py:132 -msgid "Enable/disable processes stats" -msgstr "Prozess-Daten aktivieren/deaktivieren" - -#: glances/plugins/glances_help.py:134 -msgid "Quit (Esc and Ctrl-C also work)" -msgstr "Beenden (auch Esc und Strg+C)" - -#: glances/plugins/glances_help.py:137 -msgid "Enable/disable top extended stats" -msgstr "" - -#: glances/plugins/glances_help.py:140 -msgid "Enable/disable short processes name" -msgstr "" - -#: glances/plugins/glances_help.py:145 -msgid "Edit the process filter pattern" -msgstr "" - -#: glances/plugins/glances_load.py:127 glances/outputs/glances_curses.py:1011 -msgid "LOAD" -msgstr "LAST" - -#: glances/plugins/glances_load.py:131 -#, python-brace-format -msgid "{0:d}-core" -msgstr "" - -#: glances/plugins/glances_load.py:136 -msgid "1 min:" -msgstr "1 Min:" - -#: glances/plugins/glances_load.py:143 -msgid "5 min:" -msgstr "5 Min:" - -#: glances/plugins/glances_load.py:151 -msgid "15 min:" -msgstr "15 Min:" - -#: glances/plugins/glances_cpu.py:141 -msgid "CPU" -msgstr "CPU" - -#: glances/plugins/glances_cpu.py:151 -msgid "nice:" -msgstr "nice:" - -#: glances/plugins/glances_cpu.py:170 -msgid "irq:" -msgstr "IRQ:" - -#: glances/plugins/glances_cpu.py:183 -msgid "core:" -msgstr "" - -#: glances/plugins/glances_cpu.py:189 -msgid "iowait:" -msgstr "IOWait:" - -#: glances/plugins/glances_cpu.py:203 -msgid "steal:" -msgstr "Steal:" - -#: glances/outputs/glances_curses.py:546 -#, python-format -msgid "" -"Generate graphs history in %s\n" -"Please wait..." -msgstr "" - -#: glances/outputs/glances_curses.py:548 -#, python-format -msgid "" -"Generate graphs history in %s\n" -"Done: %s graphs generated" -msgstr "" - -#: glances/outputs/glances_curses.py:557 -msgid "" -"History disabled\n" -"Enable it using --enable-history" -msgstr "" - -#: glances/outputs/glances_curses.py:560 -msgid "" -"History disabled\n" -"Please install MatPlotLib" -msgstr "" - -#: glances/outputs/glances_curses.py:567 -msgid "Process filter pattern: " -msgstr "" - -#: glances/outputs/glances_curses.py:573 -msgid "Process filter only available in standalone mode" -msgstr "" - -#: glances/outputs/glances_curses.py:984 -msgid "Glances is scanning your network (please wait)..." -msgstr "" - -#: glances/outputs/glances_curses.py:987 -msgid "No Glances servers available" -msgstr "" - -#: glances/outputs/glances_curses.py:989 -msgid "One Glances server available" -msgstr "" - -#: glances/outputs/glances_curses.py:991 -#, python-format -msgid "%d Glances servers available" -msgstr "" - -#: glances/outputs/glances_curses.py:994 -msgid "(auto discover is disabled)" -msgstr "" - -#: glances/outputs/glances_curses.py:1009 -msgid "Name" -msgstr "" - -#: glances/outputs/glances_curses.py:1014 -msgid "STATUS" -msgstr "" - -#: glances/outputs/glances_curses.py:1015 -msgid "IP" -msgstr "" - -#: glances/outputs/glances_curses.py:1017 -msgid "OS" -msgstr "" - -#: glances/outputs/glances_bottle.py:34 -msgid "Install it using pip: # pip install bottle" -msgstr "" - -#: glances/outputs/glances_bottle.py:104 -#, python-brace-format -msgid "Glances web server started on http://{0}:{1}/" -msgstr "" - -#: glances/core/glances_password.py:119 -msgid "Password: " -msgstr "Passwort:" - -#: glances/core/glances_password.py:123 -msgid "Password (confirm): " -msgstr "Passwort (wiederholen):" - -#: glances/core/glances_password.py:137 -msgid "Do you want to save the password? [Yes/No]: " -msgstr "Willst du das Passwort speichern? [Ja/Nein]" - -#: glances/core/glances_password.py:138 -msgid "Y" -msgstr "J" - -#: glances/core/glances_monitor_list.py:146 -msgid "Error: " -msgstr "Fehler: " - -#: glances/core/glances_monitor_list.py:148 -msgid "Cannot execute command" -msgstr "Kann Befehl nicht ausführen" - -#: glances/core/glances_client_browser.py:158 -#, python-format -msgid "Connect to %s:%s" -msgstr "" - -#: glances/core/glances_client_browser.py:164 -#, python-format -msgid "Password needed for %s: " -msgstr "" - -#: glances/core/glances_client_browser.py:187 -#, python-format -msgid "Sorry, cannot connect to %s (see log file for additional information)" -msgstr "" - -#: glances/core/glances_client.py:116 -msgid "Trying fallback to SNMP..." -msgstr "" - -#: glances/core/glances_main.py:65 -msgid "Enable debug mode" -msgstr "" - -#: glances/core/glances_main.py:67 -msgid "path to the configuration file" -msgstr "Pfad zur Konfigurationsdatei" - -#: glances/core/glances_main.py:70 -msgid "disable network module" -msgstr "Netzwerk-Modul deaktivieren" - -#: glances/core/glances_main.py:72 -msgid "disable disk I/O module" -msgstr "Disk-I/O-Modul deaktivieren" - -#: glances/core/glances_main.py:74 -msgid "disable filesystem module" -msgstr "Dateisystem-Modul deaktivieren" - -#: glances/core/glances_main.py:76 -msgid "disable sensors module" -msgstr "Sensor-Modul deaktivieren" - -#: glances/core/glances_main.py:78 -msgid "disable network, disk io, FS and sensors modules" -msgstr "" - -#: glances/core/glances_main.py:80 -msgid "disable process module" -msgstr "Prozess-Modul deaktivieren" - -#: glances/core/glances_main.py:82 -msgid "disable log module" -msgstr "Log-Modul deaktivieren" - -#: glances/core/glances_main.py:84 -msgid "disable bold mode in the terminal" -msgstr "Fett-Modus im Terminal deaktivieren" - -#: glances/core/glances_main.py:86 -msgid "enable extended stats on top process" -msgstr "" - -#: glances/core/glances_main.py:88 -msgid "enable the history mode" -msgstr "" - -#: glances/core/glances_main.py:90 -msgid "Set the export path for graph history" -msgstr "" - -#: glances/core/glances_main.py:93 -msgid "export stats to a CSV file" -msgstr "Exportiere Daten zu CSV-Datei" - -#: glances/core/glances_main.py:96 -msgid "connect to a Glances server by IPv4/IPv6 address or hostname" -msgstr "Zu einem Glances-Server mit IPv4/IPv6-Adresse oder Hostnamen verbinden" - -#: glances/core/glances_main.py:98 -msgid "run Glances in server mode" -msgstr "Glances im Server-Modus ausführen" - -#: glances/core/glances_main.py:100 -msgid "start the client browser (list of servers)" -msgstr "" - -#: glances/core/glances_main.py:102 -msgid "disable autodiscover feature" -msgstr "" - -#: glances/core/glances_main.py:104 -#, python-brace-format -msgid "define the client/server TCP port [default: {0}]" -msgstr "Client-/Server-TCP-Port festlegen [default: {0}]" - -#: glances/core/glances_main.py:106 -msgid "bind server to the given IPv4/IPv6 address or hostname" -msgstr "Server auf gegebene IPv4/IPv6-Adresse oder Hostnamen festlegen" - -#: glances/core/glances_main.py:108 -msgid "define password from the command line" -msgstr "Passwort auf Kommandozeile bestimmen" - -#: glances/core/glances_main.py:110 -msgid "define a client/server password from the prompt or file" -msgstr "Client-/Server-Passwort über Prompt oder Datei festlegen" - -#: glances/core/glances_main.py:112 -msgid "SNMP community" -msgstr "SNMP-Community" - -#: glances/core/glances_main.py:114 -msgid "SNMP port" -msgstr "SNMP-Port" - -#: glances/core/glances_main.py:116 -msgid "SNMP version (1, 2c or 3)" -msgstr "SNMP-Version (1, 2c oder 3)" - -#: glances/core/glances_main.py:118 -msgid "SNMP username (only for SNMPv3)" -msgstr "SNMP-Benutzername (nur für SNMPv3)" - -#: glances/core/glances_main.py:120 -msgid "SNMP authentication key (only for SNMPv3)" -msgstr "SNMP-Authentifizierungs-Schlüssel (nur für SNMPv3)" - -#: glances/core/glances_main.py:122 -msgid "force SNMP mode" -msgstr "" - -#: glances/core/glances_main.py:124 -#, python-brace-format -msgid "set refresh time in seconds [default: {0} sec]" -msgstr "Aktualisierungszeit in Sekunden [default: {0} Sek]" - -#: glances/core/glances_main.py:126 -msgid "run Glances in web server mode" -msgstr "Glances im Webserver-Modus starten" - -#: glances/core/glances_main.py:129 -msgid "set the process filter pattern (regular expression)" -msgstr "" - -#: glances/core/glances_main.py:131 -msgid "force short name for processes name" -msgstr "" - -#: glances/core/glances_main.py:134 -msgid "hide kernel threads in process list" -msgstr "" - -#: glances/core/glances_main.py:136 -msgid "display processes as a tree" -msgstr "" - -#: glances/core/glances_main.py:138 -msgid "display network rate in byte per second" -msgstr "Netzwerkgeschwindigkeit anzeigen in Byte/Sekunde" - -#: glances/core/glances_main.py:140 -msgid "start Glances in per CPU mode" -msgstr "Glances im pro-CPU-Modus starten" - -#: glances/core/glances_main.py:142 -msgid "display FS free space instead of used" -msgstr "" - -#: glances/core/glances_main.py:144 -msgid "optimize display for white background" -msgstr "" - -#: glances/core/glances_main.py:188 -msgid "Define the password for the Glances server" -msgstr "Passwort für Glances-Server festlegen" - -#: glances/core/glances_main.py:192 -msgid "Enter the Glances server password" -msgstr "Passwort für Glances-Server eingeben" - -#~ msgid "Error: The server version is not compatible with the client" -#~ msgstr "Fehler: Die Server-Version ist mit dem Client nicht kompatibel" - -#~ msgid "Error: Update {0} failed: {1}" -#~ msgstr "Fehler: Aktualisierung {0} ist fehlgeschlagen: {1}" - -#~ msgid "Error: Couldn't create socket {0}: {1}" -#~ msgstr "Fehler: Konnte Socket {0} nicht erzeugen: {1}" - -#~ msgid "Error: Connection to server failed: Bad password" -#~ msgstr "Fehler: Verbindung zum Server fehlgeschlagen: Falsches Passwort" - -#~ msgid "Error: Connection to server failed: {0}" -#~ msgstr "Fehler: Verbindung zum Server fehlgeschlagen: {0}" - -#~ msgid "" -#~ "Info: Connection to Glances server failed. Trying fallback to SNMP..." -#~ msgstr "" -#~ "Info: Verbindung zum Glances-Server fehlgeschlagen. Versuche Fallback zu " -#~ "SNMP..." - -#~ msgid "Error: Connection to SNMP server failed" -#~ msgstr "Fehler: Verbindung zum SNMP-Server fehlgeschlagen" - -#~ msgid "Error: Unknown server mode: {0}" -#~ msgstr "Fehler: Unbekannter Servers-Modus: {0}" - -#~ msgid "Error: Cannot decode configuration file '{0}': {1}" -#~ msgstr "Fehler: Kann Konfigurationsdatei '{0}' nicht lesen: {1}" - -#~ msgid "Error: Cannot read monitored list: {0}" -#~ msgstr "Fehler: Kann Überwachungs-Liste nicht lesen: {0}" - -#~ msgid "Info: Read password from file: {0}" -#~ msgstr "Info: Passwort gelesen aus Datei {0}" - -#~ msgid "Error: Sorry, but passwords did not match..." -#~ msgstr "Fehler: Passwörter stimmen nicht überein..." - -#~ msgid "Warning: Cannot create Glances directory: {0}" -#~ msgstr "Warnung: Kann Glances-Ordner nicht erzeugen: {0}" - -#~ msgid "Error: Couldn't open socket: {0}" -#~ msgstr "Fehler: Kann Socket nicht öffnen: {0}" - -#~ msgid "Error: Cannot start Glances server: {0}" -#~ msgstr "Fehler: Kann Glances-Server nicht starten: {0}" - -#~ msgid "Error: Cannot init the curses library.\n" -#~ msgstr "Fehler: Kann curses-Bibliothek nicht initialisieren.\n" - -#~ msgid "Error: Cannot create the CSV file: {0}" -#~ msgstr "Fehler: Kann CSV-Datei nicht erzeugen: {0}" - -#~ msgid "Stats dumped to CSV file: {0}" -#~ msgstr "Daten nach CSV-Datei gespeichert: {0}" - -#~ msgid " with psutil {0}" -#~ msgstr " mit psutil {0}" - -#~ msgid "a" -#~ msgstr "a" - -#~ msgid "b" -#~ msgstr "b" - -#~ msgid "c" -#~ msgstr "c" - -#~ msgid "l" -#~ msgstr "l" - -#~ msgid "Show/hide logs (alerts)" -#~ msgstr "Logs (Warnungen) zeigen/verstecken" - -#~ msgid "m" -#~ msgstr "m" - -#~ msgid "w" -#~ msgstr "w" - -#~ msgid "p" -#~ msgstr "p" - -#~ msgid "x" -#~ msgstr "x" - -#~ msgid "i" -#~ msgstr "i" - -#~ msgid "1" -#~ msgstr "1" - -#~ msgid "d" -#~ msgstr "d" - -#~ msgid "h" -#~ msgstr "h" - -#~ msgid "f" -#~ msgstr "f" - -#~ msgid "Show/hide file system stats" -#~ msgstr "Zeige/Verstecke Dateisystem-Daten" - -#~ msgid "t" -#~ msgstr "t" - -#~ msgid "n" -#~ msgstr "n" - -#~ msgid "u" -#~ msgstr "u" - -#~ msgid "s" -#~ msgstr "s" - -#~ msgid "z" -#~ msgstr "z" - -#~ msgid "q" -#~ msgstr "q" - -#~ msgid "{0}-core" -#~ msgstr "{0}-Kern" diff --git a/i18n/glances.pot b/i18n/glances.pot deleted file mode 100644 index 96436991..00000000 --- a/i18n/glances.pot +++ /dev/null @@ -1,819 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-12-13 22:14+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: glances/__init__.py:166 -#, python-brace-format -msgid "Glances server is running on {0}:{1}" -msgstr "" - -#: glances/plugins/glances_diskio.py:132 -msgid "DISK I/O" -msgstr "" - -#: glances/plugins/glances_diskio.py:134 -msgid "R/s" -msgstr "" - -#: glances/plugins/glances_diskio.py:136 -msgid "W/s" -msgstr "" - -#: glances/plugins/glances_memswap.py:146 -msgid "SWAP" -msgstr "" - -#: glances/plugins/glances_memswap.py:154 glances/plugins/glances_mem.py:185 -msgid "total:" -msgstr "" - -#: glances/plugins/glances_memswap.py:161 glances/plugins/glances_mem.py:198 -msgid "used:" -msgstr "" - -#: glances/plugins/glances_memswap.py:169 glances/plugins/glances_mem.py:212 -msgid "free:" -msgstr "" - -#: glances/plugins/glances_batpercent.py:96 -msgid "Battery (%)" -msgstr "" - -#: glances/plugins/glances_percpu.py:94 -msgid "PER CPU not available" -msgstr "" - -#: glances/plugins/glances_percpu.py:100 -msgid "PER CPU" -msgstr "" - -#: glances/plugins/glances_percpu.py:110 glances/plugins/glances_cpu.py:159 -msgid "user:" -msgstr "" - -#: glances/plugins/glances_percpu.py:118 glances/plugins/glances_cpu.py:178 -msgid "system:" -msgstr "" - -#: glances/plugins/glances_percpu.py:126 glances/plugins/glances_cpu.py:164 -#: glances/plugins/glances_cpu.py:197 -msgid "idle:" -msgstr "" - -#: glances/plugins/glances_processcount.py:76 -msgid "PROCESSES DISABLED (press 'z' to display)" -msgstr "" - -#: glances/plugins/glances_processcount.py:85 -msgid "Processes filter:" -msgstr "" - -#: glances/plugins/glances_processcount.py:87 -#, python-brace-format -msgid " {0} " -msgstr "" - -#: glances/plugins/glances_processcount.py:89 -msgid "(press ENTER to edit)" -msgstr "" - -#: glances/plugins/glances_processcount.py:95 -msgid "TASKS " -msgstr "" - -#: glances/plugins/glances_processcount.py:103 -#, python-brace-format -msgid " ({0} thr)," -msgstr "" - -#: glances/plugins/glances_processcount.py:108 -#, python-brace-format -msgid " {0} run," -msgstr "" - -#: glances/plugins/glances_processcount.py:113 -#, python-brace-format -msgid " {0} slp," -msgstr "" - -#: glances/plugins/glances_processcount.py:116 -#, python-brace-format -msgid " {0} oth " -msgstr "" - -#: glances/plugins/glances_processcount.py:121 -msgid "sorted automatically" -msgstr "" - -#: glances/plugins/glances_processcount.py:123 -#, python-brace-format -msgid " by {0}" -msgstr "" - -#: glances/plugins/glances_processcount.py:126 -#, python-brace-format -msgid "sorted by {0}" -msgstr "" - -#: glances/plugins/glances_fs.py:175 -msgid "FILE SYS" -msgstr "" - -#: glances/plugins/glances_fs.py:178 -msgid "Free" -msgstr "" - -#: glances/plugins/glances_fs.py:180 -msgid "Used" -msgstr "" - -#: glances/plugins/glances_fs.py:182 -msgid "Total" -msgstr "" - -#: glances/plugins/glances_uptime.py:89 -#, python-brace-format -msgid "Uptime: {0}" -msgstr "" - -#: glances/plugins/glances_sensors.py:133 -msgid "SENSORS" -msgstr "" - -#: glances/plugins/glances_sensors.py:136 -#: glances/plugins/glances_sensors.py:138 -msgid "°C" -msgstr "" - -#: glances/plugins/glances_now.py:47 -msgid "%Y-%m-%d %H:%M:%S" -msgstr "" - -#: glances/plugins/glances_processlist.py:288 -msgid "CPU affinity: " -msgstr "" - -#: glances/plugins/glances_processlist.py:288 -msgid " cores" -msgstr "" - -#: glances/plugins/glances_processlist.py:293 -msgid "Memory info: " -msgstr "" - -#: glances/plugins/glances_processlist.py:299 -msgid "swap " -msgstr "" - -#: glances/plugins/glances_processlist.py:304 -msgid "threads " -msgstr "" - -#: glances/plugins/glances_processlist.py:306 -msgid "files " -msgstr "" - -#: glances/plugins/glances_processlist.py:308 -msgid "handles " -msgstr "" - -#: glances/plugins/glances_processlist.py:310 -msgid "TCP " -msgstr "" - -#: glances/plugins/glances_processlist.py:312 -msgid "UDP " -msgstr "" - -#: glances/plugins/glances_processlist.py:315 -msgid "Open: " -msgstr "" - -#: glances/plugins/glances_processlist.py:320 -msgid "IO nice: " -msgstr "" - -#: glances/plugins/glances_processlist.py:321 -msgid "Class is " -msgstr "" - -#: glances/plugins/glances_processlist.py:331 -#: glances/plugins/glances_processlist.py:336 -msgid "No specific I/O priority" -msgstr "" - -#: glances/plugins/glances_processlist.py:348 -#, python-format -msgid " (value %s/7)" -msgstr "" - -#: glances/plugins/glances_processlist.py:367 -#: glances/outputs/glances_curses.py:1012 -msgid "CPU%" -msgstr "" - -#: glances/plugins/glances_processlist.py:369 -#: glances/outputs/glances_curses.py:1013 -msgid "MEM%" -msgstr "" - -#: glances/plugins/glances_processlist.py:371 -msgid "VIRT" -msgstr "" - -#: glances/plugins/glances_processlist.py:373 -msgid "RES" -msgstr "" - -#: glances/plugins/glances_processlist.py:375 -msgid "PID" -msgstr "" - -#: glances/plugins/glances_processlist.py:377 -msgid "USER" -msgstr "" - -#: glances/plugins/glances_processlist.py:379 -msgid "NI" -msgstr "" - -#: glances/plugins/glances_processlist.py:381 -msgid "S" -msgstr "" - -#: glances/plugins/glances_processlist.py:383 -msgid "TIME+" -msgstr "" - -#: glances/plugins/glances_processlist.py:385 -msgid "IOR/s" -msgstr "" - -#: glances/plugins/glances_processlist.py:387 -msgid "IOW/s" -msgstr "" - -#: glances/plugins/glances_processlist.py:389 -msgid "Command" -msgstr "" - -#: glances/plugins/glances_monitor.py:101 -msgid "RUNNING" -msgstr "" - -#: glances/plugins/glances_monitor.py:101 -msgid "NOT RUNNING" -msgstr "" - -#: glances/plugins/glances_network.py:201 -msgid "NETWORK" -msgstr "" - -#: glances/plugins/glances_network.py:207 -msgid "Rx+Tx" -msgstr "" - -#: glances/plugins/glances_network.py:211 -msgid "Rx" -msgstr "" - -#: glances/plugins/glances_network.py:213 -msgid "Tx" -msgstr "" - -#: glances/plugins/glances_network.py:219 -msgid "Rx+Tx/s" -msgstr "" - -#: glances/plugins/glances_network.py:222 -msgid "Rx/s" -msgstr "" - -#: glances/plugins/glances_network.py:224 -msgid "Tx/s" -msgstr "" - -#: glances/plugins/glances_alert.py:71 -msgid "No warning or critical alert detected" -msgstr "" - -#: glances/plugins/glances_alert.py:75 -msgid "Warning or critical alerts" -msgstr "" - -#: glances/plugins/glances_alert.py:79 -#, python-brace-format -msgid " (lasts {0} entries)" -msgstr "" - -#: glances/plugins/glances_alert.py:81 -msgid " (one entry)" -msgstr "" - -#: glances/plugins/glances_alert.py:95 -msgid " (ongoing)" -msgstr "" - -#: glances/plugins/glances_alert.py:101 -#, python-brace-format -msgid "{0} on {1}" -msgstr "" - -#: glances/plugins/glances_alert.py:110 -#, python-brace-format -msgid " (Min:{0:.1f} Mean:{1:.1f} Max:{2:.1f})" -msgstr "" - -#: glances/plugins/glances_system.py:158 -msgid "Connected to " -msgstr "" - -#: glances/plugins/glances_system.py:161 -msgid "SNMP from " -msgstr "" - -#: glances/plugins/glances_system.py:164 -msgid "Disconnected from " -msgstr "" - -#: glances/plugins/glances_mem.py:171 -msgid "MEM" -msgstr "" - -#: glances/plugins/glances_mem.py:178 -msgid "active:" -msgstr "" - -#: glances/plugins/glances_mem.py:191 -msgid "inactive:" -msgstr "" - -#: glances/plugins/glances_mem.py:205 -msgid "buffers:" -msgstr "" - -#: glances/plugins/glances_mem.py:218 -msgid "cached:" -msgstr "" - -#: glances/plugins/glances_help.py:58 -#, python-brace-format -msgid " with PSutil {0}" -msgstr "" - -#: glances/plugins/glances_help.py:64 -msgid "Configuration file" -msgstr "" - -#: glances/plugins/glances_help.py:77 -msgid "Sort processes automatically" -msgstr "" - -#: glances/plugins/glances_help.py:79 -msgid "Bytes or bits for network I/O" -msgstr "" - -#: glances/plugins/glances_help.py:82 -msgid "Sort processes by CPU%" -msgstr "" - -#: glances/plugins/glances_help.py:84 -msgid "Show/hide alert logs" -msgstr "" - -#: glances/plugins/glances_help.py:87 -msgid "Sort processes by MEM%" -msgstr "" - -#: glances/plugins/glances_help.py:89 -msgid "Delete warning alerts" -msgstr "" - -#: glances/plugins/glances_help.py:92 -msgid "Sort processes by name" -msgstr "" - -#: glances/plugins/glances_help.py:94 -msgid "Delete warning and critical alerts" -msgstr "" - -#: glances/plugins/glances_help.py:97 -msgid "Sort processes by I/O rate" -msgstr "" - -#: glances/plugins/glances_help.py:99 -msgid "Global CPU or per-CPU stats" -msgstr "" - -#: glances/plugins/glances_help.py:102 -msgid "Sort processes by CPU times" -msgstr "" - -#: glances/plugins/glances_help.py:104 -msgid "Show/hide this help screen" -msgstr "" - -#: glances/plugins/glances_help.py:107 -msgid "Show/hide disk I/O stats" -msgstr "" - -#: glances/plugins/glances_help.py:109 -msgid "View network I/O as combination" -msgstr "" - -#: glances/plugins/glances_help.py:112 -msgid "Show/hide filesystem stats" -msgstr "" - -#: glances/plugins/glances_help.py:114 -msgid "View cumulative network I/O" -msgstr "" - -#: glances/plugins/glances_help.py:117 -msgid "Show/hide network stats" -msgstr "" - -#: glances/plugins/glances_help.py:119 -msgid "Show filesystem free space" -msgstr "" - -#: glances/plugins/glances_help.py:122 -msgid "Show/hide sensors stats" -msgstr "" - -#: glances/plugins/glances_help.py:124 -msgid "Generate graphs for current history" -msgstr "" - -#: glances/plugins/glances_help.py:127 -msgid "Show/hide left sidebar" -msgstr "" - -#: glances/plugins/glances_help.py:129 glances/outputs/glances_curses.py:550 -msgid "Reset history" -msgstr "" - -#: glances/plugins/glances_help.py:132 -msgid "Enable/disable processes stats" -msgstr "" - -#: glances/plugins/glances_help.py:134 -msgid "Quit (Esc and Ctrl-C also work)" -msgstr "" - -#: glances/plugins/glances_help.py:137 -msgid "Enable/disable top extended stats" -msgstr "" - -#: glances/plugins/glances_help.py:140 -msgid "Enable/disable short processes name" -msgstr "" - -#: glances/plugins/glances_help.py:145 -msgid "Edit the process filter pattern" -msgstr "" - -#: glances/plugins/glances_load.py:127 glances/outputs/glances_curses.py:1011 -msgid "LOAD" -msgstr "" - -#: glances/plugins/glances_load.py:131 -#, python-brace-format -msgid "{0:d}-core" -msgstr "" - -#: glances/plugins/glances_load.py:136 -msgid "1 min:" -msgstr "" - -#: glances/plugins/glances_load.py:143 -msgid "5 min:" -msgstr "" - -#: glances/plugins/glances_load.py:151 -msgid "15 min:" -msgstr "" - -#: glances/plugins/glances_cpu.py:141 -msgid "CPU" -msgstr "" - -#: glances/plugins/glances_cpu.py:151 -msgid "nice:" -msgstr "" - -#: glances/plugins/glances_cpu.py:170 -msgid "irq:" -msgstr "" - -#: glances/plugins/glances_cpu.py:183 -msgid "core:" -msgstr "" - -#: glances/plugins/glances_cpu.py:189 -msgid "iowait:" -msgstr "" - -#: glances/plugins/glances_cpu.py:203 -msgid "steal:" -msgstr "" - -#: glances/outputs/glances_curses.py:546 -#, python-format -msgid "" -"Generate graphs history in %s\n" -"Please wait..." -msgstr "" - -#: glances/outputs/glances_curses.py:548 -#, python-format -msgid "" -"Generate graphs history in %s\n" -"Done: %s graphs generated" -msgstr "" - -#: glances/outputs/glances_curses.py:557 -msgid "" -"History disabled\n" -"Enable it using --enable-history" -msgstr "" - -#: glances/outputs/glances_curses.py:560 -msgid "" -"History disabled\n" -"Please install MatPlotLib" -msgstr "" - -#: glances/outputs/glances_curses.py:567 -msgid "Process filter pattern: " -msgstr "" - -#: glances/outputs/glances_curses.py:573 -msgid "Process filter only available in standalone mode" -msgstr "" - -#: glances/outputs/glances_curses.py:984 -msgid "Glances is scanning your network (please wait)..." -msgstr "" - -#: glances/outputs/glances_curses.py:987 -msgid "No Glances servers available" -msgstr "" - -#: glances/outputs/glances_curses.py:989 -msgid "One Glances server available" -msgstr "" - -#: glances/outputs/glances_curses.py:991 -#, python-format -msgid "%d Glances servers available" -msgstr "" - -#: glances/outputs/glances_curses.py:994 -msgid "(auto discover is disabled)" -msgstr "" - -#: glances/outputs/glances_curses.py:1009 -msgid "Name" -msgstr "" - -#: glances/outputs/glances_curses.py:1014 -msgid "STATUS" -msgstr "" - -#: glances/outputs/glances_curses.py:1015 -msgid "IP" -msgstr "" - -#: glances/outputs/glances_curses.py:1017 -msgid "OS" -msgstr "" - -#: glances/outputs/glances_bottle.py:34 -msgid "Install it using pip: # pip install bottle" -msgstr "" - -#: glances/outputs/glances_bottle.py:104 -#, python-brace-format -msgid "Glances web server started on http://{0}:{1}/" -msgstr "" - -#: glances/core/glances_password.py:119 -msgid "Password: " -msgstr "" - -#: glances/core/glances_password.py:123 -msgid "Password (confirm): " -msgstr "" - -#: glances/core/glances_password.py:137 -msgid "Do you want to save the password? [Yes/No]: " -msgstr "" - -#: glances/core/glances_password.py:138 -msgid "Y" -msgstr "" - -#: glances/core/glances_monitor_list.py:146 -msgid "Error: " -msgstr "" - -#: glances/core/glances_monitor_list.py:148 -msgid "Cannot execute command" -msgstr "" - -#: glances/core/glances_client_browser.py:158 -#, python-format -msgid "Connect to %s:%s" -msgstr "" - -#: glances/core/glances_client_browser.py:164 -#, python-format -msgid "Password needed for %s: " -msgstr "" - -#: glances/core/glances_client_browser.py:187 -#, python-format -msgid "Sorry, cannot connect to %s (see log file for additional information)" -msgstr "" - -#: glances/core/glances_client.py:116 -msgid "Trying fallback to SNMP..." -msgstr "" - -#: glances/core/glances_main.py:65 -msgid "Enable debug mode" -msgstr "" - -#: glances/core/glances_main.py:67 -msgid "path to the configuration file" -msgstr "" - -#: glances/core/glances_main.py:70 -msgid "disable network module" -msgstr "" - -#: glances/core/glances_main.py:72 -msgid "disable disk I/O module" -msgstr "" - -#: glances/core/glances_main.py:74 -msgid "disable filesystem module" -msgstr "" - -#: glances/core/glances_main.py:76 -msgid "disable sensors module" -msgstr "" - -#: glances/core/glances_main.py:78 -msgid "disable network, disk io, FS and sensors modules" -msgstr "" - -#: glances/core/glances_main.py:80 -msgid "disable process module" -msgstr "" - -#: glances/core/glances_main.py:82 -msgid "disable log module" -msgstr "" - -#: glances/core/glances_main.py:84 -msgid "disable bold mode in the terminal" -msgstr "" - -#: glances/core/glances_main.py:86 -msgid "enable extended stats on top process" -msgstr "" - -#: glances/core/glances_main.py:88 -msgid "enable the history mode" -msgstr "" - -#: glances/core/glances_main.py:90 -msgid "Set the export path for graph history" -msgstr "" - -#: glances/core/glances_main.py:93 -msgid "export stats to a CSV file" -msgstr "" - -#: glances/core/glances_main.py:96 -msgid "connect to a Glances server by IPv4/IPv6 address or hostname" -msgstr "" - -#: glances/core/glances_main.py:98 -msgid "run Glances in server mode" -msgstr "" - -#: glances/core/glances_main.py:100 -msgid "start the client browser (list of servers)" -msgstr "" - -#: glances/core/glances_main.py:102 -msgid "disable autodiscover feature" -msgstr "" - -#: glances/core/glances_main.py:104 -#, python-brace-format -msgid "define the client/server TCP port [default: {0}]" -msgstr "" - -#: glances/core/glances_main.py:106 -msgid "bind server to the given IPv4/IPv6 address or hostname" -msgstr "" - -#: glances/core/glances_main.py:108 -msgid "define password from the command line" -msgstr "" - -#: glances/core/glances_main.py:110 -msgid "define a client/server password from the prompt or file" -msgstr "" - -#: glances/core/glances_main.py:112 -msgid "SNMP community" -msgstr "" - -#: glances/core/glances_main.py:114 -msgid "SNMP port" -msgstr "" - -#: glances/core/glances_main.py:116 -msgid "SNMP version (1, 2c or 3)" -msgstr "" - -#: glances/core/glances_main.py:118 -msgid "SNMP username (only for SNMPv3)" -msgstr "" - -#: glances/core/glances_main.py:120 -msgid "SNMP authentication key (only for SNMPv3)" -msgstr "" - -#: glances/core/glances_main.py:122 -msgid "force SNMP mode" -msgstr "" - -#: glances/core/glances_main.py:124 -#, python-brace-format -msgid "set refresh time in seconds [default: {0} sec]" -msgstr "" - -#: glances/core/glances_main.py:126 -msgid "run Glances in web server mode" -msgstr "" - -#: glances/core/glances_main.py:129 -msgid "set the process filter pattern (regular expression)" -msgstr "" - -#: glances/core/glances_main.py:131 -msgid "force short name for processes name" -msgstr "" - -#: glances/core/glances_main.py:134 -msgid "hide kernel threads in process list" -msgstr "" - -#: glances/core/glances_main.py:136 -msgid "display processes as a tree" -msgstr "" - -#: glances/core/glances_main.py:138 -msgid "display network rate in byte per second" -msgstr "" - -#: glances/core/glances_main.py:140 -msgid "start Glances in per CPU mode" -msgstr "" - -#: glances/core/glances_main.py:142 -msgid "display FS free space instead of used" -msgstr "" - -#: glances/core/glances_main.py:144 -msgid "optimize display for white background" -msgstr "" - -#: glances/core/glances_main.py:188 -msgid "Define the password for the Glances server" -msgstr "" - -#: glances/core/glances_main.py:192 -msgid "Enter the Glances server password" -msgstr "" diff --git a/man/glances.1 b/man/glances.1 index 3a717659..a17b9ae9 100644 --- a/man/glances.1 +++ b/man/glances.1 @@ -1,4 +1,4 @@ -.TH glances 1 "January, 2015" "version 2.3" "USER COMMANDS" +.TH glances 1 "May, 2015" "version 2.4" "USER COMMANDS" .SH NAME glances \- A cross-platform curses-based system monitoring tool .SH SYNOPSIS @@ -7,7 +7,7 @@ glances \- A cross-platform curses-based system monitoring tool .SH DESCRIPTION Glances is a free (LGPL) cross-platform curses-based system monitoring tool which aims to present a maximum of information in a minimum of space, ideally to fit in -a classical 80x24 terminal or higher to have additionnal information. It can adapt +a classical 80x24 terminal or higher to have additional information. It can adapt dynamically the displayed information depending on the terminal size. .PP Glances can also work in client/server mode. Remote monitoring could be done via @@ -26,16 +26,16 @@ show this help message and exit show program's version number and exit .TP .B \-d, \-\-debug -Enable debug mode (log file is /tmp/glances.log) +enable debug mode (log file is /tmp/glances.log) .TP .B \-C CONF_FILE, \-\-config CONF_FILE path to the configuration file .TP -.B \-b, \-\-byte -display network rate in byte per second [default: bit per second] +.B \-\-disable-network +disable network module .TP -.B \-\-disable-bold -disable bold mode in the terminal +.B \-\-disable-ip +disable IP module .TP .B \-\-disable-diskio disable disk I/O module @@ -43,14 +43,20 @@ disable disk I/O module .B \-\-disable-fs disable file system module .TP -.B \-\-disable-network -disable network module -.TP .B \-\-disable-sensors disable sensors module .TP +.B \-\-disable-hddtemp +disable HDDTemp module +.TP +.B \-\-disable-raid +disable RAID module +.TP +.B \-\-disable-docker +disable Docker module +.TP .B \-\-disable-left-sidebar -disable network, disk IO, FS and sensors modules +disable network, disk I/O, file system and sensors modules .TP .B \-\-disable-process disable process module @@ -58,23 +64,35 @@ disable process module .B \-\-disable-log disable log module .TP +.B \-\-disable-quicklook +disable quick look module +.TP +.B \-\-disable-bold +disable bold mode in the terminal +.TP .B \-\-enable-process-extended enable extended stats on top process .TP .B \-\-enable-history -enable the history mode +enable the history mode (matplotlib needed) .TP -B \-\-path-history PATH_HISTORY +.B \-\-path-history PATH_HISTORY set the export path for graph history .TP -.B \-\-export-csv CSV_FILE +.B \-\-export-csv EXPORT_CSV export stats to a CSV file .TP .B \-\-export-influxdb -export stats to an InfluxDB server +export stats to an InfluxDB server (influxdb needed) .TP .B \-\-export-statsd -export stats to a Statsd server +export stats to a StatsD server (statsd needed) +.TP +.B \-\-export-rabbitmq +export stats to a RabbitMQ server (pika needed) +.TP +.B \-c CLIENT, \-\-client CLIENT +connect to a Glances server by IPv4/IPv6 address or hostname .TP .B \-s, \-\-server run Glances in server mode @@ -85,18 +103,15 @@ start the client browser (display list of servers) .B \-\-disable-autodiscover disable autodiscover feature .TP -.B \-c CLIENT, \-\-client CLIENT -connect to a Glances server by IPv4/IPv6 address or hostname -.TP .B \-p PORT, \-\-port PORT define the client/server TCP port [default: 61209] .TP -.B \-\-password -define a client/server password from the prompt or file -.TP .B \-B BIND_ADDRESS, \-\-bind BIND_ADDRESS bind server to the given IPv4/IPv6 address or hostname .TP +.B \-\-password +define a client/server password +.TP .B \-\-snmp-community SNMP_COMMUNITY SNMP community .TP @@ -113,25 +128,40 @@ SNMP username (only for SNMPv3) SNMP authentication key (only for SNMPv3) .TP .B \-\-snmp-force -Force the SNMP mode (do not try Glances server) +force the SNMP mode (do not try Glances server) .TP .B \-t TIME, \-\-time TIME set refresh time in seconds [default: 3 sec] .TP .B \-w, \-\-webserver -run Glances in Web server mode +run Glances in web server mode (bottle needed) +.TP +.B \-q, \-\-quiet +run Glances in quiet mode (nothing is displayed) +.TP +.B \-f PROCESS_FILTER, \-\-process\-filter PROCESS_FILTER +set the process filter pattern (regular expression) +.TP +.B \-\-process-short-name +force short name for processes name +.TP +.B \-\-hide-kernel-threads +hide kernel threads in process list +.TP +.B \-\-tree +display processes as a tree +.TP +.B \-b, \-\-byte +display network rate in byte per second [default: bit per second] .TP .B \-1, \-\-percpu start Glances in per CPU mode .TP -.B \-1, \-\-process-short-name -Force short name for processes name +.B \-\-fs-free-space +display file system free space instead of used .TP -.B \-1, \-\-fs-free-space -Display FS free space instead of used -.TP -.B \-1, \-\-theme-white -Optimize display for white background +.B \-\-theme-white +optimize display colors for white background .SH INTERACTIVE COMMANDS You can use the following keys while in Glances: .TP @@ -155,6 +185,10 @@ Enable/disable top extended stats .TP .B f Show/hide file system stats +.TP +.B F +Switch between file system used and free space +.TP .B g Generate graphs for current history .TP @@ -185,13 +219,16 @@ Reset history .B s Show/hide sensors stats .TP -.B T +.B t Sort process by CPU times (TIME+) .TP -.B t +.B T View network I/O as combination .TP .B u +Sort processes by USER +.TP +.B U View cumulative network I/O .TP .B w @@ -208,11 +245,45 @@ Show/hide processes list (for low CPU consumption) .TP .B 1 Switch between global CPU and per-CPU stats +.TP +.B 2 +Enable/disable left sidebar +.TP +.B 3 +Enable/disable the quick look module +.TP +.B / +Switch between short name/command line (processes name) .SH EXAMPLES .TP -Refresh information every 5 seconds: -.B glances -\-t 5 +Monitor local machine (standalone mode): +.B $ glances +.PP +Monitor local machine with the Web interface (Web UI): +.B $ glances -w +.PP +Glances web server started on http://0.0.0.0:61208/ +.PP +Monitor local machine and export stats to a CSV file (standalone mode): +.B $ glances --export-csv +.PP +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 +Connect Glances to a Glances server (client mode): +.B $ glances -c +.PP +Connect Glances to a Glances server and export stats to a StatsD server (client mode): +.B $ glances -c --export-statsd +.PP +Start the client browser (browser mode): +.B $ glances --browser .PP .SH EXIT STATUS Glances returns a zero exit status if it succeeds to print/grab information. diff --git a/requirements.txt b/requirements.txt index 7a795604..914d2457 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -psutil==2.2.0 +psutil==2.2.1 diff --git a/setup.py b/setup.py index a7fe0a5a..f046b2b9 100755 --- a/setup.py +++ b/setup.py @@ -1,12 +1,14 @@ #!/usr/bin/env python import glob -import os 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(): @@ -17,27 +19,6 @@ 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])) - return data_files @@ -45,20 +26,20 @@ def get_requires(): requires = ['psutil>=2.0.0'] if sys.platform.startswith('win'): requires += ['colorconsole'] - if sys.version_info < (2, 7): - requires += ['argparse'] + if sys.version_info == (2, 6): + requires += ['argparse', 'logutils'] return requires setup( name='Glances', - version='2.3', + version='2.4', description="A cross-platform curses-based monitoring tool", long_description=open('README.rst').read(), author='Nicolas Hennion', author_email='nicolas@nicolargo.com', url='https://github.com/nicolargo/glances', - # download_url='https://s3.amazonaws.com/glances/glances-2.3.tar.gz', + # download_url='https://s3.amazonaws.com/glances/glances-2.4.tar.gz', license="LGPL", keywords="cli curses monitoring system", install_requires=get_requires(), @@ -68,10 +49,11 @@ setup( 'BATINFO': ['batinfo'], 'SNMP': ['pysnmp'], 'CHART': ['matplotlib'], - 'BROWSER': ['zeroconf>=0.16', 'netifaces'], + 'BROWSER': ['zeroconf>=0.17'], + 'IP': ['netifaces'], 'RAID': ['pymdstat'], 'DOCKER': ['docker-py'], - 'EXPORT': ['influxdb', 'statsd'], + 'EXPORT': ['influxdb>=1.0.0', 'statsd', 'pika'], 'ACTION': ['pystache'] }, packages=['glances'], diff --git a/sonar-project.properties b/sonar-project.properties index 226c9e76..726f5926 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,7 +1,7 @@ # Required metadata sonar.projectKey=glances sonar.projectName=Glances -sonar.projectVersion=2.3_beta +sonar.projectVersion=2.4_beta # Path to the parent source code directory. # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. @@ -17,4 +17,4 @@ sonar.language=py sonar.sourceEncoding=UTF-8 # Additional parameters -#sonar.my.property=value \ No newline at end of file +#sonar.my.property=value diff --git a/unitest-restful.py b/unitest-restful.py index 55fb5292..efd7e572 100755 --- a/unitest-restful.py +++ b/unitest-restful.py @@ -20,8 +20,6 @@ """Glances unitary tests suite for the RESTFul API.""" -import gettext -import locale import sys import time import unittest @@ -52,11 +50,6 @@ if not is_linux: else: print('Unitary tests for {0} {1}'.format(appname, version)) -# Import local settings -from glances.core.glances_globals import gettext_domain, locale_dir -locale.setlocale(locale.LC_ALL, '') -gettext.install(gettext_domain, locale_dir) - # Init Glances core from glances.core.glances_main import GlancesMain core = GlancesMain() @@ -91,7 +84,7 @@ class TestGlances(unittest.TestCase): args = shlex.split(cmdline) pid = subprocess.Popen(args) print("Please wait...") - time.sleep(1) + time.sleep(3) self.assertTrue(pid is not None) diff --git a/unitest-xmlrpc.py b/unitest-xmlrpc.py index 4e7a86bb..a6ea3083 100755 --- a/unitest-xmlrpc.py +++ b/unitest-xmlrpc.py @@ -20,8 +20,6 @@ """Glances unitary tests suite for the XML/RPC API.""" -import gettext -import locale import sys import time import unittest @@ -56,11 +54,6 @@ if not is_linux: else: print('Unitary tests for {0} {1}'.format(appname, version)) -# Import local settings -from glances.core.glances_globals import gettext_domain, locale_dir -locale.setlocale(locale.LC_ALL, '') -gettext.install(gettext_domain, locale_dir) - # Init Glances core from glances.core.glances_main import GlancesMain core = GlancesMain() diff --git a/unitest.py b/unitest.py index d01693c7..f87d31b0 100755 --- a/unitest.py +++ b/unitest.py @@ -20,8 +20,6 @@ """Glances unitary tests suite.""" -import gettext -import locale import sys import time import unittest @@ -42,11 +40,6 @@ if not is_linux: else: print('Unitary tests for {0} {1}'.format(appname, version)) -# Import local settings -from glances.core.glances_globals import gettext_domain, locale_dir -locale.setlocale(locale.LC_ALL, '') -gettext.install(gettext_domain, locale_dir) - # Init Glances core from glances.core.glances_main import GlancesMain core = GlancesMain() @@ -78,14 +71,14 @@ class TestGlances(unittest.TestCase): print('INFO: [TEST_000] Test the stats update function') try: stats.update() - except: - print('ERROR: Stats update failed') + except Exception as e: + print('ERROR: Stats update failed ({})'.format(e)) self.assertTrue(False) time.sleep(1) try: stats.update() - except: - print('ERROR: Stats update failed') + except Exception as e: + print('ERROR: Stats update failed ({})'.format(e)) self.assertTrue(False) self.assertTrue(True)