10月开始学习python, 学习一段时间之后,发现python真的是一门非常优美,开发迅速的语言,  漂亮的缩进, 功能强大的模块,丰富的图形库, 同时还能自己用c/c++添加你需要的扩展。

    10月28号的, 在熟悉了这么一段时间后, 简单的用python+wxPython写了一个linux下的系统监控程序,  主要监控系统的cpu,内存,网络流量,磁盘, 主要是直接分析proc来获取各种信息。 然后图形界面是wxPython, 功能简单,直观。 

如图(各种数据都是每秒钟刷新一次):

 

贴出监控的代码,图形界面的就不贴了,欢迎大家指点:

 

代码
import threading,re,time,sys,os
from subprocess import *
from shlex import split

#global Variables
prev_cpu_info = {"user":0,"system":0,"idle":0,"iowait":0}
cpu_stat
= []
prev_partition_info
= []
HZ
= 100
SLEEP_TIME
= 3
prev_net_info
= {"in":0,"out":0}

class SysMonitor(threading.Thread):
def __init__(self,name,eventList,eventListMutex):
threading.Thread.
__init__(self)
self.name
= name
self.eventList
= eventList
self.eventListMutex
= eventListMutex
self.running
= True
self.runningMutex
= threading.Lock()

def stop(self):
self.runningMutex.acquire()
self.running
= False
self.runningMutex.release()

def calculate_deltams(self):
ncpu
= self.get_numbers_of_cpu()

if len(cpu_stat) == 0:
raise Exception("Please run check_cpu() at first!")

deltams
= 1000.0 * ((cpu_stat['user'] + cpu_stat['system'] + cpu_stat['idle'] + cpu_stat['iowait']) - (prev_cpu_info['user'] + prev_cpu_info['system'] + prev_cpu_info['idle'] + prev_cpu_info['iowait'])) / ncpu / HZ

return deltams

def get_numbers_of_cpu(self):
try:
cpufp
= file("/proc/cpuinfo")
ncpu
= 0
while True:
line
= cpufp.readline()
if len(line) < 1:
break
if re.search(r"processor\t:",line) != None:
ncpu
+= 1
finally:
cpufp.close()
return ncpu

def get_cpu_stat(self):
cpu_info
= {
"user" : 0,
"system": 0,
"idle" : 0,
"iowait": 0
}

try:
cpustatfp
= file("/proc/stat")
line
= split(cpustatfp.readline())
cpu_info[
'user'] = float(line[1]) + float(line[2])
cpu_info[
'system'] = float(line[3]) + float(line[6]) + float(line[7])
cpu_info[
'idle'] = float(line[4])
cpu_info[
'iowait'] = float(line[5])

finally:
cpustatfp.close()

return cpu_info

def check_cpu(self):
global prev_cpu_info,cpu_stat
cpu
= {
"user" : 0,
"system": 0,
"idle" : 0,
"iowait": 0
}

if prev_cpu_info['system'] == 0:
prev_cpu_info
= self.get_cpu_stat()
time.sleep(
1)
else:
prev_cpu_info
= cpu_stat

cpu_stat
= self.get_cpu_stat()

cpu[
'user'] = cpu_stat['user'] - prev_cpu_info['user']
cpu[
'system'] = cpu_stat['system'] - prev_cpu_info['system']
cpu[
'idle'] = cpu_stat['idle'] - prev_cpu_info['idle']
cpu[
'iowait'] = cpu_stat['iowait'] - prev_cpu_info['iowait']


total
= (cpu['user'] + cpu['system'] + cpu['idle'] + cpu['iowait'] )

cpu[
'user'] = cpu['user'] / total * 100
cpu[
'system'] = cpu['system'] / total * 100
cpu[
'idle'] = cpu['idle'] / total * 100
cpu[
'iowait'] = cpu['iowait'] / total * 100

return cpu

def get_disk_stat(self):
diskfp
= open('/proc/diskstats')
all_partition
= []
curr
= {
"major":0,
"minor":0,
"name" : None, #disk name
"rd_ios" : 0, #read I/O operation
"rd_merges" : 0, #readed merged
"rd_sectors" : 0, #sectors readed
"rd_ticks" : 0, #time in queue and server for read
"wr_ios" : 0, #write I/O operation
"wr_merges" : 0, #write merged
"wr_sectors" : 0, #sectors writed
"wr_ticks" : 0, #time in queue and server for write
"ticks" : 0, #time of request in queue
"aveq" : 0 #average queue length
}
while True:
line
= split(diskfp.readline())
if len(line) == 0:
break
if int(line[3]) == 0:
continue
curr[
'major'] = line[0]
curr[
'minor'] = line[1]
curr[
'name'] = line[2]
curr[
'rd_ios'] = float(line[3])
curr[
'rd_merges'] = float(line[4])
curr[
'rd_sectors'] = float(line[5])
curr[
'rd_ticks'] = float(line[6])
curr[
'wr_ios'] = float(line[7])
curr[
'wr_merges'] = float(line[8])
curr[
'wr_sectors'] = float(line[9])
curr[
'wr_ticks'] = float(line[10])
curr[
'ticks'] = float(line[11])
curr[
'aveq'] = float(line[12])

all_partition.append(curr.copy())

return all_partition

def check_disk(self):
global prev_partition_info
DISK_STAT
= []
deltams
= self.calculate_deltams()

curr_partition_info
= self.get_disk_stat()
if len(prev_partition_info) == 0:
prev_partition_info
= curr_partition_info
curr_partition_info
= self.get_disk_stat()

partition_num
= len(curr_partition_info)
i
= 0
while i < partition_num:
disk_info
= curr_partition_info[i]
prev_disk_info
= prev_partition_info[i]

rd_ios
= disk_info['rd_ios'] - prev_disk_info['rd_ios']
rd_merges
= disk_info['rd_merges'] - prev_disk_info['rd_merges']
rd_sectors
= disk_info['rd_sectors'] - prev_disk_info['rd_sectors']
rd_ticks
= disk_info['rd_ticks'] - prev_disk_info['rd_ticks']
wr_ios
= disk_info['wr_ios'] - prev_disk_info['wr_ios']
wr_merges
= disk_info['wr_merges'] - prev_disk_info['wr_merges']
wr_sectors
= disk_info['wr_sectors'] - prev_disk_info['wr_sectors']
wr_ticks
= disk_info['wr_ticks'] - prev_disk_info['wr_ticks']
ticks
= disk_info['ticks'] - prev_disk_info['ticks']
aveq
= disk_info['aveq'] - prev_disk_info['aveq']

# prev_disk_info = disk_info #store the old info
prev_partition_info[i] = curr_partition_info[i]
i
= i + 1
n_ios
= rd_ios + wr_ios
n_ticks
= rd_ticks + wr_ticks
n_kbytes
= (rd_sectors + wr_sectors) / 2.0

queue
= aveq / deltams
if n_ios:
size
= n_kbytes / n_ios
wait
= n_ticks / n_ios
else:
size
= 0.0
wait
= 0.0

busy
= 100.0 * ticks / deltams

if busy > 100.0:
busy
= 100

# print rd_sectors,wr_sectors

readPerSec
= str(1000 * rd_sectors / deltams / 2.0 * 1024)
writePerSec
= str(1000.0 * wr_sectors / deltams / 2.0 * 1024)

readPerSec
= readPerSec[:readPerSec.find(".") + 3]
writePerSec
= writePerSec[:writePerSec.find(".") + 3]


#calculate total size and free size for every partition
try:
mounts
= open("/etc/mtab")
#initialize
total_size = 0
free_size
= 0
while True:
line
= mounts.readline().strip()
if len(line) <1:
break
if line.find(disk_info['name'] + " ") != -1:
line
= line.split()
s
= os.statvfs(line[1])
total_size
= s.f_bsize * s.f_blocks #unit : bytes
free_size = s.f_bsize * s.f_bavail #
break

finally:
mounts.close()

DISK_STAT.append({
"name":disk_info["name"],"total_size":total_size,"free_size":free_size,"readPerSec":readPerSec,"writePerSec":writePerSec,"wait":wait,"queue":queue,"size":size})

return DISK_STAT

def get_net_stat(self,eth):
try:
netfp
= file("/proc/net/dev")
while True:
line
= netfp.readline()
if re.search(eth,line) != None:
line
= split(line[7:])
netin
= int(line[0])
netout
= int(line[8])
break
finally:
netfp.close()

return netin,netout

def checkNet(self):
global prev_net_info
NET_STATS
= []
net_stat
= self.get_net_stat('wlan0') #Caution!!! This should be the Ethernet card in use!!!

if prev_net_info['in'] == 0 and prev_net_info['out'] == 0:
prev_net_info[
'in'] = net_stat[0]
prev_net_info[
'out'] = net_stat[1]

NET_STATS.append((net_stat[0]
- prev_net_info['in']) / SLEEP_TIME )
NET_STATS.append((net_stat[
1] - prev_net_info['out']) / SLEEP_TIME )

prev_net_info[
'in'] = net_stat[0]
prev_net_info[
'out'] = net_stat[1]

return NET_STATS

def checkMem(self):

#the memory status file
MEM_FILE="/proc/meminfo"

#default status
MEM_STATUS={
"MemTotal":0,
"MemFree":0,
"Cached":0,
"SwapCached":0,
"Active":0,
"Inactive":0,
"Inact_dirty":0,
"Inact_clean":0,
"HighTotal":0,
"LowTotal":0,
"SwapTotal":0,
"SwapFree":0
}

try:
fd
= file(MEM_FILE,"r")
mem_info_list
= fd.readlines()
PATTERN
= re.compile(r"^(\w+):\s*(\d+)\s*(\w+)") #e.g:MemTotal: 2061480 kB
for line in mem_info_list:
#DEBUG
res = PATTERN.match(line)
if res:
var_list
= res.groups()
if MEM_STATUS.has_key(var_list[0]):
MEM_STATUS[var_list[0]]
= var_list[1]
fd.seek(0)
finally:
fd.close()

return MEM_STATUS


def run(self):
while True:
self.runningMutex.acquire()
if not self.running:
self.runningMutex.release()
break
self.runningMutex.release()

cpuStatus
= self.check_cpu()
diskStatus
= self.check_disk()
netStatus
= self.checkNet()
memStatus
= self.checkMem()

#add those status to eventList
# print cpuStatus
# print memStatus
# print diskStatus
# print netStatus


self.eventListMutex.acquire()
while len(self.eventList) > 0:
del self.eventList[0]
self.eventList.append({
"cpu":cpuStatus,"mem":memStatus,"disk":diskStatus,"net":netStatus}) #Changed!!! trasform the dictionary to string!!!
self.eventListMutex.release()

#Just for test
time.sleep(SLEEP_TIME)

if __name__ == '__main__':
monitor
= SysMonitor('SysMonitor',[],threading.Lock())
monitor.start()

 

 

posted on 2010-11-02 22:36  Junw_china  阅读(5564)  评论(9编辑  收藏  举报