summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicolargo <nicolargo@lifebook.(none)>2012-05-01 18:25:11 +0200
committernicolargo <nicolargo@lifebook.(none)>2012-05-01 18:25:11 +0200
commite413c170e9919d59347b3918dfe2192fbb987215 (patch)
tree4bd32e371ac0506f4122f737a036d59c9056cca3
parent0bfbaf2d3c0a52cf651663edbe36f53111d00844 (diff)
Add PID/UID to the processes informations
-rw-r--r--NEWS1
-rw-r--r--[l---------]README.md257
-rw-r--r--glances/css/default.css11
-rwxr-xr-xglances/glances.py121
-rw-r--r--glances/html/default.html4
-rwxr-xr-xsetup.py6
6 files changed, 345 insertions, 55 deletions
diff --git a/NEWS b/NEWS
index 72bf4139..7e6b87ca 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,7 @@ Version 1.4
* No more autotools, use setup.py to install
* Sort by Process name ('p' key)
* Only major stats (CPU, Load and memory) use background colors
+ * Add optionnal (if space is available): PID, UID
* Improve operating system name
* Code is now checked with pep8
diff --git a/README.md b/README.md
index 100b9382..15e9547b 120000..100644
--- a/README.md
+++ b/README.md
@@ -1 +1,256 @@
-README \ No newline at end of file
+[![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
diff --git a/glances/css/default.css b/glances/css/default.css
index 01e219db..6e4811ba 100644
--- a/glances/css/default.css
+++ b/glances/css/default.css
@@ -175,5 +175,14 @@ header {
margin-top: 50px;
}
-
/* Footer */
+
+footer {
+ clear: both;
+ margin: 20px 0px 10px 0px;
+ text-align: center;
+}
+
+footer a {
+ color: white;
+}
diff --git a/glances/glances.py b/glances/glances.py
index 8c2458dc..987139b6 100755
--- a/glances/glances.py
+++ b/glances/glances.py
@@ -22,7 +22,7 @@
from __future__ import generators
__appname__ = 'glances'
-__version__ = "1.4b17"
+__version__ = "1.4b18"
__author__ = "Nicolas Hennion <nicolas@nicolargo.com>"
__licence__ = "LGPL"
@@ -66,7 +66,11 @@ try:
import psutil
except ImportError:
print _('PsUtil library initialization failed, Glances cannot start.')
- print _('On Debian/Ubuntu, you can try (as root):')
+ print
+ print _('On Ubuntu 12.04+, you can try (as root):')
+ print _('# apt-get install python-psutil')
+ print
+ print _('On Debian/Ubuntu(< 12.04), you can try (as root):')
print _('# apt-get install python-dev python-pip')
print _('# pip install psutil')
print
@@ -606,6 +610,8 @@ class glancesStats:
if (psutil_get_cpu_percent_tag):
procstat['cpu_percent'] = \
proc.get_cpu_percent(interval=0)
+ procstat['pid'] = proc.pid
+ procstat['uid'] = proc.username
self.process.append(procstat)
except:
pass
@@ -708,24 +714,22 @@ class glancesScreen:
# Init windows positions
self.term_w = 80
self.term_h = 24
- self.host_x = 0
- self.host_y = 0
self.system_x = 0
- self.system_y = 1
+ self.system_y = 0
self.cpu_x = 0
- self.cpu_y = 3
+ self.cpu_y = 2
self.load_x = 20
- self.load_y = 3
+ self.load_y = 2
self.mem_x = 41
- self.mem_y = 3
+ self.mem_y = 2
self.network_x = 0
- self.network_y = 8
+ self.network_y = 7
self.diskio_x = 0
self.diskio_y = -1
self.fs_x = 0
self.fs_y = -1
self.process_x = 30
- self.process_y = 8
+ self.process_y = 7
self.log_x = 0
self.log_y = -1
self.help_x = 0
@@ -995,8 +999,7 @@ class glancesScreen:
def display(self, stats):
# Display stats
- self.displayHost(stats.getHost())
- self.displaySystem(stats.getSystem())
+ self.displaySystem(stats.getHost(), stats.getSystem())
self.displayCpu(stats.getCpu())
self.displayLoad(stats.getLoad(), stats.getCore())
self.displayMem(stats.getMem(), stats.getMemSwap())
@@ -1038,32 +1041,18 @@ class glancesScreen:
# Wait 100ms...
curses.napms(100)
- def displayHost(self, host):
- # Host information
- if (not host):
- return 0
- screen_x = self.screen.getmaxyx()[1]
- screen_y = self.screen.getmaxyx()[0]
- if ((screen_y > self.host_y)
- and (screen_x > self.host_x + 79)):
- host_msg = _("Glances v") + self.__version + _(" running on ") + \
- host['hostname']
- self.term_window.addnstr(self.host_y, \
- self.host_x + int(screen_x / 2) - \
- len(host_msg) / 2, host_msg, \
- 80, \
- self.title_color if self.hascolors else 0)
-
- def displaySystem(self, system):
+ def displaySystem(self, host, system):
# System information
- if (not system):
+ if (not host or not system):
return 0
screen_x = self.screen.getmaxyx()[1]
screen_y = self.screen.getmaxyx()[0]
if ((screen_y > self.system_y)
and (screen_x > self.system_x + 79)):
- system_msg = system['os_name'] + " " + system['platform'] + " " + \
- system['os_version']
+ system_msg = host['hostname'] + " (" + \
+ system['os_name'] + " " + \
+ system['platform'] + " " + \
+ system['os_version'] + ")"
self.term_window.addnstr(self.system_y, \
self.system_x + int(screen_x / 2) - \
len(system_msg) / 2, \
@@ -1393,7 +1382,12 @@ class glancesScreen:
stats.getProcessCount()['sleeping']), \
8)
# Display the process detail
- if ((screen_y > self.process_y + 7)
+ tag_pid = tag_uid = False
+ if (screen_x > process_x + 55):
+ tag_pid = True
+ if (screen_x > process_x + 64):
+ tag_uid = True
+ if ((screen_y > self.process_y + 8)
and (screen_x > process_x + 49)):
# Processes detail
self.term_window.addnstr(self.process_y + 3, process_x, \
@@ -1406,7 +1400,20 @@ class glancesScreen:
if (self.getProcessSortedBy() == 'proc_size') else 0)
self.term_window.addnstr(self.process_y + 3, process_x + 18, \
_("Mem resi."), 9)
- self.term_window.addnstr(self.process_y + 3, process_x + 30, \
+ process_name_x = 30
+ # If screen space (X) is available then:
+ # 1) Add PID
+ if (tag_pid):
+ self.term_window.addnstr(self.process_y + 3, process_x + process_name_x, \
+ _("PID"), 6 )
+ process_name_x = process_name_x + 8
+ # 2) Add UID
+ if (tag_uid):
+ self.term_window.addnstr(self.process_y + 3, process_x + process_name_x, \
+ _("UID"), 8 )
+ process_name_x = process_name_x + 10
+ # 3) Process name
+ self.term_window.addnstr(self.process_y + 3, process_x + process_name_x, \
_("Process name"), 12, \
curses.A_UNDERLINE \
if (self.getProcessSortedBy() == 'process_name') else 0)
@@ -1418,7 +1425,7 @@ class glancesScreen:
return 6
for processes in range(0, min(screen_y - self.term_h + \
- self.process_y - log_count + 2, len(processlist))):
+ self.process_y - log_count + 4, len(processlist))):
if (psutil_get_cpu_percent_tag):
self.term_window.addnstr(self.process_y + 4 + processes, \
process_x, \
@@ -1436,27 +1443,39 @@ class glancesScreen:
process_x + 18, \
self.__autoUnit(\
processlist[processes]['proc_resident']), 9)
- maxprocessname = screen_x - process_x - 30
- # If screen space is available then display long name
+ # If screen space (X) is available then:
+ # 1) Add PID
+ if (tag_pid):
+ self.term_window.addnstr(self.process_y + 4 + processes, \
+ process_x + 30, \
+ str(processlist[processes]['pid']), 6)
+ # 2) Add UID
+ if (tag_uid):
+ self.term_window.addnstr(self.process_y + 4 + processes, \
+ process_x + 38, \
+ str(processlist[processes]['uid']), 8)
+ # 3) Display long process command line
+ maxprocessname = screen_x - process_x - process_name_x
if ((len(processlist[processes]['proctitle']) > maxprocessname)
or (len(processlist[processes]['proctitle']) == 0)):
processname = processlist[processes]['process_name']
else:
processname = processlist[processes]['proctitle']
self.term_window.addnstr(self.process_y + 4 + processes, \
- process_x + 30, processname, maxprocessname)
+ process_x + process_name_x, processname, maxprocessname)
def displayCaption(self):
# Caption
screen_x = self.screen.getmaxyx()[1]
screen_y = self.screen.getmaxyx()[0]
- if ((screen_x < 80) or (screen_y < 24)):
+ msg = _("Glances ") + __version__
+ if ((screen_x > 79) and (screen_y > 23)):
# Help can only be displayed on a 80x24 console
- return 0
+ msg = msg + " - " + _("Press 'h' for help")
if ((screen_y > self.caption_y)
and (screen_x > self.caption_x + 32)):
self.term_window.addnstr(max(self.caption_y, screen_y - 1), \
- self.caption_x, _("Press 'h' for help"), self.default_color)
+ self.caption_x, msg, self.default_color)
def displayHelp(self):
"""
@@ -1468,7 +1487,7 @@ class glancesScreen:
screen_y = self.screen.getmaxyx()[0]
if ((screen_y > self.help_y + 23)
and (screen_x > self.help_x + 79)):
- # Console 80x24 is mandatory to display teh help message
+ # Console 80x24 is mandatory to display the help message
self.erase()
self.term_window.addnstr(self.help_y, self.help_x, \
@@ -1547,15 +1566,15 @@ class glancesHtml:
This class manages the HTML output
"""
- def __init__(self, htmlfolder="./", refresh_time=1):
+ def __init__(self, htmlfolder="/usr/share", refresh_time=1):
# Global information to display
# Init refresh time
self.__refresh_time = refresh_time
# Set the templates path
- environment = jinja2.Environment(\
- loader=jinja2.FileSystemLoader('html'), \
+ environment = jinja2.Environment( \
+ loader=jinja2.FileSystemLoader(htmlfolder + '/html'), \
extensions=['jinja2.ext.loopcontrols'])
# Open the template
@@ -1668,12 +1687,6 @@ class glancesHtml:
proccount=stats.getProcessCount(), \
proclist=stats.getProcessList())
- # Display stats
- # Todo:
- #~ self.displayCaption()
- #~ self.displayNow(stats.getNow())
- #~ self.displayHelp()
-
# Write data into the file
f.write(data)
@@ -1738,7 +1751,7 @@ def printSyntax():
print ""
print _("\t-f file\t\tSet the output folder (HTML) or file (CSV)")
print _("\t-h\t\tDisplay the syntax and exit")
- print _("\t-o output\tGenerate output (available: HTML, CSV)")
+ print _("\t-o output\tDefine additional output (available: HTML or CSV)")
print _("\t-t sec\t\tSet the refresh time in second default is %d" \
% refresh_time)
print _("\t-v\t\tDisplay the version and exit")
@@ -1790,7 +1803,9 @@ def init():
if (jinja_tag):
html_tag = True
else:
- print _("Error: Need Jinja library to export into HTML")
+ print _("Error: Need Jinja2 library to export into HTML")
+ print
+ print _("Try to install the python-jinja2 package")
sys.exit(2)
elif arg == "csv":
if (csvlib_tag):
diff --git a/glances/html/default.html b/glances/html/default.html
index 06d3ef34..65dd52cf 100644
--- a/glances/html/default.html
+++ b/glances/html/default.html
@@ -225,3 +225,7 @@
</table>
{% endif %}
{% endblock %}
+
+{% block footer %}
+<p>Powered by <a href="https://github.com/nicolargo/glances">Glances</a></p>
+{% endblock %}
diff --git a/setup.py b/setup.py
index 2a875b23..4ac6e2f7 100755
--- a/setup.py
+++ b/setup.py
@@ -15,6 +15,9 @@ data_files = [
'NEWS',
'screenshot.png']),
('share/doc/glances/doc', glob('doc/*.png')),
+ ('share/glances/html', glob('glances/html/*.html')),
+ ('share/glances/html/css', glob('glances/css/*.css')),
+ ('share/glances/html/img', glob('glances/img/*.png')),
]
for mo in glob('i18n/*/LC_MESSAGES/*.mo'):
data_files.append((dirname(mo).replace('i18n/', 'share/locale/'), [mo]))
@@ -31,6 +34,9 @@ setup(name='Glances',
long_description=open('README').read(),
install_requires=['psutil>=0.4.1'],
packages=['glances'],
+ extras_require = {
+ 'HTML': ['jinja2>=2.0'],
+ },
include_package_data=True,
data_files=data_files,
entry_points={"console_scripts": ["glances = glances.glances:main"]},