summaryrefslogtreecommitdiffstats
path: root/src/glances.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/glances.py')
-rwxr-xr-xsrc/glances.py3156
1 files changed, 2017 insertions, 1139 deletions
diff --git a/src/glances.py b/src/glances.py
index 8ff0b818..4d005c03 100755
--- a/src/glances.py
+++ b/src/glances.py
@@ -1,1188 +1,2066 @@
#!/usr/bin/env python
#
-# Glances is a simple CLI monitoring tool based on libstatgrab
+# Glances is a simple textual monitoring tool
#
-# Pre-requisites: python-statgrab 0.5 or >
+# Pre-requisites: Python 2.6+ and PsUtil 0.4.0+ (for full functions)
#
# Copyright (C) Nicolargo 2012 <nicolas@nicolargo.com>
-#
+#
# 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 <http://www.gnu.org/licenses/>.";
#
from __future__ import generators
-try:
- import os
- import getopt
- import sys
- import signal
- import time
- import datetime
- import multiprocessing
- import gettext
-except KeyboardInterrupt:
- pass
-
-
-# i18n
-#=====
+__appname__ = 'glances'
+__version__ = "1.4"
+__author__ = "Nicolas Hennion <nicolas@nicolargo.com>"
+__licence__ = "LGPL"
+
+# Libraries
+#==========
-application = 'glances'
-__version__ = "1.3.7"
-gettext.install(application)
+import os
+import sys
+import platform
+import getopt
+import signal
+import time
+from datetime import datetime, timedelta
+import gettext
+
+# International
+#==============
+
+gettext.install(__appname__)
+
+# Test methods
+#=============
try:
- import statgrab
-except:
- print _('Statgrab initialization failed, Glances cannot start.')
- print
- sys.exit(1)
+ import curses
+ import curses.panel
+except ImportError:
+ print _('Curses module not found. Glances cannot start.')
+ print _('Glances requires at least Python 2.6 or higher.')
+ print
+ sys.exit(1)
try:
- import curses
- import curses.panel
-except:
- print _('Textmode GUI initialization failed, Glances cannot start.')
+ import psutil
+except ImportError:
+ print _('PsUtil module not found. Glances cannot start.')
+ print
+ print _('On Ubuntu 12.04 or higher:')
+ print _('$ sudo apt-get install python-psutil')
+ print
+ print _('To install PsUtil using pip (as root):')
+ print _('# pip install psutil')
print
sys.exit(1)
+try:
+ # get_cpu_percent method only available with PsUtil 0.2.0+
+ psutil.Process(os.getpid()).get_cpu_percent(interval=0)
+except Exception:
+ psutil_get_cpu_percent_tag = False
+else:
+ psutil_get_cpu_percent_tag = True
+
+try:
+ # (phy|virt)mem_usage methods only available with PsUtil 0.3.0+
+ psutil.phymem_usage()
+ psutil.virtmem_usage()
+except Exception:
+ psutil_mem_usage_tag = False
+else:
+ psutil_mem_usage_tag = True
+
+try:
+ # disk_(partitions|usage) methods only available with PsUtil 0.3.0+
+ psutil.disk_partitions()
+ psutil.disk_usage('/')
+except Exception:
+ psutil_fs_usage_tag = False
+else:
+ psutil_fs_usage_tag = True
+
+try:
+ # disk_io_counters method only available with PsUtil 0.4.0+
+ psutil.disk_io_counters()
+except Exception:
+ psutil_disk_io_tag = False
+else:
+ psutil_disk_io_tag = True
+
+try:
+ # network_io_counters method only available with PsUtil 0.4.0+
+ psutil.network_io_counters()
+except Exception:
+ psutil_network_io_tag = False
+else:
+ psutil_network_io_tag = True
+
+try:
+ # HTML output
+ import jinja2
+except ImportError:
+ jinja_tag = False
+else:
+ jinja_tag = True
+
+try:
+ # CSV output
+ import csv
+except ImportError:
+ csvlib_tag = False
+else:
+ csvlib_tag = True
+
# Classes
#========
-class Timer():
- """
- The timer class
- """
-
- def __init__(self, duration):
- self.started(duration)
-
- def started(self, duration):
- self.target = time.time() + duration
-
- def finished(self):
- return time.time() > self.target
-
-
-class glancesLimits():
- """
- Manage the limit OK,CAREFUL,WARNING,CRITICAL for each stats
- """
-
- # The limit list is stored in an hash table:
- # limits_list[STAT] = [ CAREFUL , WARNING , CRITICAL ]
- # Exemple:
- # limits_list['STD'] = [ 50, 70 , 90 ]
-
- __limits_list = { # CAREFUL WARNING CRITICAL
- 'STD': [50, 70, 90],
- 'LOAD': [0.7, 1.0, 5.0]
- }
-
- def getSTDCareful(self):
- return self.__limits_list['STD'][0]
-
- def getSTDWarning(self):
- return self.__limits_list['STD'][1]
-
- def getSTDCritical(self):
- return self.__limits_list['STD'][2]
-
- def getLOADCareful(self, core = 1):
- return self.__limits_list['LOAD'][0] * core
-
- def getLOADWarning(self, core = 1):
- return self.__limits_list['LOAD'][1] * core
-
- def getLOADCritical(self, core = 1):
- return self.__limits_list['LOAD'][2] * core
-
-
-class glancesLogs():
- """
- The main class to manage logs inside the Glances software
- Logs is a list of list:
- [["begin", "end", "WARNING|CRITICAL", "CPU|LOAD|MEM", MAX, AVG, MIN, SUM, COUNT],...]
- """
-
- def __init__(self):
- """
- Init the logs classe
- """
- # Maximum size of the logs list
- self.logs_max = 10
-
- # Init the logs list
- self.logs_list = []
-
- def get(self):
- """
- Return the logs list (RAW)
- """
- return self.logs_list
-
- def len(self):
- """
- Return the number of item in the log list
- """
- return self.logs_list.__len__()
-
- def __itemexist__(self, item_type):
- """
- An item exist in the list if:
- * end is < 0
- * item_type is matching
- """
- for i in range(self.len()):
- if ((self.logs_list[i][1] < 0) and
- (self.logs_list[i][3] == item_type)):
- return i
- return -1
-
- def add(self, item_state, item_type, item_value):
- """
- item_state = "OK|CAREFUL|WARNING|CRITICAL"
- item_type = "CPU|LOAD|MEM"
- item_value = value
- Item is defined by:
- ["begin", "end", "WARNING|CRITICAL", "CPU|LOAD|MEM", MAX, AVG, MIN, SUM, COUNT]
- If item is a 'new one':
- Add the new item at the beginning of the logs list
- Else:
- Update the existing item
- """
- item_index = self.__itemexist__(item_type)
- if (item_index < 0):
- # Item did not exist, add if WARNING or CRITICAL
- if ((item_state == "WARNING") or
- (item_state == "CRITICAL")):
- # Time is stored in Epoch format
- # Epoch -> DMYHMS = datetime.datetime.fromtimestamp(epoch)
- item = []
- item.append(time.mktime(datetime.datetime.now().timetuple()))
- item.append(-1)
- 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
- self.logs_list.insert(0, item)
- if (self.len() > self.logs_max):
- self.logs_list.pop()
- else:
- # Item exist, update
- if ((item_state == "OK") or
- (item_state == "CAREFUL")):
- # Close the item
- self.logs_list[item_index][1] = time.mktime(datetime.datetime.now().timetuple())
- else:
- # Update the item
- # State
- if (item_state == "CRITICAL"):
- self.logs_list[item_index][2] = item_state
- # Value
- if (item_value > self.logs_list[item_index][4]):
- # MAX
- self.logs_list[item_index][4] = item_value
- elif (item_value < self.logs_list[item_index][6]):
- # MIN
- self.logs_list[item_index][6] = item_value
- # AVG
- self.logs_list[item_index][7] += item_value
- self.logs_list[item_index][8] += 1
- self.logs_list[item_index][5] = self.logs_list[item_index][7] / self.logs_list[item_index][8]
- return self.len()
-
-
-class glancesGrabFs():
- """
- Get FS stats: idem as structure http://www.i-scream.org/libstatgrab/docs/sg_get_fs_stats.3.html
- """
-
- def __init__(self):
- self.__update__()
-
-
- def __update__(self):
- """
- Update the stats
- """
-
- # Reset the list
- self.fs_list = []
-
- # Ignore the following fs
- ignore_fsname = ('none', 'gvfs-fuse-daemon', 'fusectl', 'cgroup')
- ignore_fstype = ('binfmt_misc', 'devpts', 'iso9660', 'none', 'proc', 'sysfs', 'usbfs')
-
- # Open the current mounted FS
- mtab = open("/etc/mtab", "r")
- for line in mtab.readlines():
- if line.split()[0] in ignore_fsname: continue
- if line.split()[2] in ignore_fstype: continue
- # Get FS stats
- fs_current = {}
- fs_name = self.__getmount__(line.split()[1])
- fs_stats = os.statvfs(fs_name)
- # Build the list
- fs_current['device_name'] = str(line.split()[0])
- fs_current['fs_type'] = str(line.split()[2])
- fs_current['mnt_point'] = str(fs_name)
- fs_current['size'] = float(fs_stats.f_blocks) * long(fs_stats.f_frsize)
- fs_current['used'] = float(fs_stats.f_blocks - fs_stats.f_bfree) * long(fs_stats.f_frsize)
- fs_current['avail'] = float(fs_stats.f_bfree) * long(fs_stats.f_frsize)
- self.fs_list.append(fs_current)
- mtab.close()
-
-
- def __getmount__(self, path):
- """
- Return the real root path of a file
- Exemple: /home/nicolargo can return /home or /
- """
- path = os.path.realpath(os.path.abspath(path))
- while path != os.path.sep:
- if os.path.ismount(path):
- return path
- path = os.path.abspath(os.path.join(path, os.pardir))
- return path
-
-
- def get(self):
- self.__update__()
- return self.fs_list
-
-
-class glancesStats():
- """
- This class store, update and give the libstatgrab stats
- """
-
- def __init__(self):
- """
- Init the libstatgrab and process to the first update
- """
-
- # Init libstatgrab
- if not statgrab.sg_init():
- print _("Error: Can not init the libstatgrab library.\n")
-
- # Init the fs stats
- try:
- self.glancesgrabfs = glancesGrabFs()
- except:
- self.glancesgrabfs = {}
-
- # Do the first update
- self.__update__()
-
- def __update__(self):
- """
- Update the stats
- """
-
- # Get informations from libstatgrab and others...
- try:
- self.host = statgrab.sg_get_host_info()
- except:
- self.host = {}
- self.system = self.host
- try:
- self.cpu = statgrab.sg_get_cpu_percents()
- except:
- self.cpu = {}
- try:
- self.load = statgrab.sg_get_load_stats()
- except:
- self.load = {}
- try:
- self.mem = statgrab.sg_get_mem_stats()
- except:
- self.mem = {}
- try:
- self.memswap = statgrab.sg_get_swap_stats()
- except:
- self.memswap = {}
- try:
- self.networkinterface = statgrab.sg_get_network_iface_stats()
- except:
- self.networkinterface = {}
- try:
- self.network = statgrab.sg_get_network_io_stats_diff()
- except:
- self.network = {}
- try:
- self.diskio = statgrab.sg_get_disk_io_stats_diff()
- except:
- self.diskio = {}
- try:
- # Replace the bugged self.fs = statgrab.sg_get_fs_stats()
- self.fs = self.glancesgrabfs.get()
- except:
- self.fs = {}
- try:
- self.processcount = statgrab.sg_get_process_count()
- except:
- self.processcount = {}
- try:
- self.process = statgrab.sg_get_process_stats()
- except:
- self.process = {}
-
- # Get the current date/time
- self.now = datetime.datetime.now()
-
- # Get the number of core (CPU)
- # Used to display load alerts
- self.core_number = multiprocessing.cpu_count()
-
-
- def end(self):
- # Shutdown the libstatgrab
- statgrab.sg_shutdown()
-
-
- def update(self):
- # Update the stats
- self.__update__()
-
-
- def getHost(self):
- return self.host
-
-
- def getSystem(self):
- return self.system
-
-
- def getCpu(self):
- return self.cpu
-
-
- def getCore(self):
- return self.core_number
-
-
- def getLoad(self):
- return self.load
-
-
- def getMem(self):
- return self.mem
-
-
- def getMemSwap(self):
- return self.memswap
-
-
- def getNetworkInterface(self):
- return self.networkinterface
-
-
- def getNetwork(self):
- return self.network
-
-
- def getDiskIO(self):
- return self.diskio
-
-
- def getFs(self):
- return self.fs
-
-
- def getProcessCount(self):
- return self.processcount
-
-
- def getProcessList(self, sortedby = 'auto'):
- """
- Return the sorted process list
- """
-
- if sortedby == 'auto':
- # If global Mem > 70% sort by process size
- # Else sort by cpu comsoption
- sortedby = 'cpu_percent'
- if ( self.mem['total'] != 0):
- if ( ( (self.mem['used'] - self.mem['cache']) * 100 / self.mem['total']) > limits.getSTDWarning()):
- sortedby = 'proc_size'
- return sorted(self.process, key=lambda process: process[sortedby], reverse=True)
-
-
- def getNow(self):
- return self.now
-
-
-class glancesScreen():
- """
- This class manage the screen (display and key pressed)
- """
-
- # By default the process list is automaticaly sorted
- # If global CPU > WANRING => Sorted by process Cpu consomption
- # If global used MEM > WARINING => Sorted by process size
- __process_sortedby = 'auto'
-
- def __init__(self, refresh_time = 1):
- # Global information to display
- self.__version = __version__
-
- # 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.cpu_x = 0 ; self.cpu_y = 3
- self.load_x = 20; self.load_y = 3
- self.mem_x = 41; self.mem_y = 3
- self.network_x = 0 ; self.network_y = 9
- self.diskio_x = 0 ; self.diskio_y = -1
- self.fs_x = 0 ; self.fs_y = -1
- self.process_x = 30; self.process_y = 9
- self.log_x = 0 ; self.log_y = -1
- self.help_x = 30; self.help_y = 12
- self.now_x = 79; self.now_y = 3
- self.caption_x = 0 ; self.caption_y = 3
-
- # Init the curses screen
- self.screen = curses.initscr()
- if not self.screen:
- print _("Error: Can not init the curses library.\n")
-
- curses.start_color()
- if hasattr(curses, 'use_default_colors'):
- curses.use_default_colors()
- if hasattr(curses, 'noecho'):
- curses.noecho()
- if hasattr(curses, 'cbreak'):
- curses.cbreak()
- if hasattr(curses, 'curs_set'):
- curses.curs_set(0)
-
- # Init colors
- self.hascolors = False
- if curses.has_colors():
- self.hascolors = True
- # Init FG color BG color
- curses.init_pair(1, curses.COLOR_WHITE, -1)
- curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_RED)
- curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_GREEN)
- curses.init_pair(4, curses.COLOR_WHITE, curses.COLOR_BLUE)
- curses.init_pair(5, curses.COLOR_WHITE, curses.COLOR_MAGENTA)
- curses.init_pair(6, curses.COLOR_WHITE, curses.COLOR_CYAN)
- curses.init_pair(7, curses.COLOR_BLACK, curses.COLOR_YELLOW)
- else:
- self.hascolors = False
-
- self.title_color = curses.A_BOLD|curses.A_UNDERLINE
- self.help_color = curses.A_BOLD
- if self.hascolors:
- # Colors text styles
- self.no_color = curses.color_pair(1)
- self.default_color = curses.color_pair(3)|curses.A_BOLD
- self.ifCAREFUL_color = curses.color_pair(4)|curses.A_BOLD
- self.ifWARNING_color = curses.color_pair(5)|curses.A_BOLD
- self.ifCRITICAL_color = curses.color_pair(2)|curses.A_BOLD
- else:
- # B&W text styles
- self.no_color = curses.A_NORMAL
- self.default_color = curses.A_NORMAL
- self.ifCAREFUL_color = curses.A_UNDERLINE
- self.ifWARNING_color = curses.A_BOLD
- self.ifCRITICAL_color = curses.A_REVERSE
-
- # Define the colors list (hash table)
- self.__colors_list = {
- # CAREFUL WARNING CRITICAL
- 'DEFAULT': self.no_color,
- 'OK': self.default_color,
- 'CAREFUL': self.ifCAREFUL_color,
- 'WARNING': self.ifWARNING_color,
- 'CRITICAL': self.ifCRITICAL_color
- }
-
- # By default all the stats are displayed
- self.network_tag = True
- self.diskio_tag = True
- self.fs_tag = True
- self.log_tag = True
-
- # Init main window
- self.term_window = self.screen.subwin(0, 0)
-
- # Init help panel
- # TODO: pb when size of the screen < 22 lines
- screen_x = self.screen.getmaxyx()[1]
- screen_y = self.screen.getmaxyx()[0]
- if (screen_x > (self.term_w-self.help_x) and
- (screen_y > (self.term_h-self.help_y-2))):
- term_help = self.screen.subwin(self.term_h-self.help_y-2, self.term_w-self.help_x, self.help_y, self.help_x)
- self.panel_help = curses.panel.new_panel(term_help)
- self.hideHelp()
-
- # Init refresh time
- self.__refresh_time = refresh_time
-
- # Catch key pressed with non blocking mode
- self.term_window.keypad(1) ; self.term_window.nodelay(1) ; self.pressedkey = -1
-
-
- def setProcessSortedBy(self, sorted):
- self.__process_sortedautoflag = False
- self.__process_sortedby = sorted
-
-
- def getProcessSortedBy(self):
- return self.__process_sortedby
-
-
- def __autoUnit(self, val):
- """
- Convert val to string and concatenate the good unit
- Exemples:
- 960 -> 960
- 142948 -> 143K
- 560745673 -> 561M
- ...
- """
- if val >= 1073741824L:
- return "%.1fG" % (val / 1073741824L)
- elif val >= 1048576L:
- return "%.1fM" % (val / 1048576L)
- elif val >= 1024:
- return "%.1fK" % (val / 1024)
- else:
- return str(int(val))
-
- def __getAlert(self, current = 0, max = 100):
- # If current < CAREFUL of max then alert = OK
- # If current > CAREFUL of max then alert = CAREFUL
- # If current > WARNING of max then alert = WARNING
- # If current > CRITICAL of max then alert = CRITICAL
- try:
- (current * 100) / max
- except ZeroDivisionError:
- return 'DEFAULT'
-
- variable = (current * 100) / max
-
- if variable > limits.getSTDCritical():
- return 'CRITICAL'
- elif variable > limits.getSTDWarning():
- return 'WARNING'
- elif variable > limits.getSTDCareful():
- return 'CAREFUL'
-
- return 'OK'
-
-
- def __getColor(self, current = 0, max = 100):
- return self.__colors_list[self.__getAlert(current, max)]
-
-
- def __getCpuAlert(self, current = 0, max = 100):
- return self.__getAlert(current, max)
-
-
- def __getCpuColor(self, current = 0, max = 100):
- return self.__getColor(current, max)
-
-
- def __getLoadAlert(self, current = 0, core = 1):
- # If current < CAREFUL*core of max then alert = OK
- # If current > CAREFUL*core of max then alert = CAREFUL
- # If current > WARNING*core of max then alert = WARNING
- # If current > CRITICAL*core of max then alert = CRITICAL
-
- if current > limits.getLOADCritical(core):
- return 'CRITICAL'
- elif current > limits.getLOADWarning(core):
- return 'WARNING'
- elif current > limits.getLOADCareful(core):
- return 'CAREFUL'
-
- return 'OK'
-
-
- def __getLoadColor(self, current = 0, core = 1):
- return self.__colors_list[self.__getLoadAlert(current, core)]
-
-
- def __getMemAlert(self, current = 0, max = 100):
- return self.__getAlert(current, max)
-
-
- def __getMemColor(self, current = 0, max = 100):
- return self.__getColor(current, max)
-
-
- def __getNetColor(self, current = 0, max = 100):
- return self.__getColor(current, max)
-
-
- def __getFsColor(self, current = 0, max = 100):
- return self.__getColor(current, max)
-
-
- def __catchKey(self):
- # Get key
- self.pressedkey = self.term_window.getch();
-
- # Actions...
- if (self.pressedkey == 27) or (self.pressedkey == 113):
- # 'ESC'|'q' > Exit
- end()
- #elif (self.pressedkey == curses.KEY_RESIZE):
- # Resize event
- elif (self.pressedkey == 97):
- # 'a' > Sort process list automaticaly
- self.setProcessSortedBy('auto')
- elif (self.pressedkey == 99):
- # 'c' > Sort process list by Cpu usage
- self.setProcessSortedBy('cpu_percent')
- elif (self.pressedkey == 100):
- # 'n' > Enable/Disable diskio stats
- self.diskio_tag = not self.diskio_tag
- elif (self.pressedkey == 102):
- # 'n' > Enable/Disable fs stats
- self.fs_tag = not self.fs_tag
- elif (self.pressedkey == 104):
- # 'h' > Enable/Disable help
- if (self.panel_help.hidden()):
- self.showHelp()
- else:
- self.hideHelp()
- elif (self.pressedkey == 108):
- # 'l' > Enable/Disable logs list
- self.log_tag = not self.log_tag
- elif (self.pressedkey == 109):
- # 'm' > Sort process list by Mem usage
- self.setProcessSortedBy('proc_size')
- elif (self.pressedkey == 110):
- # 'n' > Enable/Disable network stats
- self.network_tag = not self.network_tag
-
- # Return the key code
- return self.pressedkey
-
-
- def end(self):
- # Shutdown the curses window
- curses.echo() ; curses.nocbreak() ; curses.curs_set(1)
- curses.endwin()
-
-
- def display(self, stats):
- # Display stats
- self.displayHost(stats.getHost())
- self.displaySystem(stats.getSystem())
- self.displayCpu(stats.getCpu())
- self.displayLoad(stats.getLoad(), stats.getCore())
- self.displayMem(stats.getMem(), stats.getMemSwap())
- network_count = self.displayNetwork(stats.getNetwork(), stats.getNetworkInterface())
- diskio_count = self.displayDiskIO(stats.getDiskIO(), self.network_y + network_count)
- fs_count = self.displayFs(stats.getFs(), self.network_y + network_count + diskio_count)
- log_count = self.displayLog(self.network_y + network_count + diskio_count + fs_count)
- self.displayProcess(stats.getProcessCount(), stats.getProcessList(screen.getProcessSortedBy()), log_count)
- self.displayCaption()
- self.displayNow(stats.getNow())
-
- # Display help panel
- if (not self.panel_help.hidden()):
- self.displayHelp()
-
- def erase(self):
- # Erase the content of the screen
- self.term_window.erase()
-
-
- def flush(self, stats):
- # Flush display
- self.erase()
- self.display(stats)
- #curses.panel.update_panels()
- #curses.doupdate()
-
- def update(self, stats):
- # flush display
- self.flush(stats)
-
- # Wait
- countdown = Timer(self.__refresh_time)
- while (not countdown.finished()):
- # Refresh the screen
- self.term_window.refresh()
- # Getkey
- if (self.__catchKey() > -1):
- # flush display
- self.flush(stats)
- # Wait 100ms...
- curses.napms(100)
-
-
- def displayHelp(self):
- """
- Display the help panel (active| desactive with the 'h' key)
- """
- screen_x = self.screen.getmaxyx()[1]
- screen_y = self.screen.getmaxyx()[0]
- if ((screen_y > 23)
- and (screen_x > 79)):
- helpWindow = self.panel_help.window()
- helpWindow.resize(self.term_h-self.help_y-2, self.term_w-self.help_x)
- helpWindow.clear()
- msg = _("Glances help (press 'h' to hide)")
- helpWindow.addnstr(1, 2, _("'a'\tto sort processes automatically"), self.term_w-self.help_x-4, self.help_color if self.hascolors else 0)
- helpWindow.addnstr(2, 2, _("'c'\tto sort processes by CPU consumption"), self.term_w-self.help_x-4, self.help_color if self.hascolors else 0)
- helpWindow.addnstr(3, 2, _("'d'\tto disable|enable the disk IO stats"), self.term_w-self.help_x-4, self.help_color if self.hascolors else 0)
- helpWindow.addnstr(4, 2, _("'f'\tto disable|enable the file system stats"), self.term_w-self.help_x-4, self.help_color if self.hascolors else 0)
- helpWindow.addnstr(5, 2, _("'l'\tto display|hide the logs messages"), self.term_w-self.help_x-4, self.help_color if self.hascolors else 0)
- helpWindow.addnstr(6, 2, _("'m'\tto sort processes by process size"), self.term_w-self.help_x-4, self.help_color if self.hascolors else 0)
- helpWindow.addnstr(7, 2, _("'n'\tto disable|enable the network interfaces stats"), self.term_w-self.help_x-4, self.help_color if self.hascolors else 0)
- helpWindow.addnstr(8, 2, _("'q'\tto exit Glances"), self.term_w-self.help_x-4, self.help_color if self.hascolors else 0)
- helpWindow.box()
-
-
- def showHelp(self):
- """
- Show the help panel
- """
- self.panel_help.show()
-
-
- def hideHelp(self):
- """
- Hide the help panel
- """
- self.panel_help.hide()
-
-
- 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'] # +" "+str(self.pressedkey)
- 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):
- # System information
- if (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']
- self.term_window.addnstr(self.system_y, self.system_x+int(screen_x/2)-len(system_msg)/2, system_msg, 80)
-
-
- def displayCpu(self, cpu):
- # CPU %
- if (not cpu):
- return 0
- screen_x = self.screen.getmaxyx()[1]
- screen_y = self.screen.getmaxyx()[0]
- if ((screen_y > self.cpu_y+6)
- and (screen_x > self.cpu_x+18)):
- self.term_window.addnstr(self.cpu_y, self.cpu_x, _("Cpu"), 8, self.title_color if self.hascolors else curses.A_UNDERLINE)
- self.term_window.addnstr(self.cpu_y, self.cpu_x+10,"%", 8)
- self.term_window.addnstr(self.cpu_y+1, self.cpu_x, _("User:"), 8)
- self.term_window.addnstr(self.cpu_y+2, self.cpu_x, _("Kernel:"), 8)
- self.term_window.addnstr(self.cpu_y+3, self.cpu_x, _("Nice:"), 8)
- self.term_window.addnstr(self.cpu_y+4, self.cpu_x, _("Idle:"), 8)
-
- alert = self.__getCpuAlert(cpu['user'])
- logs.add(alert, "CPU user", cpu['user'])
- self.term_window.addnstr(self.cpu_y+1, self.cpu_x+10, "%.1f" % cpu['user'], 8, self.__colors_list[alert])
-
- alert = self.__getCpuAlert(cpu['kernel'])
- logs.add(alert, "CPU kernel", cpu['kernel'])
- self.term_window.addnstr(self.cpu_y+2, self.cpu_x+10, "%.1f" % cpu['kernel'], 8, self.__colors_list[alert])
-
- alert = self.__getCpuAlert(cpu['nice'])
- logs.add(alert, "CPU nice", cpu['nice'])
- self.term_window.addnstr(self.cpu_y+3, self.cpu_x+10, "%.1f" % cpu['nice'], 8, self.__colors_list[alert])
-
- self.term_window.addnstr(self.cpu_y+4, self.cpu_x+10, "%.1f" % cpu['idle'], 8)
-
-
- def displayLoad(self, load, core):
- # Load %
- if (not load):
- return 0
- screen_x = self.screen.getmaxyx()[1]
- screen_y = self.screen.getmaxyx()[0]
- if ((screen_y > self.load_y+5)
- and (screen_x > self.load_x+18)):
- self.term_window.addnstr(self.load_y, self.load_x, _("Load"), 8, self.title_color if self.hascolors else curses.A_UNDERLINE)
- self.term_window.addnstr(self.load_y, self.load_x+10, str(core)+_("-Core"), 8)
- self.term_window.addnstr(self.load_y+1, self.load_x, _("1 min:"), 8)
- self.term_window.addnstr(self.load_y+2, self.load_x, _("5 mins:"), 8)
- self.term_window.addnstr(self.load_y+3, self.load_x, _("15 mins:"), 8)
-
- self.term_window.addnstr(self.load_y+1, self.load_x+10, str(load['min1']), 8)
-
- alert = self.__getLoadAlert(load['min5'], core)
- logs.add(alert, "LOAD 5-mins", load['min5'])
- self.term_window.addnstr(self.load_y+2, self.load_x+10, str(load['min5']), 8, self.__colors_list[alert])
-
- alert = self.__getLoadAlert(load['min15'], core)
- logs.add(alert, "LOAD 15-mins", load['min15'])
- self.term_window.addnstr(self.load_y+3, self.load_x+10, str(load['min15']), 8, self.__colors_list[alert])
-
-
- def displayMem(self, mem, memswap):
- # MEM
- if (not mem or not memswap):
- return 0
- screen_x = self.screen.getmaxyx()[1]
- screen_y = self.screen.getmaxyx()[0]
- if ((screen_y > self.mem_y+5)
- and (screen_x > self.mem_x+38)):
- self.term_window.addnstr(self.mem_y, self.mem_x, _("Mem MB"), 8, self.title_color if self.hascolors else curses.A_UNDERLINE)
- self.term_window.addnstr(self.mem_y, self.mem_x+10,_("Mem"), 8)
- self.term_window.addnstr(self.mem_y, self.mem_x+20,_("Swap"), 8)
- self.term_window.addnstr(self.mem_y, self.mem_x+30,_("Real"), 8)
- self.term_window.addnstr(self.mem_y+1, self.mem_x, _("Total:"), 8)
- self.term_window.addnstr(self.mem_y+2, self.mem_x, _("Used:"), 8)
- self.term_window.addnstr(self.mem_y+3, self.mem_x, _("Free:"), 8)
-
- self.term_window.addnstr(self.mem_y+1, self.mem_x+10, str(mem['total']/1048576), 8)
- self.term_window.addnstr(self.mem_y+2, self.mem_x+10, str(mem['used']/1048576), 8)
- self.term_window.addnstr(self.mem_y+3, self.mem_x+10, str(mem['free']/1048576), 8)
-
- alert = self.__getMemAlert(memswap['used'], memswap['total'])
- logs.add(alert, "MEM swap", memswap['used']/1048576)
- self.term_window.addnstr(self.mem_y+1, self.mem_x+20, str(memswap['total']/1048576), 8)
- self.term_window.addnstr(self.mem_y+2, self.mem_x+20, str(memswap['used']/1048576), 8, self.__colors_list[alert])
- self.term_window.addnstr(self.mem_y+3, self.mem_x+20, str(memswap['free']/1048576), 8)
-
- alert = self.__getMemAlert(mem['used']-mem['cache'], mem['total'])
- logs.add(alert, "MEM real", (mem['used']-mem['cache'])/1048576)
- self.term_window.addnstr(self.mem_y+1, self.mem_x+30, "-", 8)
- self.term_window.addnstr(self.mem_y+2, self.mem_x+30, str((mem['used']-mem['cache'])/1048576), 8, self.__colors_list[alert])
- self.term_window.addnstr(self.mem_y+3, self.mem_x+30, str((mem['free']+mem['cache'])/1048576), 8)
-
-
- def displayNetwork(self, network, networkinterface):
- """
- Display the network interface bitrate
- Return the number of interfaces
- """
- # Network interfaces bitrate
- if (not network or not networkinterface or not self.network_tag):
- return 0
- screen_x = self.screen.getmaxyx()[1]
- screen_y = self.screen.getmaxyx()[0]
- if ((screen_y > self.network_y+3)
- and (screen_x > self.network_x+28)):
- # Get the speed of the network interface
- # TODO: optimize...
- speed = {}
- for i in range(0, len(networkinterface)):
- # Strange think, on Ubuntu, libstatgrab return 65525 for my ethernet card...
- if networkinterface[i]['speed'] == 65535:
- speed[networkinterface[i]['interface_name']] = 0
- else:
- speed[networkinterface[i]['interface_name']] = networkinterface[i]['speed']*1000000
- # Network interfaces bitrate
- self.term_window.addnstr(self.network_y, self.network_x, _("Net rate"), 8, self.title_color if self.hascolors else curses.A_UNDERLINE)
- self.term_window.addnstr(self.network_y, self.network_x+10, _("Rx/ps"), 8)
- self.term_window.addnstr(self.network_y, self.network_x+20, _("Tx/ps"), 8)
- # Adapt the maximum interface to the screen
- ret = 2
- for i in range(0, min(screen_y-self.network_y-3, len(network))):
- try:
- speed[network[i]['interface_name']]
- except:
- break
- elapsed_time = max (1, network[i]['systime'])
- self.term_window.addnstr(self.network_y+1+i, self.network_x, network[i]['interface_name']+':', 8)
- self.term_window.addnstr(self.network_y+1+i, self.network_x+10, self.__autoUnit(network[i]['rx']/elapsed_time*8) + "b", 8, self.__getNetColor(network[i]['rx']/elapsed_time*8, speed[network[i]['interface_name']]))
- self.term_window.addnstr(self.network_y+1+i, self.network_x+20, self.__autoUnit(network[i]['tx']/elapsed_time*8) + "b", 8, self.__getNetColor(network[i]['tx']/elapsed_time*8, speed[network[i]['interface_name']]))
- ret = ret + 1
- return ret
- return 0
-
-
- def displayDiskIO(self, diskio, offset_y = 0):
- # Disk input/output rate
- if (not diskio or not self.diskio_tag):
- return 0
- screen_x = self.screen.getmaxyx()[1]
- screen_y = self.screen.getmaxyx()[0]
- self.diskio_y = offset_y
- if ((screen_y > self.diskio_y+3)
- and (screen_x > self.diskio_x+28)):
- self.term_window.addnstr(self.diskio_y, self.diskio_x, _("Disk I/O"), 8, self.title_color if self.hascolors else curses.A_UNDERLINE)
- self.term_window.addnstr(self.diskio_y, self.diskio_x+10, _("In/ps"), 8)
- self.term_window.addnstr(self.diskio_y, self.diskio_x+20, _("Out/ps"), 8)
- # Adapt the maximum disk to the screen
- disk = 0
- for disk in range(0, min(screen_y-self.diskio_y-3, len(diskio))):
- elapsed_time = max(1, diskio[disk]['systime'])
- self.term_window.addnstr(self.diskio_y+1+disk, self.diskio_x, diskio[disk]['disk_name']+':', 8)
- self.term_window.addnstr(self.diskio_y+1+disk, self.diskio_x+10, self.__autoUnit(diskio[disk]['write_bytes']/elapsed_time) + "B", 8)
- self.term_window.addnstr(self.diskio_y+1+disk, self.diskio_x+20, self.__autoUnit(diskio[disk]['read_bytes']/elapsed_time) + "B", 8)
- return disk+3
- return 0
-
-
- def displayFs(self, fs, offset_y = 0):
- # Filesystem stats
- if (not fs or not self.fs_tag):
- return 0
- screen_x = self.screen.getmaxyx()[1]
- screen_y = self.screen.getmaxyx()[0]
- self.fs_y = offset_y
- if ((screen_y > self.fs_y+3)
- and (screen_x > self.fs_x+28)):
-