醉里乾坤大,壶中日月长

Pymon.py

上一篇 / 下一篇  2010-04-06 11:33:50

可以用来监控指定进程的cpu,内存试用率,windows平台下是用pv.exe这个command line小工具,Linux平台下调用的是top,在windows xp sp3和ubuntu 8.04上测试可用

#!/usr/bin/python
# coding=utf-8

import os
import getopt
import subprocess
import logging
import traceback
import sys
import re

#define the const
nt    = 'windows'
posix = 'linux'

#define a global parameter to store the processes' messages
pro_list = []

class message(object):
    '''store the messages about this script. and the develop plan in the further'''
    Version     = '0.1'
    Description = 'In this version, we will just handle monitor process in localhost'
    Plan        = 'We plan to monitor process message in remote machine in the next version --2.0'
    Work_OS     = 'nt or posix'
    Prefix      = '''In windows : you must make sure there is PV.exe in your system32 or the directory witch store
                    the PV.exe is contained by the OS PATH,the website to get the pv.exe is :
                    http://www.teamcti.com/pview/prcview.htm
                    In Linux : make sure the top command was contained by the shell'''

def logInit():
    logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(levelname)s %(message)s',
                    filename=r'Pymon.log',
                    filemode='a+w')     

def get_os():
    '''Get the OS type'''
    return os.name

def spawn(cmd):
    try:
        pipe = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
        utput = pipe.communicate()[0]
        logging.debug("run %s, returncode %s" % (cmd, pipe.returncode))
        logging.debug(output)
        return output
    except:
        logging.error(traceback.format_exc())
        return 'error'
        
class process(object):
    def __init__(self,p_mes):
        self.PID     = None
        self.CPU     = None
        self.MEM     = None
        self.COMMAND = None
   
    def p_record(self):
        #define the logging format
        fs = '%(asctime)s %(levelname)s %(message)s'
        dfs = '%m-%d %H:%M'
        fmt = logging.Formatter(fs, dfs)
        log_pid =logging.getLogger('%s'%(self.PID))
        log = logging.FileHandler('%s.log'%str((self.PID)),'a')
        log.setFormatter(fmt)
        log_pid.addHandler(log)
        log_pid.setLevel(logging.INFO)
        log_pid.info('%-12s %-12s %-12s %-12s' % (self.PID,self.CPU,self.MEM,self.COMMAND))
       
class NTprocess(process):
    def __init__(self,nt_p_mes):
        self.PID    = nt_p_mes[0]
        self.CPU    = nt_p_mes[2]
        self.MEM    = nt_p_mes[3]
        self.COMMAND= nt_p_mes[4]

class Posixprocess(process):
    def __init__(self,posix_p_mes):
        self.PID    = posix_p_mes[1]
        self.CPU    = posix_p_mes[9]
        self.MEM    = posix_p_mes[10]
        self.COMMAND= posix_p_mes[12]
       
def dispatch():
    if get_os() == 'nt':
        return NTPerform()
    elif get_os() == 'posix':
        return PosixPerform()
    else:
        logging.error('The OS can not be supported by the script. now ')
        sys.exit()
       
class Perform(object):  #the basic class to define the interface
    def __init__(self):    
        self.result = 'test'
        global pro_list
   
    def byPname(self,pname):
        pass
   
    def byPid(self,pid):
        pass   
       
class NTPerform(Perform):
   
    def byPname(self,pname):
        cmd = 'pv -o"%i\t%e\t%c2000%%\t%m(K)\t%n"'+' '+pname #Error occurs when use %s to get the pname
        self.result = spawn(cmd)
        if len(self.result.split('\r\n')) > 1: #windows platform. '\r\n',at least this is a empty '',so the len most >1
            #handle the result
            for i in range (len(self.result.split('\r\n'))-1):
                try:
                    pro_list.append(NTprocess(self.result.split('\r\n')[i].split('\t')))
                except:
                    logging.error('Error occurs when create object NTprocess')
                    return 'NTProcess Create Error'
        else:
            logging.debug('The result is empty for process %s'%(pname))
            return 'empty'       
               
           
    def byPid(self,pid):
        cmd = 'pv -o"%i\t%e\t%c2000%%\t%m(K)\t%n" -i '+ str(pid) #this is error occurs when use format string~
        self.result = spawn(cmd)
        if len(self.result.split('\r\n'))==2:
            try:
                pro_list.append(NTprocess(self.result.split('\r\n')[0].split('\t')))
            except:
                logging.error('Error occurs when create object NTprocess')
                return 'NTProcess Create Error'
        else:
            logging.debug('The result is empty for pid %s'%(pid))
            return 'empty'
           

class PosixPerform(Perform):
   
    def byPname(self,pname):
        cmd = 'top -b -n 1|grep %s|grep -v grep'%(pname)
        self.result = spawn(cmd)
        if len(self.result.split('\n')) > 1:    #in the linux platfrom . use '\n' to divide the result,at least this is a empty '' ,so the len most >1
            for i in range(len(self.result.split('\n'))-1):
                try :
                    pro_list.append(Posixprocess(re.split(r'\s+',self.result.split('\n')[i])))
                except:
                    logging.error('Error occurs when create object Posixprocess')
                    return 'Posixprocess Create Error'
        else:
            logging.debug('The result is empty for process %s'%(pname))
            return 'empty'
   
    def byPid(self,pid):
        cmd = 'top -b -n 1 -p %d|sed -n "8p"'%(int(pid)) #if not the grep, this will return the top title about the os,so need the grep
        self.result = spawn(cmd)
        if len(self.result.split('\n')) == 2:
            try:
                 pro_list.append(Posixprocess(re.split(r'\s+',self.result.split('\n')[0])))
            except:
                logging.error('Error occurs when create object Posixprocess'+traceback.format_exc())
                return 'Posixprocess Create Error'
        else:
            logging.debug('The reuslt is empty for process %s'%(pid))
            return 'empty'
       
#Init the log file in the directory where contains the script,the log file's name is pymon.log    
logInit()
  
if __name__ == '__main__':
    pid   = None
    pname = None
   
    #handle the parameter passed by the user
    if len(sys.argv) < 2:
        print 'Useage: python pymon.exe -p pid or python pymon.exe -n processname or python pymon.exe -p pid -n processname'  
        sys.exit()
    opt,args = getopt.getopt(sys.argv[1:], 'p:n:')
    if len(opt) == 2:
        print 'We will handle the process name and ignore the pid'
        for o,v in opt:
            if o == '-n':
                pname = v
    else:
        for o,v in opt:
            if o == '-p':
                if ',' not in v:
                    pid = v
                else:
                    pid = v.split(',')
            elif o == '-n':
                pname = v
            else:
                logging.error('The parameter that we can not handle %s'%(o))
    #get the object
    platform. = dispatch() 
         
    if pname:
        oplatform.byPname(pname)
    elif pid:
        if isinstance(pid,str):
            oplatform.byPid(pid)
        elif isinstance(pid,list):
            for i in pid:
                oplatform.byPid(i)
    else:
        logging.error('Please give me a parameter, OK?')
        sys.exit()
   
    #record the message to log file
    if len(pro_list) == 0:
        logging.debug('This is no process match the search condition')  
    else:
        for i in pro_list:
            i.p_record()
       
   
                

TAG:

逍遥客 引用 删除 xiaoyaoke   /   2010-04-06 22:18:31
原帖由假装不在于2010-04-06 20:20:32发表
  想不到这么长都能贴出来。


长吗?
最近做的东西里这是最短的,只不过具有普遍意义
假装不在 引用 删除 假装不在   /   2010-04-06 20:20:32
  想不到这么长都能贴出来。
 

评分:0

我来说两句

日历

« 2024-03-28  
     12
3456789
10111213141516
17181920212223
24252627282930
31      

数据统计

  • 访问量: 72734
  • 日志数: 106
  • 建立时间: 2009-06-05
  • 更新时间: 2011-09-09

RSS订阅

Open Toolbar