监测程序的cpu使用率 – IT夜班车

监测程序的cpu使用率

下面的python脚本程序用来统计某个程序的在某一段时间的cpu的使用率,然后画出一张统计表,并且保存成cpu,这样就不用你用肉眼一直使用top来查看。由于本博客禁止复制代码,所以这里我提供大家下载此份代码

下载代码

下载之后将后缀改为py,也就是最后为

render.py

然后运行

python render.py 参数

具体请使用

$ python render.py -h

process name must be provided
usage: python render.py [options]
options:
    -h help
    -t total time
    -i interval to pick up cpu usage
    -p process name
    -r thread name
    -l 1: mark X axis with time, 0: without time
    -m mode, by default, use 'top', value can be top or ps

查看。

最简单的就是提供程序的名字,例如

python render.py firefox

 

"""

this script is used to render cpu usage
to get cpu usage, here use top rather than ps because ps got bad accuarcy, for top got firefox's cpu
usage, 8.3 or 8.4, while ps always got 6.2
"""

import sys
import matplotlib as mpl # render diagram to pdf rather than x window because our target machine may not allowed using x11
mpl.use('Agg') # this must called before import pylab
import pylab
import subprocess
import time
import datetime
import getopt
import re


TotalTime = 30 # seconds
Interval = 1 # seconds
MoitorProcess = ""
LabelYTime = '0'
ThreadName = ""

def getProcessCPUUsage( processName ):
    global Interval

    p1 = subprocess.Popen([“top”, “-n”, str(Interval), “-b”], stdout=subprocess.PIPE)
    p2 = subprocess.Popen([“grep”, processName], stdin=p1.stdout, stdout=subprocess.PIPE)
    p3 = subprocess.Popen([“grep”, “-v”, “grep”], stdin=p2.stdout, stdout=subprocess.PIPE)
    # here we just extact first process that is matched with process name
    p4 = subprocess.Popen([“awk”, “{if( NR==1 ) print $9}”], stdin=p3.stdout, stdout=subprocess.PIPE)
    usg = p4.communicate()[0]
    print "process cpu: " , usg
    # use regular express remove none decimal charactar
    non_decimal = re.compile(r'[^\d.]+')
    cpu = non_decimal.sub('', usg )
    return float( cpu )

def getProcessId( processName ):
    p1 = subprocess.Popen([“top”, “-n”, “1”, “-b”], stdout=subprocess.PIPE)
    p2 = subprocess.Popen([“grep”, processName], stdin=p1.stdout, stdout=subprocess.PIPE)
    p3 = subprocess.Popen([“grep”, “-v”, “grep”], stdin=p2.stdout, stdout=subprocess.PIPE)
    # here we just extact first process that is matched with process name
    p4 = subprocess.Popen([“awk”, “{if( NR==1 ) print $1}”], stdin=p3.stdout, stdout=subprocess.PIPE)
    pid = p4.communicate()[0]
    return pid

def getProcessThread( pid, threadName ):
    pid=str(int(pid)) # force tick out none-decimal
    p1 = subprocess.Popen([“top”, “-p”, pid,  “-n”, str(Interval), “-H”, “-b”], stdout=subprocess.PIPE)
    p2 = subprocess.Popen([“grep”, threadName], stdin=p1.stdout, stdout=subprocess.PIPE)
    p3 = subprocess.Popen([“grep”, “-v”, “grep”], stdin=p2.stdout, stdout=subprocess.PIPE)
    p4 = subprocess.Popen([“wc”, “-l”], stdin=p2.stdout, stdout=subprocess.PIPE)
    if '0' == p4.communicate()[0]:
        return False
    else:
        return True

def getProcessThreadCPUUsage( processName, threadName ):
    global Interval

    pid = getProcessId( processName )
    if( '' == pid or None == pid ):
        print "cannot find process: ", processName
        return    
    #print 'pid:', pid
    pid=str(int(pid)) # force tick out none-decimal
    p1 = subprocess.Popen([“top”, “-p”, pid,  “-n”, str(Interval), “-H”, “-b”], stdout=subprocess.PIPE)
    p2 = subprocess.Popen([“grep”, threadName], stdin=p1.stdout, stdout=subprocess.PIPE)
    p3 = subprocess.Popen([“grep”, “-v”, “grep”], stdin=p2.stdout, stdout=subprocess.PIPE)
    # here we just extact first process that is matched with process name
    p4 = subprocess.Popen([“awk”, “{if( NR==1 ) print $9}”], stdin=p3.stdout, stdout=subprocess.PIPE)
    usg = p4.communicate()[0]
    if usg == '':
        print "cannot find thread: ", threadName
        return
    print "thread cpu: " , usg
    # use regular express remove none decimal charactar
    non_decimal = re.compile(r'[^\d.]+')
    cpu = non_decimal.sub('', usg )
    return float( cpu )

def renderFromFile( fileName ):
    print "input file: ", fileName
    # generate data
    i = 0
    x = list()
    y = list()
    with open( fileName, 'r' ) as pf:
        for line in pf:
            y.append( round( float( line ), 2))
            x.append( i )
            i += 1
    pylab.plot( x, y )
    #pylab.show()
    pylab.savefig( fileName + '.png' )

def renderFromListXY( listX, listY ):
    # generate data
    #i = 0
    #x = list()
    #y = list()
    #for el in data:
    #    y.append( round( float( el ), 2))
    #    x.append( i )
    #    i += 1

    global MoitorProcess
    pylab.xlabel( "time( in seconds )" )
    pylab.ylabel( "cpu usage" )
    pylab.title( "CPU Usage of Process( " + MoitorProcess + ":" + ThreadName + " )" )
    pylab.plot( listX, listY, aa=True, label="CPU Usage of " + MoitorProcess )
    pylab.gcf().autofmt_xdate()
    #pylab.show()

def renderFromListY( listY ):
    # generate data
    i = 0
    x = list()
    y = list()
    for el in listY:
        y.append( round( float( el ), 2))
        x.append( i )
        i += 1

    global MoitorProcess
    pylab.xlabel( "time( in seconds )" )
    pylab.ylabel( "cpu usage" )
    pylab.title( "CPU Usage of Process( " + MoitorProcess + ":" + ThreadName + " )" )
    pylab.plot( x, y, aa=True )
    pylab.gcf().autofmt_xdate()
    #pylab.show()

def savePlot( processName, threadName ):
    if threadName == '':
        pylab.savefig( processName + '.png' )
    else:
        pylab.savefig( processName + '-' + threadName + '.png' )


def usage():
    print "usage: python render.py [options]"
    print "options:"
    print "    -h help"
    print "    -t total time"
    print "    -i interval to pick up cpu usage"
    print "    -p process name"
    print "    -r thread name"
    print "    -l 1: mark X axis with time, 0: without time"
    print "    -m mode, by default, use 'top', value can be top or ps"
    sys.exit( 0 )

def parseOptions( argv ):
    argv.remove( argv[0])
    optlist, args = getopt.getopt(argv, 'ht:i:p:r:l:m:')
    bTotalTime = False
    bInterval = False
    bProcessName = False
    bLabelYTime = False
    bThreadName = False

    try:
        for opt in optlist:
            if opt[0] == '-h':
                usage()
                return
            if opt[0] == '-t':
                global TotalTime
                TotalTime = int(opt[1])
                bTotalTime = True
            if opt[0] == '-i':
                global Interval
                Interval = int(opt[1])
                bInterval = True
            if opt[0] == '-p':
                global MoitorProcess
                MoitorProcess = opt[1]
                bProcessName = True
            if opt[0] == '-r':
                global ThreadName
                ThreadName = opt[1]
                bThreadName = True
            if opt[0] == '-l':
                global LabelYTime
                LabelYTime = opt[1]
                bLabelYTime = True
            if opt[0] == '-m':
                pass
            else:
                pass
        if bProcessName == False:
            print "process name must be provided"
            usage()
            return
        if bTotalTime == False:
            print "total time not specified, use default value – 30 seconds"
        if bInterval == False:
            print "interval not provided, use default value – 1 second"
        if bLabelYTime == False:
            print "draw diagram without time"
        else:
            print "draw diagram with time"
    except Exception as e:
        #print "got exception: " + e.message()
        usage()
        

def main( argv ):
    # get input file
    #fileName = argv[1]
    #renderFromFile( fileName )
    parseOptions( argv )

    global TotalTime
    global Interval
    global MoitorProcess  
    global LabelYTime
    global ThreadName

    # check if process or thread exists, if not exit program
    pid = getProcessId( MoitorProcess )
    if '' == pid:
        print "cannot find process: " + MoitorProcess
        sys.exit( 0 )
    if False == getProcessThread( pid, ThreadName ):
        print "cannot find thread: " + ThreadName
        sys.exit( 0 )

    listUage = list()
    listTime = list()
    count = TotalTime / Interval
    print "capture data…."
    print "total time: ", TotalTime, " interval: ", Interval
    for it in range( count ):
        if ThreadName != "":
            usage = getProcessThreadCPUUsage( MoitorProcess, ThreadName )
        else:
            usage = getProcessCPUUsage( MoitorProcess )
        listUage.append( usage )
        #tm = time.localtime()
        #listTime.append( str(tm.tm_hour)+":"+str(tm.tm_min)+":"+str(tm.tm_sec))
        listTime.append( datetime.datetime.now())
        #time.sleep( Interval )
    
    # render
    if LabelYTime == '1':
        renderFromListXY( listTime, listUage )
    else:
        renderFromListY( listUage )
    savePlot( MoitorProcess, ThreadName  )


if __name__ == "__main__":
    main( sys.argv )

 

版权所有,禁止转载. 如需转载,请先征得博主的同意,并且表明文章转载自:IT夜班车,否则按侵权处理.

    分享到:

Leave a Reply

Your email address will not be published. Required fields are marked *