casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables
profileplot.py
Go to the documentation of this file.
00001 import signal
00002 import os
00003 import pylab as pl
00004 import string
00005 import commands
00006 import sys
00007 import re
00008 import time
00009 import inspect
00010 from tw_utils import *
00011 from matplotlib.font_manager import  FontProperties
00012 
00013 #### usage: python profileplot.py testname RESULT_DIR \
00014 ####               webpage_abspath asciidata processname 
00015 t=[0]
00016 y11=[0]
00017 y22=[0]
00018 numfile=[0]
00019 
00020 testname=sys.argv[1]
00021 RESULT_DIR=sys.argv[2]
00022 webpage=sys.argv[3]
00023 asciidata=sys.argv[4]
00024 casapy_pid = sys.argv[5]
00025 
00026 def handler(signum, frame):
00027     try:
00028         fd.close()  # might not be open yet
00029     except:
00030         pass
00031 
00032     a=inspect.stack()
00033     stacklevel=0
00034     for k in range(len(a)):
00035         if (string.find(a[k][1], 'profileplot.py') > 0):
00036             stacklevel=k
00037             break
00038     myf=sys._getframe(stacklevel).f_globals
00039 #    myf=frame.f_globals
00040     t=myf['t']
00041     y11=myf['y11']
00042     y22=myf['y22']
00043     numfile=myf['numfile']
00044     pl.plot(t,y11,lw=2)
00045     pl.plot(t,y22,lw=2)
00046     if max(y11)>=max(y22):
00047         pl.axis([0.9*min(t),1.1*max(t),0.9*min(y11),1.1*max(y11)])
00048     else:
00049         pl.axis([0.9*min(t),1.1*max(t),0.9*min(y22),1.1*max(y22)])
00050     pl.xlabel('time (sec)')
00051     pl.ylabel('memory footprint') #note virtual vs. resident
00052     font=FontProperties(size='small')
00053     pl.legend(('virtual','resident'),loc=[0.7,0.85], prop=font)
00054     ax2 = pl.twinx()
00055     pl.ylabel('No of open File Descriptors')
00056     ax2.yaxis.tick_right()
00057     pl.plot(t,numfile, 'r-.',lw=2)
00058     pl.legend(['No. of Open FDs'],loc=[0.7,0.8], prop=font)
00059     pl.title('memory usage of casapy for '+testname)
00060 
00061     #s="test-plot.ps" change to PNG for web browser compatibility
00062     #s="test-plot.png"
00063 
00064     #set up special images directory?
00065     if os.path.basename(myf['RESULT_DIR']) == myf['testname']:
00066         png_path=myf['RESULT_DIR']
00067     else:
00068         png_path=myf['RESULT_DIR']+time.strftime('/%Y_%m_%d')
00069 
00070     png_filename=png_path +'/'+myf['testname']+'_profile.png'
00071     if not os.path.isdir(png_path):
00072         os.mkdir(png_path)
00073 
00074     pl.savefig(png_filename);
00075     ht=htmlPub(myf['webpage'], 'Memory profile of '+myf['testname'])
00076     body1=['<pre>Memory profile of run of test %s at %s </pre>'%(myf['testname'],time.strftime('%Y/%m/%d/%H:%M:%S'))]
00077     body2=['']
00078     ht.doBlk(body1, body2,myf['testname']+'_profile.png', 'Profile')
00079     ht.doFooter()
00080 
00081     sys.stdout.flush()
00082 
00083     sys.exit()
00084     return
00085 
00086 # return memory usage in KB
00087 def getmem(pid):
00088     # First get memory info
00089 
00090     lsof = "/usr/sbin/lsof"
00091     if not os.path.isfile(lsof):
00092         lsof = "/usr/bin/lsof"
00093     if not os.path.isfile(lsof):
00094         print "Warning: Could not find lsof at /usr/sbin/lsof or /usr/bin/lsof"
00095 
00096     (errorcode, numoffile) = commands.getstatusoutput(lsof + ' -p ' + str(pid) + ' 2>/dev/null | wc -l')
00097     if errorcode != 0:
00098         numoffile = -1
00099 
00100     (errorcode, mem_virtual)  = commands.getstatusoutput('ps -p ' + str(pid) + ' -o vsz | tail -1')
00101     if errorcode != 0:
00102         mem_virtual = -1
00103     (errorcode, mem_resident) = commands.getstatusoutput('ps -p ' + str(pid) + ' -o rss | tail -1')
00104     if errorcode != 0:
00105         mem_resident = -1
00106 
00107     # Get CPU usage.
00108     # top in batch mode doesn't give accurate numbers
00109     # with just 1 iterations, so do 2 iterations with 1 sec
00110     # delay
00111 
00112     if os.uname()[0] == "Linux":
00113         cmd = 'top -b -d 1 -n2 | grep -E "^Cpu" | tail -1'
00114         (errorcode, a) = commands.getstatusoutput(cmd)   
00115         if len(a)==0 or errorcode != 0:
00116             return -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0
00117         
00118         cpu_us = re.sub('.*[ :]', '', re.sub('%.*', '', a.split(',')[0]))
00119         cpu_sy = re.sub('.*[ :]', '', re.sub('%.*', '', a.split(',')[1]))
00120         cpu_id = re.sub('.*[ :]', '', re.sub('%.*', '', a.split(',')[3]))
00121         cpu_wa = re.sub('.*[ :]', '', re.sub('%.*', '', a.split(',')[4]))
00122 
00123     elif os.uname()[0] == "Darwin":
00124         cmd = 'top -l 2 -s 1 | grep -Eo "CPU.usage.*" | tail -1'
00125         (errorcode, a) = commands.getstatusoutput(cmd)
00126         if len(a)==0 or errorcode != 0:
00127             return -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0
00128         
00129         cpu_us = re.sub('.*[ :]', '', re.sub('%.*', '', a.split(',')[0]))
00130         cpu_sy = re.sub('.*[ :]', '', re.sub('%.*', '', a.split(',')[1]))
00131         cpu_id = re.sub('.*[ :]', '', re.sub('%.*', '', a.split(',')[2]))
00132         cpu_wa = 0 # CPU wait not available from top on Mac
00133     else:
00134         raise Exception, "Unrecognized os.uname()[0] = " + str(os.uname()[0])
00135 
00136     return int(mem_virtual), int(mem_resident), numoffile, \
00137            cpu_us, cpu_sy, cpu_id, cpu_wa
00138 
00139 
00140 
00141 signal.signal(signal.SIGHUP, handler)
00142 signal.signal(signal.SIGTERM, handler)
00143 signal.signal(signal.SIGINT, handler)
00144 
00145 mylabel="memory footprint of casapy"
00146 t1=time.time()
00147 y1=0.5
00148 y2=0.5
00149 
00150 # dump data to ascii file
00151 # (doing so in the signal handler might be too late
00152 #  because the data will be read from publish_summary)
00153 fd = open(asciidata, "w")
00154 fd.write('#time(s) memory_virtual(Mbytes) memory_resident(Mbytes) no_filedesc CPU_user CPU_system CPU_idle CPU_wait\n')
00155 
00156 i=0
00157 
00158 while True:
00159         y1,y2,nfile, cpu_us, cpu_sy, cpu_id, cpu_wa = getmem(casapy_pid)
00160         if (y1 > 0.0):
00161                 time.sleep(2.0)
00162                 tt = time.time()-t1
00163                 t.append(tt)
00164 
00165                 y11.append(y1)
00166                 y22.append(y2)
00167                 numfile.append(nfile)
00168                 fd.write(str(int(round(tt, 0))) + ' ' + \
00169                          str(int(round(y1/1024, 0))) + ' ' + \
00170                          str(int(round(y2/1024, 0))) + ' ' + \
00171                          str(nfile) + ' ' + \
00172                          str(cpu_us) + ' ' + \
00173                          str(cpu_sy) + ' ' + \
00174                          str(cpu_id) + ' ' + \
00175                          str(cpu_wa) + '\n')
00176                 fd.flush()
00177         else:
00178 
00179                 #sleep(10.0)
00180                 time.sleep(3.0)
00181         i+=1
00182