Skip to content
Snippets Groups Projects
Commit 4f9e8163 authored by Gigg, Martyn Anthony's avatar Gigg, Martyn Anthony
Browse files

Updated to SysMon v0.27

Refs #9843
parent 9ef4c184
No related branches found
No related tags found
No related merge requests found
#File to identify the current version of the software #File to identify the current version of the software
#Note that this file must be manually updated to contain the same #Note that this file must be manually updated to contain the same
#version number as the git tag for the check-in. #version number as the git tag for the check-in.
__version__="v0.26" __version__="v0.27"
\ No newline at end of file \ No newline at end of file
...@@ -13,6 +13,8 @@ import config ...@@ -13,6 +13,8 @@ import config
import math import math
import getpass import getpass
import re import re
import sys
import time
#check if command line flag --nompl set to disable matplotlib #check if command line flag --nompl set to disable matplotlib
if not(config.nompl): if not(config.nompl):
...@@ -190,6 +192,9 @@ def constantUpdateActor(self,config): ...@@ -190,6 +192,9 @@ def constantUpdateActor(self,config):
def updateProcTable(self,config): def updateProcTable(self,config):
if self.doUpdates==True: if self.doUpdates==True:
Ncpus=len(psutil.cpu_percent(percpu=True))
table=self.ui.tableWidgetProcess table=self.ui.tableWidgetProcess
#first remove all rows #first remove all rows
Nrows=table.rowCount() Nrows=table.rowCount()
...@@ -221,25 +226,93 @@ def updateProcTable(self,config): ...@@ -221,25 +226,93 @@ def updateProcTable(self,config):
d_cpu={} d_cpu={}
d_mem={} d_mem={}
d_name={} d_name={}
d_cpuTimes={}
d_procTimes={}
#fill the dictionaries - seems to need to be done faster than within loop which also fills the table...not sure why... #fill the dictionaries - seems to need to be done faster than within loop which also fills the table...not sure why...
try:
#check if this dictionary exists or not
self.ui.d_procTimes
self.ui.d_cpuTimes
#if so, move on
pass
except:
#case to initialize the dictionary
for proc in psutil.process_iter():
try:
#check if acess denied
pname=proc.name
proctime=proc.get_cpu_times() #get
cputime=psutil.cpu_times()
d_procTimes.update({proc.pid:proctime})
d_cpuTimes.update({proc.pid:cputime})
except:
#case we skip a process
pass
self.ui.d_cpuTimes=d_cpuTimes
self.ui.d_procTimes=d_procTimes
d_cpuTimes={}
d_procTimes={}
updateInterval=float(self.update) #timer interval in seconds
for proc in psutil.process_iter(): for proc in psutil.process_iter():
try: #try:
if psutil.Process(proc.pid).is_running():
#if proc.pid == 37196:
#check if process still exists, if so, update dictionaries #check if process still exists, if so, update dictionaries
cpupct=proc.get_cpu_percent(interval=0) if config.psutilVer == 1 else proc.cpu_percent(interval=0)
memVal=float(int(float(proc.get_memory_percent())*100.0))/100.0 if config.psutilVer == 1 else float(int(float(proc.memory_percent())*100.0))/100.0
try: try:
#don't update dictionaries if name gives an access denied error when checking process name #check if process previously existed - if so we can calculate a cpupct
pname=proc.name if config.psutilVer == 1 else proc.name() proctimeHold=self.ui.d_procTimes[proc.pid]
d_user.update({proc.pid:proc.username}) if config.psutilVer == 1 else d_user.update({proc.pid:proc.username()}) proctime=proc.get_cpu_times() #get
d_cpu.update({proc.pid:cpupct}) deltaProcTime=(proctime.user+proctime.system) - (proctimeHold.user+proctimeHold.system)
d_mem.update({proc.pid:memVal})
d_name.update({proc.pid:pname}) cputimeHold=self.ui.d_cpuTimes[proc.pid]
cputime=psutil.cpu_times()
deltaCPUTime=(cputime.user+cputime.system+cputime.idle) - (cputimeHold.user+cputimeHold.system+cputimeHold.idle)
if deltaProcTime > 0:
if deltaCPUTime < updateInterval:
deltaCPUTime=updateInterval
else:
pass
cpupct=float(deltaProcTime)/float(deltaCPUTime)*100.0
else:
cpupct=0
if cpupct < 0:
cpupct=0
cpupct=float(int(float(cpupct)*100))/100 #only keep two decimal places
memVal=float(int(float(proc.get_memory_percent())*100.0))/100.0 if config.psutilVer == 1 else float(int(float(proc.memory_percent())*100.0))/100.0
try:
#don't update dictionaries if name gives an access denied error when checking process name
#print "Updating"
pname=proc.name if config.psutilVer == 1 else proc.name()
d_user.update({proc.pid:proc.username}) if config.psutilVer == 1 else d_user.update({proc.pid:proc.username()})
d_cpu.update({proc.pid:cpupct})
d_mem.update({proc.pid:memVal})
d_name.update({proc.pid:pname})
d_cpuTimes.update({proc.pid:cputime})
d_procTimes.update({proc.pid:proctime})
except:
#print "psutil General Error: ",sys.exc_info()[0]
pass
except: except:
pass #place holder #else process did not previously exist and we cannot give an update this iteration
except: #print "except - pid: ",proc.pid
pass #skip this process - case where it no longer exists
pass
#once the dictionarys are updated, update cpu times for next loop
self.ui.d_cpuTimes=d_cpuTimes
self.ui.d_procTimes=d_procTimes
#now fill the table for display #now fill the table for display
for proc in d_user.keys(): for proc in d_user.keys():
#print "proc: ",proc," type: ",type(proc) #print "proc: ",proc," type: ",type(proc)
...@@ -295,25 +368,98 @@ def updateUserChart(self,config): ...@@ -295,25 +368,98 @@ def updateUserChart(self,config):
d_cpu={} d_cpu={}
d_mem={} d_mem={}
d_name={} d_name={}
#fill the dictionaries - seems to need to be done faster than within loop which also fills the table...not sure why... d_cpuTimes={}
d_procTimes={}
try:
#check if this dictionary exists or not
self.ui.d_procTimes
self.ui.d_cpuTimes
#if so, move on
pass
except:
#case to initialize the dictionary
for proc in psutil.process_iter():
try:
#check if acess denied
pname=proc.name
proctime=proc.get_cpu_times() #get
cputime=psutil.cpu_times()
d_procTimes.update({proc.pid:proctime})
d_cpuTimes.update({proc.pid:cputime})
except:
#case we skip a process
pass
self.ui.d_cpuTimes=d_cpuTimes
self.ui.d_procTimes=d_procTimes
d_cpuTimes={}
d_procTimes={}
updateInterval=float(self.update) #timer interval in seconds
totcpupct=0
for proc in psutil.process_iter(): for proc in psutil.process_iter():
try: try:
psutil.Process(proc.pid).is_running()
#if proc.pid == 37196:
#check if process still exists, if so, update dictionaries #check if process still exists, if so, update dictionaries
cpupct=proc.get_cpu_percent(interval=0) if config.psutilVer == 1 else proc.cpu_percent(interval=0)
memVal=float(int(float(proc.get_memory_percent())*100.0))/100.0 if config.psutilVer == 1 else float(int(float(proc.memory_percent())*100.0))/100.0
try: try:
#don't update dictionaries if name gives an access denied error when checking process name #check if process previously existed - if so we can calculate a cpupct
pname=proc.name if config.psutilVer == 1 else proc.name() proctimeHold=self.ui.d_procTimes[proc.pid]
d_user.update({proc.pid:proc.username}) if config.psutilVer == 1 else d_user.update({proc.pid:proc.username()}) proctime=proc.get_cpu_times() #get
d_cpu.update({proc.pid:cpupct}) deltaProcTime=(proctime.user+proctime.system) - (proctimeHold.user+proctimeHold.system)
d_mem.update({proc.pid:memVal})
d_name.update({proc.pid:pname}) cputimeHold=self.ui.d_cpuTimes[proc.pid]
cputime=psutil.cpu_times()
deltaCPUTime=(cputime.user+cputime.system+cputime.idle) - (cputimeHold.user+cputimeHold.system+cputimeHold.idle)
if deltaProcTime > 0:
if deltaCPUTime < updateInterval:
deltaCPUTime=updateInterval
else:
pass
cpupct=float(deltaProcTime)/float(deltaCPUTime)*100.0
else:
cpupct=0
if cpupct < 0:
cpupct=0
cpupct=float(int(float(cpupct)*100))/100 #only keep two decimal places
totcpupct+=cpupct
memVal=float(int(float(proc.get_memory_percent())*100.0))/100.0 if config.psutilVer == 1 else float(int(float(proc.memory_percent())*100.0))/100.0
try:
#don't update dictionaries if name gives an access denied error when checking process name
#print "Updating"
pname=proc.name if config.psutilVer == 1 else proc.name()
d_user.update({proc.pid:proc.username}) if config.psutilVer == 1 else d_user.update({proc.pid:proc.username()})
#System Idle process should not be listed in users cpu totals so set it to zero
if pname =="System Idle Process":
cpupct=0
d_cpu.update({proc.pid:cpupct})
d_mem.update({proc.pid:memVal})
d_name.update({proc.pid:pname})
d_cpuTimes.update({proc.pid:cputime})
d_procTimes.update({proc.pid:proctime})
except:
#print "psutil General Error: ",sys.exc_info()[0]
pass
except: except:
#print "access denied" #else process did not previously exist and we cannot give an update this iteration
pass #place holder #print "except - pid: ",proc.pid
pass
except: except:
#print "skipped process" #process no longer exists - do nothing
pass #skip this process as it no longer exists pass
self.ui.d_cpuTimes=d_cpuTimes
self.ui.d_procTimes=d_procTimes
#print "** Total Mem Used: ",sum(d_mem.values()) #print "** Total Mem Used: ",sum(d_mem.values())
users=d_user.values() users=d_user.values()
users_unique=list(set(users)) #use set() to find unique users then convert the resulting set to a list via list() users_unique=list(set(users)) #use set() to find unique users then convert the resulting set to a list via list()
...@@ -335,7 +481,7 @@ def updateUserChart(self,config): ...@@ -335,7 +481,7 @@ def updateUserChart(self,config):
user=d_user[pid] user=d_user[pid]
cpu_by_users[user]=cpu_by_users[user] + d_cpu[pid] cpu_by_users[user]=cpu_by_users[user] + d_cpu[pid]
mem_by_users[user]=mem_by_users[user] + d_mem[pid] mem_by_users[user]=mem_by_users[user] + d_mem[pid]
#print d_cpu[35296],d_cpu[37196],d_cpu[35296]+d_cpu[37196]
#now convert to a list which we can index #now convert to a list which we can index
cpu_by_users_lst=cpu_by_users.values() cpu_by_users_lst=cpu_by_users.values()
mem_by_users_lst=mem_by_users.values() mem_by_users_lst=mem_by_users.values()
...@@ -370,6 +516,7 @@ def updateUserChart(self,config): ...@@ -370,6 +516,7 @@ def updateUserChart(self,config):
indx=sorted(range(len(mem_by_users_lst)), key=mem_by_users_lst.__getitem__,reverse=True) indx=sorted(range(len(mem_by_users_lst)), key=mem_by_users_lst.__getitem__,reverse=True)
else: else:
print 'Incorrect sort parameter' print 'Incorrect sort parameter'
#sort lists #sort lists
cpu_by_users_sorted=[cpu_by_users_lst[x] for x in indx] cpu_by_users_sorted=[cpu_by_users_lst[x] for x in indx]
mem_by_users_sorted=[mem_by_users_lst[x] for x in indx] mem_by_users_sorted=[mem_by_users_lst[x] for x in indx]
...@@ -438,10 +585,10 @@ def updateUserChart(self,config): ...@@ -438,10 +585,10 @@ def updateUserChart(self,config):
frame=plt.gca() frame=plt.gca()
frame.axes.get_yaxis().set_ticks([]) frame.axes.get_yaxis().set_ticks([])
plt.xticks(np.arange(2)+width/2.,('CPU','Mem'),fontsize=config.pltFont,fontweight='bold') plt.xticks(np.arange(2)+width/2.,('CPU','Mem'),fontsize=config.pltFont,fontweight='bold')
ymaxCPU=int((sum(cpu_by_users_sorted)+100)/100)*100 #range ymaxCPU to nearest 100% ymaxCPU=int(round(sum(cpu_by_users_sorted)+10))/10*10 #range ymaxCPU to nearest 10%
ymaxMEM=int(round(sum(mem_by_users_sorted)+10))/10*10 #range ymaxMEM to nearest 10% ymaxMEM=int(round(sum(mem_by_users_sorted)+10))/10*10 #range ymaxMEM to nearest 10%
ymaxMAX=max([ymaxCPU,ymaxMEM,100]) ymaxMAX=max([ymaxCPU,ymaxMEM])
if sortBy == 'cpu': if sortBy == 'cpu':
ymax=max([ymaxCPU,10]) ymax=max([ymaxCPU,10])
...@@ -452,20 +599,23 @@ def updateUserChart(self,config): ...@@ -452,20 +599,23 @@ def updateUserChart(self,config):
elif sortBy == 'max': elif sortBy == 'max':
ymax=max([ymaxMAX,10]) ymax=max([ymaxMAX,10])
auto=True auto=True
# print 'ymaxCPU: ',ymaxCPU,' ymaxMEM: ',ymaxMEM,' ymaxMAX: ',ymaxMAX,' ymax: ',ymax,' sum(mem_by_users_sorted): ',sum(mem_by_users_sorted) #print 'ymaxCPU: ',ymaxCPU,' ymaxMEM: ',ymaxMEM,' ymaxMAX: ',ymaxMAX,' ymax: ',ymax
plt.ylim(0,ymax,auto=auto) #print 'sum(cpu_by_users_sorted): ',sum(cpu_by_users_sorted),'sum(mem_by_users_sorted): ',sum(mem_by_users_sorted)
#print cpu_by_users
plt.ylim(0,ymax,auto=True)
#compute composite % #compute composite %
sumCPU=sum(cpu_by_users_sorted) sumCPU=sum(cpu_by_users_sorted)
ylab=np.arange(5)/4.0*float(sumCPU)/float(self.ui.Ncpus) sumCPU=float(int(sumCPU*100))/100 #use two digits
ylab=np.arange(5)/4.0*float(sumCPU)#/float(self.ui.Ncpus)
scl=float(ymax)/float(sumCPU) scl=float(ymax)/float(sumCPU)
ylab=ylab*100*scl ylab=ylab*100*scl
tmp=ylab.astype('int') tmp=ylab.astype('int')
tmp1=tmp.astype('float') tmp1=tmp.astype('float')
tmp1=tmp1/100 tmp1=tmp1/100
ylab1=tmp1 ylab1=np.round(tmp1)
ax1=plt.twinx() ax1=plt.twinx()
ax1.set_ylabel('Composite CPU Percent',fontsize=config.pltFont,fontweight='bold') ax1.set_ylabel('Composite CPU Percent',fontsize=config.pltFont,fontweight='bold')
...@@ -496,7 +646,7 @@ def updateUserChart(self,config): ...@@ -496,7 +646,7 @@ def updateUserChart(self,config):
#place second y axis label on plot #place second y axis label on plot
ylab2=np.arange(5)/4.0*float(ymax) ylab2=np.arange(5)/4.0*float(ymax)
ax2=plt.twinx() ax2=plt.twinx()
ax2.set_ylabel('Percent',fontsize=config.pltFont,fontweight='bold',position=(0.9,0.5)) ax2.set_ylabel('Memory Percent',fontsize=config.pltFont,fontweight='bold',position=(0.9,0.5))
ax2.set_yticks(ylab2) ax2.set_yticks(ylab2)
#ax2.set_yticks(ylab2) #ax2.set_yticks(ylab2)
ax2.yaxis.set_ticks_position('right') ax2.yaxis.set_ticks_position('right')
......
Mantid SysMon
====== ======
The Mantid project provides a framework that supports high-performance computing and visualisation of scientific data. Mantid has been created to manipulate and analyse Neutron and Muon scattering data, but could be applied to many other techniques. The framework is open source and supported on multiple target platforms (Windows, Linux, Mac OS X). Python qt system monitor which utilizes the Python psutil and platform modules to provide system information for display.
Useful links This application has been adapted to work with psutil version 1 and version 2 modules as there are some command syntax changes between these two versions.
------------
* Homepage: http://www.mantidproject.org The SysMon user interface has been divided into a main window which imports the tabs to make a standalone application, or the tabs can be imported into other applications as a QWidget. Thus there are separate .ui files corresponding to each.
* Download: http://download.mantidproject.org
* Asking for help: http://download.mantidproject.org/webmailer/index.php The code which imports the tabs into the main program resides in SysMon.pyw. This is where to look to see how to include the tabs into your own application. All files except SysMon.pyw and ui_sysmonMainWindow.* will be required when tabs are incorporated in other applications.
* Issue tracking: http://trac.mantidproject.org/mantid/
* Build server: http://builds.mantidproject.org The following command line arguments have been added:
* Developer site: http://developer.mantidproject.org --help to print out the help message.
--nompl to run the application minus matplotlib in support of the current MantidPlot (removes those tabs requiring matplotlib).
--custom to enable the custom menubar item in the standalone application (currently supports checking Matlab license status on SNS analysis computers).
To run as a standalone application via the corresponding command lines:
*Change to the folder containing the Sysmon software, then:
*DOS: python SysMon.pyw
*Linux: ./SysMon.pyw
The standalone application been tested on Windows and RHEL Linux, but not on Mac yet.
Note that configuration and global constants and variables now reside in config.py.
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/mantidproject/mantid/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment