mirror of
https://github.com/nicolargo/glances.git
synced 2024-12-29 04:04:03 +03:00
Add test to solve issue #45
This commit is contained in:
parent
8737e3764d
commit
8bc4a4d527
256
README.md
Normal file
256
README.md
Normal file
@ -0,0 +1,256 @@
|
||||
[![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=nicolargo&url=https://github.com/nicolargo/glances&title=Glances&language=&tags=github&category=software)
|
||||
|
||||
=============================
|
||||
Glances -- Eye on your system
|
||||
=============================
|
||||
|
||||
## Description
|
||||
|
||||
Glances is a CLI curses based monitoring tool for GNU/Linux and BSD OS.
|
||||
|
||||
Glances uses the PsUtil library to get information from your system.
|
||||
|
||||
It is developed in Python.
|
||||
|
||||
![screenshot](https://github.com/nicolargo/glances/raw/master/screenshot.png)
|
||||
|
||||
## Installation
|
||||
|
||||
### From package manager (very easy way)
|
||||
|
||||
Packages exist for Arch, Fedora, Redhat, FreeBSD...
|
||||
|
||||
### From PPA (easy way for Ubuntu/Mint...)
|
||||
|
||||
Arnaud Hartmann (thanks to him !) maintains a PPA with the latest Glances version:
|
||||
|
||||
To install the PPA just enter:
|
||||
|
||||
$ sudo add-apt-repository ppa:arnaud-hartmann/glances-dev
|
||||
$ sudo apt-get update
|
||||
|
||||
Then install Glances:
|
||||
|
||||
$ sudo apt-get install glances
|
||||
|
||||
### From PyPi (easy way)
|
||||
|
||||
PyPi is an official Python package manager.
|
||||
|
||||
You first need to install pypi on your system. For exemple on Debian/Ubuntu:
|
||||
|
||||
$ sudo apt-get install python-pip
|
||||
|
||||
Then install the latest Glances version:
|
||||
|
||||
$ sudo pip install glances
|
||||
|
||||
### From source
|
||||
|
||||
Get the latest version:
|
||||
|
||||
$ wget https://github.com/downloads/nicolargo/glances/glances-1.4.tar.gz
|
||||
|
||||
Glances use a standard GNU style installer:
|
||||
|
||||
$ tar zxvf glances-1.4.tar.gz
|
||||
$ cd glances-1.4
|
||||
$ sudo python setup.py install
|
||||
|
||||
Pre-requisites:
|
||||
|
||||
* Python 2.6+ (not tested with Python 3+)
|
||||
|
||||
## Running
|
||||
|
||||
Easy way (that's all folks !):
|
||||
|
||||
$ glances.py
|
||||
|
||||
## User guide
|
||||
|
||||
By default, stats are refreshed every second, to change this setting, you can
|
||||
use the -t option. For exemple to set the refrech rate to 5 seconds:
|
||||
|
||||
$ glances.py -t 5
|
||||
|
||||
Importants stats are colored:
|
||||
|
||||
* GREEN: stat counter is "OK"
|
||||
* BLUE: stat counter is "CAREFUL"
|
||||
* MAGENTA: stat counter is "WARNING"
|
||||
* RED: stat counter is "CRITICAL"
|
||||
|
||||
When Glances is running, you can press:
|
||||
|
||||
* 'h' to display an help message whith the keys you can press
|
||||
* 'a' to set the automatic mode. The processes are sorted automatically
|
||||
|
||||
If CPU > 70%, sort by process "CPU consumption"
|
||||
|
||||
If MEM > 70%, sort by process "memory size"
|
||||
|
||||
* 'c' to sort the processes list by CPU consumption
|
||||
* 'd' Disable or enable the disk IO stats
|
||||
* 'f' Disable or enable the file system stats
|
||||
* 'l' Disable or enable the logs
|
||||
* 'm' to sort the processes list by process size
|
||||
* 'n' Disable or enable the network interfaces stats
|
||||
* 'q' Exit
|
||||
|
||||
### Header
|
||||
|
||||
![screenshot](https://github.com/nicolargo/glances/raw/master/doc/header.png)
|
||||
|
||||
The header shows the Glances version, the host name and the operating
|
||||
system name, version and architecture.
|
||||
|
||||
### CPU
|
||||
|
||||
![screenshot](https://github.com/nicolargo/glances/raw/master/doc/cpu.png)
|
||||
|
||||
The CPU states are shown as a percentage and for the configured refresh
|
||||
time.
|
||||
|
||||
If user|kernel|nice CPU is < 50%, then status is set to "OK".
|
||||
|
||||
If user|kernel|nice CPU is > 50%, then status is set to "CAREFUL".
|
||||
|
||||
If user|kernel|nice CPU is > 70%, then status is set to "WARNING".
|
||||
|
||||
If user|kernel|nice CPU is > 90%, then status is set to "CRITICAL".
|
||||
|
||||
### Load
|
||||
|
||||
![screenshot](https://github.com/nicolargo/glances/raw/master/doc/load.png)
|
||||
|
||||
On the Nosheep blog, Zach defines the average load: "In short it is the
|
||||
average sum of the number of processes waiting in the run-queue plus the
|
||||
number currently executing over 1, 5, and 15 minute time periods."
|
||||
|
||||
Glances gets the number of CPU cores to adapt the alerts. With Glances,
|
||||
alerts on average load are only set on 5 and 15 mins.
|
||||
|
||||
If average load is < O.7*Core, then status is set to "OK".
|
||||
|
||||
If average load is > O.7*Core, then status is set to "CAREFUL".
|
||||
|
||||
If average load is > 1*Core, then status is set to "WARNING".
|
||||
|
||||
If average load is > 5*Core, then status is set to "CRITICAL".
|
||||
|
||||
### Memory
|
||||
|
||||
![screenshot](https://github.com/nicolargo/glances/raw/master/doc/mem.png)
|
||||
|
||||
Glances uses tree columns: memory (RAM), swap and "real".
|
||||
|
||||
Real used memory is: used - cache.
|
||||
|
||||
Real free memory is: free + cache.
|
||||
|
||||
With Glances, alerts are only set for on used swap and real memory.
|
||||
|
||||
If memory is < 50%, then status is set to "OK".
|
||||
|
||||
If memory is > 50%, then status is set to "CAREFUL".
|
||||
|
||||
If memory is > 70%, then status is set to "WARNING".
|
||||
|
||||
If memory is > 90%, then status is set to "CRITICAL".
|
||||
|
||||
### Network bit rate
|
||||
|
||||
![screenshot](https://github.com/nicolargo/glances/raw/master/doc/network.png)
|
||||
|
||||
Glances display the network interface bit rate. The unit is adapted
|
||||
dynamicaly (bits per second, Kbits per second, Mbits per second...).
|
||||
|
||||
Alerts are set only if the network interface maximum speed is available.
|
||||
|
||||
If bitrate is < 50%, then status is set to "OK".
|
||||
|
||||
If bitrate is > 50%, then status is set to "CAREFUL".
|
||||
|
||||
If bitrate is > 70%, then status is set to "WARNING".
|
||||
|
||||
If bitrate is > 90%, then status is set to "CRITICAL".
|
||||
|
||||
For exemple, on a 100 Mbps Ethernet interface, the warning status is set
|
||||
if the bit rate is higher than 70 Mbps.
|
||||
|
||||
### Disk I/O
|
||||
|
||||
![screenshot](https://github.com/nicolargo/glances/raw/master/doc/diskio.png)
|
||||
|
||||
Glances display the disk I/O throughput. The unit is adapted dynamicaly
|
||||
(bytes per second, Kbytes per second, Mbytes per second...).
|
||||
|
||||
There is no alert on this information.
|
||||
|
||||
### Filesystem
|
||||
|
||||
![screenshot](https://github.com/nicolargo/glances/raw/master/doc/fs.png)
|
||||
|
||||
Glances display the total and used filesytem disk space. The unit is
|
||||
adapted dynamicaly (bytes per second, Kbytes per second, Mbytes per
|
||||
second...).
|
||||
|
||||
Alerts are set for used disk space:
|
||||
|
||||
If disk used is < 50%, then status is set to "OK".
|
||||
|
||||
If disk used is > 50%, then status is set to "CAREFUL".
|
||||
|
||||
If disk used is > 70%, then status is set to "WARNING".
|
||||
|
||||
If disk used is > 90%, then status is set to "CRITICAL".
|
||||
|
||||
### Processes
|
||||
|
||||
![screenshot](https://github.com/nicolargo/glances/raw/master/doc/processlist.png)
|
||||
|
||||
Glances displays a summary and a list of processes.
|
||||
|
||||
By default (or if you hit the 'a' key) the process list is automaticaly
|
||||
sorted by CPU of memory consumption.
|
||||
|
||||
The number of processes in the list is adapted to the screen size.
|
||||
|
||||
### Logs
|
||||
|
||||
![screenshot](https://github.com/nicolargo/glances/raw/master/doc/logs.png)
|
||||
|
||||
A logs list is displayed in the bottom of the screen if (an only if):
|
||||
|
||||
* at least one WARNING or CRITICAL alert was occured.
|
||||
* space is available in the bottom of the console/terminal
|
||||
|
||||
There is one line per alert with the following information:
|
||||
|
||||
* start date
|
||||
* end date
|
||||
* alert name
|
||||
* (min/avg/max) values
|
||||
|
||||
### Footer
|
||||
|
||||
![screenshot](https://github.com/nicolargo/glances/raw/master/doc/footer.png)
|
||||
|
||||
Glances displays a caption and the current time/date.
|
||||
|
||||
## Localisation
|
||||
|
||||
To generate french locale execute as root or sudo :
|
||||
i18n_francais_generate.sh
|
||||
|
||||
To generate spanish locale execute as root or sudo :
|
||||
i18n_espanol_generate.sh
|
||||
|
||||
## Todo
|
||||
|
||||
You are welcome to contribute to this software.
|
||||
|
||||
* Packaging for Debian, Ubuntu, BSD...
|
||||
* Check the needed Python library in the configure.ac
|
||||
* Add file system stats when the python-statgrab is corrected
|
@ -30,6 +30,18 @@ Colors table
|
||||
.bgmem { background: transparent; }
|
||||
.fgmem { color: #3C8AAD; }
|
||||
|
||||
.bgnet { background: transparent; }
|
||||
.fgnet { color: #3C8AAD; }
|
||||
|
||||
.bgdiskio { background: transparent; }
|
||||
.fgdiskio { color: #3C8AAD; }
|
||||
|
||||
.bgfs { background: transparent; }
|
||||
.fgfs { color: #3C8AAD; }
|
||||
|
||||
.bgproc { background: transparent; }
|
||||
.fgproc { color: #3C8AAD; }
|
||||
|
||||
.bgcdefault { background: transparent; }
|
||||
.fgcdefault { color: #FFFFFF; }
|
||||
.bgcok { background: #60AC39; }
|
||||
@ -65,7 +77,7 @@ table{
|
||||
}
|
||||
|
||||
thead th{
|
||||
padding:10px;
|
||||
padding:5px;
|
||||
border:1px solid #3C8AAD;
|
||||
-webkit-border-top-left-radius:5px;
|
||||
-webkit-border-top-right-radius:5px;
|
||||
@ -89,8 +101,8 @@ tfoot th{
|
||||
}
|
||||
|
||||
tbody td{
|
||||
width: 80px;
|
||||
padding:10px;
|
||||
width:80px;
|
||||
padding:5px;
|
||||
text-align:center;
|
||||
border:1px solid #3C8AAD;
|
||||
-moz-border-radius:2px;
|
||||
@ -98,11 +110,25 @@ tbody td{
|
||||
border-radius:2px;
|
||||
}
|
||||
|
||||
#item{
|
||||
width:60px;
|
||||
border:none;
|
||||
text-align:right;
|
||||
color: #8cf;
|
||||
}
|
||||
|
||||
#command{
|
||||
width:240px;
|
||||
font-size:11px;
|
||||
text-align:left;
|
||||
color: #8cf;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
|
||||
header {
|
||||
text-align: center;
|
||||
margin-bottom: 50px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
/* Main */
|
||||
@ -111,13 +137,28 @@ header {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* First line stats: CLM (CPU, LOAD, MEM) */
|
||||
|
||||
#clm {
|
||||
#firstline, #secondline {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#cpu, #load, #mem {
|
||||
#secondline {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#sideleft {
|
||||
width: 310px;
|
||||
float: left;
|
||||
margin-right: 25px;
|
||||
}
|
||||
|
||||
#sideright {
|
||||
width: 550px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#cpu, #load, #mem, #net, #diskio, #fs {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
@ -126,5 +167,13 @@ header {
|
||||
margin-right: 50px;
|
||||
}
|
||||
|
||||
#diskio, #fs {
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
#proclist {
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
|
||||
/* Footer */
|
||||
|
@ -22,7 +22,7 @@
|
||||
from __future__ import generators
|
||||
|
||||
__appname__ = 'glances'
|
||||
__version__ = "1.4b15"
|
||||
__version__ = "1.4b16"
|
||||
__author__ = "Nicolas Hennion <nicolas@nicolargo.com>"
|
||||
__licence__ = "LGPL"
|
||||
|
||||
@ -371,12 +371,46 @@ class glancesStats():
|
||||
self.cputime_old
|
||||
except:
|
||||
self.cputime_old = psutil.cpu_times()
|
||||
self.cputime_total_old = self.cputime_old.user+self.cputime_old.nice+self.cputime_old.system+self.cputime_old.idle+self.cputime_old.iowait+self.cputime_old.irq+self.cputime_old.softirq
|
||||
self.cputime_total_old = self.cputime_old.user+self.cputime_old.system+self.cputime_old.idle
|
||||
# Only available on some OS
|
||||
try:
|
||||
self.cputime_total_old += self.cputime_old.nice
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
self.cputime_total_old += self.cputime_old.iowait
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
self.cputime_total_old += self.cputime_old.irq
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
self.cputime_total_old += self.cputime_old.softirq
|
||||
except:
|
||||
pass
|
||||
self.cpu = {}
|
||||
else:
|
||||
try:
|
||||
self.cputime_new = psutil.cpu_times()
|
||||
self.cputime_total_new = self.cputime_new.user+self.cputime_new.nice+self.cputime_new.system+self.cputime_new.idle+self.cputime_new.iowait+self.cputime_new.irq+self.cputime_new.softirq
|
||||
self.cputime_total_new = self.cputime_new.user+self.cputime_new.system+self.cputime_new.idle
|
||||
# Only available on some OS
|
||||
try:
|
||||
self.cputime_total_new += self.cputime_new.nice
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
self.cputime_total_new += self.cputime_new.iowait
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
self.cputime_total_new += self.cputime_new.irq
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
self.cputime_total_new += self.cputime_new.softirq
|
||||
except:
|
||||
pass
|
||||
percent = 100/(self.cputime_total_new-self.cputime_total_old)
|
||||
self.cpu = { 'kernel': (self.cputime_new.system-self.cputime_old.system)*percent,
|
||||
'user': (self.cputime_new.user-self.cputime_old.user)*percent,
|
||||
@ -1316,7 +1350,7 @@ class glancesHtml():
|
||||
self.__refresh_time = refresh_time
|
||||
|
||||
# Set the templates path
|
||||
environment = jinja2.Environment(loader=jinja2.FileSystemLoader('html'))
|
||||
environment = jinja2.Environment(loader=jinja2.FileSystemLoader('html'), extensions=['jinja2.ext.loopcontrols'])
|
||||
|
||||
# Open the template
|
||||
self.template = environment.get_template('default.html')
|
||||
@ -1413,7 +1447,12 @@ class glancesHtml():
|
||||
load = self.__getLoadColor(stats.getLoad(), stats.getCore()),
|
||||
core = stats.getCore(),
|
||||
mem = self.__getMemColor(stats.getMem()),
|
||||
memswap = self.__getMemSwapColor(stats.getMemSwap()) )
|
||||
memswap = self.__getMemSwapColor(stats.getMemSwap()),
|
||||
net = stats.getNetwork(),
|
||||
diskio = stats.getDiskIO(),
|
||||
fs = stats.getFs(),
|
||||
proccount = stats.getProcessCount(),
|
||||
proclist = stats.getProcessList() )
|
||||
|
||||
# Write data into the file
|
||||
f.write(data)
|
||||
|
@ -17,7 +17,7 @@
|
||||
</header>
|
||||
|
||||
<section id="main">
|
||||
<section id="clm">
|
||||
<section id="firstline">
|
||||
<article id="cpu">
|
||||
{% block cpu %}{% endblock %}
|
||||
</article>
|
||||
@ -28,6 +28,27 @@
|
||||
{% block mem %}{% endblock %}
|
||||
</article>
|
||||
</section>
|
||||
<section id="secondline">
|
||||
<section id="sideleft">
|
||||
<article id="net">
|
||||
{% block net %}{% endblock %}
|
||||
</article>
|
||||
<article id="diskio">
|
||||
{% block diskio %}{% endblock %}
|
||||
</article>
|
||||
<article id="fs">
|
||||
{% block fs %}{% endblock %}
|
||||
</article>
|
||||
</section>
|
||||
<section id="sideright">
|
||||
<article id="proccount">
|
||||
{% block proccount %}{% endblock %}
|
||||
</article>
|
||||
<article id="proclist">
|
||||
{% block proclist %}{% endblock %}
|
||||
</article>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
|
@ -96,3 +96,132 @@
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block net %}
|
||||
{% if net is defined %}
|
||||
<table >
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="bgnet fgnet"></th>
|
||||
<th scope="col" class="bgnet fgnet">Net Rx ↓</th>
|
||||
<th scope="col" class="bgnet fgnet">Net TX ↑</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for interface in net %}
|
||||
<tr>
|
||||
<td id="item">{{ interface.interface_name }}</td>
|
||||
{% if interface.rx == 0 %}
|
||||
<td>0</td>
|
||||
{% else %}
|
||||
<td>{{ (interface.rx*8)|filesizeformat(binary = true)|replace("Bytes", "bps")|replace("Byte", "bps")|replace("iB", "bps") }}</td>
|
||||
{% endif %}
|
||||
{% if interface.tx == 0 %}
|
||||
<td>0</td>
|
||||
{% else %}
|
||||
<td>{{ (interface.tx*8)|filesizeformat(binary = true)|replace("Bytes", "bps")|replace("Byte", "bps")|replace("iB", "bps") }}</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block diskio %}
|
||||
{% if diskio is defined %}
|
||||
<table >
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="bgdiskio fgdiskio"></th>
|
||||
<th scope="col" class="bgdiskio fgdiskio">Disk Write ↓</th>
|
||||
<th scope="col" class="bgdiskio fgdiskio">Disk Read ↑</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for disk in diskio %}
|
||||
<tr>
|
||||
<td id="item">{{ disk.disk_name }}</td>
|
||||
<td>{{ disk.write_bytes|filesizeformat(binary = true) }}</td>
|
||||
<td>{{ disk.read_bytes|filesizeformat(binary = true) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block fs %}
|
||||
{% if fs is defined %}
|
||||
<table >
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="bgdiskio fgdiskio"></th>
|
||||
<th scope="col" class="bgdiskio fgdiskio">FS Size</th>
|
||||
<th scope="col" class="bgdiskio fgdiskio">FS Used</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for mount in fs %}
|
||||
<tr>
|
||||
<td id="item">{{ mount.mnt_point }}</td>
|
||||
<td>{{ mount.size|filesizeformat(binary = true) }}</td>
|
||||
<td>{{ mount.used|filesizeformat(binary = true) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block proccount %}
|
||||
{% if (proccount is defined) %}
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="bgproc fgproc"></th>
|
||||
<th scope="col" class="bgproc fgproc">Total</th>
|
||||
<th scope="col" class="bgproc fgproc">Running</th>
|
||||
<th scope="col" class="bgproc fgproc">Sleep</th>
|
||||
<th scope="col" class="bgproc fgproc">Other</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td id="item">Process</td>
|
||||
<td>{{ proccount.total }}</td>
|
||||
<td>{{ proccount.running }}</td>
|
||||
<td>{{ proccount.sleeping }}</td>
|
||||
<td>{{ proccount.total-proccount.running-proccount.sleeping }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block proclist %}
|
||||
{% if proclist is defined %}
|
||||
<table >
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="bgproc fgproc">CPU %</th>
|
||||
<th scope="col" class="bgproc fgproc">Mem virt.</th>
|
||||
<th scope="col" class="bgproc fgproc">Mem resi.</th>
|
||||
<th scope="col" class="bgproc fgproc">Command</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for proc in proclist %}
|
||||
{% if loop.index > 10 %}
|
||||
{% break %}
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td>{{ proc.cpu_percent }}</td>
|
||||
<td>{{ proc.proc_size|filesizeformat(binary = true) }}</td>
|
||||
<td>{{ proc.proc_resident|filesizeformat(binary = true) }}</td>
|
||||
<td id="command">{{ proc.process_name|truncate(40, killwords=True) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
Loading…
Reference in New Issue
Block a user