初识OpenStack两周,于它已没有初见时的神秘感,褪去层层面纱以后,渐识它的强大,决心以彼为刀剑,征战云计算的疆场,今夜,号角吹响,且奏序章。html
用OpenStack 建立虚拟实例后,须要对这些实例进行监控,本文所讲的是KVM环境下利用OpenStack集成的Libvirt API对虚拟机的CPU,内存,磁盘使用率以及网络上传下载速度进行监控。python
闲话少说,直接正题。linux
1 对CPU的监控网络
Python 代码app
import libvirt
import os
import time
conn=libvirt.open("qemu:///system")
if conn==None:
print "fail to connect hypervisor"
sys.exit(1)
try:
dom0=conn.lookupByID(85)#根据OpenStack建立的Instance ID获得相应的Domain对象
except:
print "fail to find the domain by ID"
sys.exit(1)
Pstart_time=time.time() #取当前时间
Dstart_time=dom0.info()[4]#直接获取DomainInfo中的CPU时间信息
time.sleep(2)
Dstop_time=dom0.info()[4]
Pstop_time=time.time()
core_num=int(dom0.info()[3])#获取DomainIndo中的core数量信息dom
#CPU利用率计算公式-CPU时间差/时间间隔/1000000000/核的数量*100=CPU利用率
cpu_usage=(Dstart_time-Dstop_time)/(Pstart_time-Pstop_time)/1000000000/core_num*100
cpu_usage=cpu_usage if (cpu_usage>0) else 0.0
cpu_usage=cpu_usage if (cpu_usage<100) else 100.0
print cpu_usage函数
2 对内存的监控this
python代码云计算
def get_memory(pid):#定义获取当前已使用的内存的函数
mem=0spa
#linux下 /proc/pid(进程ID)/smaps 下保存的是进程内存映像信息,比同一目录下的maps文件更详细些
for line in file('/proc/%d/smaps' % int(pid),'r'):
if re.findall('Private_',line):
#统计Private内存信息量
mem+=int(re.findall('(\d+)',line)[0])
return mem
#根据实例名获取进程ID
pid=(os.popen("ps aux|grep "+dom0.name()+" | grep -v 'grep' | awk '{print $2}'").readlines()[0])
memstatus=get_memory(pid)
memusage='%.2f' % (int(memstatus)*100.0/int(dom0.info()[2]))
print memusage
验证方法: 能够SSH到相应的虚拟实例上,若是是Linux 系统能够用free -m指令查看内存使用率
3 对磁盘的监控
建立虚拟机应用实例时,会生成相应的XML文件来代表实例的信息
def get_devices(dom,path,devs):#该函数用于获取XML中某节点的值
tree=ElementTree.fromstring(dom.XMLDesc(0))#将XML文件转换为XML树对象
devices=[]
for target in tree.findall(path):
dev=target.get(devs)
if not dev in devices:
devices.append(dev)
return devices
def get_blockStats(dom):#获取磁盘状态信息函数 包含磁盘读入的总比特数和写出的总比特数
block_status={}
disks=get_devices(dom,"devices/disk/target","dev")
for block in disks:
block_status[block]=dom.blockStats(block)
return block_status
block_status0={}
block_status1={}
block_status0=get_blockStats(dom0)
time.sleep(2)
block_status1=get_blockStats(dom0)
block_info=[]
for block in get_devices(dom0,"devices/disk/source","file"):
block_info.append(dom0.blockInfo(block,0))#获取磁盘信息 其中0为默认传入的参数
for domBlockInfo in block_info:
print "logical size in bytes :%s" % domBlockInfo[0]
print "highest allocated extent in bytes :%s" % domBlockInfo[1]
print "physical size in bytes :%s" % domBlockInfo[2]
print "disk usage :%s" % str(domBlockInfo[1]/1.0/domBlockInfo[0]*100)[:5]
for block in get_devices(dom0,"devices/disk/target","dev"):
print "rd_speed :%s" % str((block_status1[block][1]-block_status0[block][1])/2048)
print "wr_speed :%s" % str((block_status1[block][3]-block_status0[block][3])/2048)
验证方法: 能够SSH到相应的虚拟实例上,若是是Linux 系统能够用df -h指令查看磁盘使用率
4 对网络的监控
def get_nicInfo(nics):#获取网络信息包括Receive的总比特数和Transmit的总比特数
net_status={}
#经过 cat /proc/net/dev 命令查看网络信息
for nic in nics:
net_status[nic]=[os.popen("cat /proc/net/dev |grep -w '"+nic+"' |awk '{print $10}'").readlines()[0][:-1],os.popen("cat /proc/net/dev |grep -w '"+nic+"' |awk '{print $2}'").readlines()[0][:-1]]
return net_status
net_status0={}
net_status1={}
#获取网卡名称
nics=get_devices(dom0,"devices/interface/target","dev")
net_status0=get_nicInfo(nics)
time.sleep(2)
net_status1=get_nicInfo(nics)
for nic in nics:
print "netcard_name :%s" % nic
print "transmit_speed :%s" % str((int(net_status1[nic][0])-int(net_status0[nic][0]))/2048)
print "receive_speed :%s" % str((int(net_status1[nic][1])-int(net_status0[nic][1]))/2048)
初次写博,请各位大神手下留情,请轻喷!
参考:
Libvirt 官网API定义
virDomainBlockInfo
struct virDomainBlockInfo {
unsigned long long | capacity | logical size in bytes of the block device backing image |
unsigned long long | allocation | highest allocated extent in bytes of the block device backing image |
unsigned long long | physical | physical size in bytes of the container of the backing image |
}
virDomainBlockStatsStruct
struct virDomainBlockStatsStruct {
long long | rd_req | number of read requests |
long long | rd_bytes | number of read bytes |
long long | wr_req | number of write requests |
long long | wr_bytes | number of written bytes |
long long | errs | In Xen this returns the mysterious 'oo_req'. |
}