被同事问到了一个性能监控的问题,干脆用Python写了一个模拟PerfMon的东西,由于没投入使用,暂时没有各种验证和优化,方法是直接使用pdh的接口,activepython中win32pdh(win32pdhutil)。不多说了,直接贴代码,api文档里有接口的说明。
#encoding:utf-8 #created by zhangyi import time import win32api, win32pdhutil, win32con import win32pdh, string import os from prettytable import PrettyTable class PerfMon(object): def __init__(self): self.object='Process' #self.proc_dict={} self.items=[ #CUP u'% Processor Time', #process related u'ID Process', u'Creating Process ID', #memory u'Working Set - Private', u'% User Time', u'% Privileged Time', u'Pool Paged Bytes', u'Pool Nonpaged Bytes', u'Handle Count', u'Virtual Bytes Peak', u'Virtual Bytes', u'Page Faults/sec', u'Working Set Peak', u'Working Set', u'Page File Bytes Peak', u'Page File Bytes', u'Private Bytes', u'Thread Count', u'Priority Base', u'Elapsed Time', #IO read/write u'IO Read Operations/sec', u'IO Write Operations/sec', u'IO Data Operations/sec', u'IO Other Operations/sec', u'IO Read Bytes/sec', u'IO Write Bytes/sec', u'IO Data Bytes/sec', u'IO Other Bytes/sec', ] @property def proc_list(self): try: junk, instances = win32pdh.EnumObjectItems(None,None,self.object, win32pdh.PERF_DETAIL_WIZARD) return instances except: raise COMException("Problem getting process list") @property def proc_dict(self): rect={} for instance in self.proc_list: if rect.has_key(instance): rect[instance] = rect[instance] + 1 else: rect[instance]=0 return rect def get_info(self): Counts=[] for instance, max_instances in self.proc_dict.items(): for inum in xrange(max_instances+1): countOfIns=['%s#%d'%(instance,inum)] for item in self.items: try: hq = win32pdh.OpenQuery() # initializes the query handle path = win32pdh.MakeCounterPath( (None,self.object,instance, None, inum, item) ) counter_handle=win32pdh.AddCounter(hq, path) #convert counter path to counter handle win32pdh.CollectQueryData(hq) #time.sleep(0.01)#collects data for the counter win32pdh.CollectQueryData(hq) type, val = win32pdh.GetFormattedCounterValue(counter_handle, win32pdh.PDH_FMT_LONG) #proc_ids.append(instance+'\t'+str(val)) countOfIns.append(val) win32pdh.CloseQuery(hq) except Exception as e: print e #raise COMException("Problem getting process id") pass Counts.append(countOfIns) return Counts def ShowInfo(self): infos=self.get_info() items=self.items items.insert(0, 'Process') x=PrettyTable(items) for info in infos: x.add_row(info) print x if __name__=="__main__": perfCount=PerfMon() perfCount.ShowInfo()
结果如下: