在Linux上使用 Python2 统计显示 KVM 各虚拟机 CPU、内存、磁盘的使用信息及汇总统计后计算剩余可用资源信息
在Linux上使用Python2 统计显示 KVM 各虚拟机 CPU、内存、磁盘的使用信息及汇总统计后计算剩余可用资源信息# 系统 CentOS 7.x# KVM yum 安装的# 脚本 系统自带的 Python2#!/usr/bin/python#_*_ coding:utf8 _*_# V 1.3# CentOS 7.x# yum 安装的 KVM# 系统自带的 Python2import co
·
在Linux上使用 Python2 统计显示 KVM 各虚拟机 CPU、内存、磁盘的使用信息及汇总统计后计算剩余可用资源信息
# 系统 CentOS 7.x
# KVM yum 安装的
# 脚本 系统自带的 Python2
#!/usr/bin/python
#_*_ coding:utf8 _*_
# V 1.3
# CentOS 7.x
# yum 安装的 KVM
# 系统自带的 Python2
import commands
import sys
import os
import re
import xml.etree.ElementTree as ET
Dir_VM_XML = '/etc/libvirt/qemu'
def VM_INFO(F_XML):
tree = ET.ElementTree(file=F_XML) # 读取xml文件
root = tree.getroot() # 根
D = {}
L_VM_DISK_FILE = []
for i in root:
#print("i.tag", i.tag) # 标签名
#print("i.attrib", i.attrib) # 标签说明(字典形式)
#print("i.text", i.text) # 标签值
if i.tag == 'name':
D['NAME'] = i.text
elif i.tag == 'memory':
D['MEM'] = [int(i.text), i.attrib['unit']]
elif i.tag == 'vcpu':
D['VCPU'] = int(i.text)
elif i.tag == 'devices':
D['NET_INT'] = []
D['DISK_FILE'] = []
for ii in i: ## 继续查找下一级标签
if ii.tag == 'disk':
D_disk = ii.attrib
if D_disk['device'] == 'disk': # <disk type='file' device='disk'>
for iii in ii: ## 继续查找下一级标签
if iii.tag == 'source':
D['DISK_FILE'].append(iii.attrib['file'])
L_VM_DISK_FILE.append(iii.attrib['file'])
elif ii.tag == 'graphics':
if ii.attrib['type'] == 'vnc':
VNC_IP = ii.attrib['listen']
if ii.attrib['autoport'] == 'no':
VNC_PORT = ii.attrib['port']
else:
VNC_PORT = 'Unknown'
D['VNC'] = VNC_IP + ':' + VNC_PORT
else:
D['VNC'] = 'NOT FIND'
elif ii.tag == 'interface':
#print("ii tag, attr, text", ii.tag, ii.attrib, ii.text)
D_NET = ii.attrib
for iii in ii:
if iii.tag == 'mac':
D['NET_INT'].append(iii.attrib['address'])
#print("iii tag, attr, text", iii.tag, iii.attrib, iii.text)
L_DISK_VS_DS = VM_DISK_INFO(L_VM_DISK_FILE)
D['DISK_SIZE'] = L_DISK_VS_DS
return(D)
## 累计单个虚拟机全磁盘的分配空间及当前实际使用空间
def VM_DISK_INFO(L_VM_DISK_FILE):
VM_TOT_DISK_VS = 0
VM_TOT_DISK_DS = 0
D = {}
for VM_DISK_FILE in L_VM_DISK_FILE:
CMD = 'qemu-img info ' + VM_DISK_FILE
(ST,OP) = commands.getstatusoutput(CMD)
if ST == 0:
RE_X = '(virtual size(.*))|(disk size(.*))'
R = re.finditer(RE_X, OP)
L_DiskSize = [i.group() for i in R]
for DiskSize in L_DiskSize:
#print DiskSize # virtual size: 200G (214748364800 bytes) 或者 disk size: 1.4G
SP = DiskSize.split(':')
#print SP
K = SP[0]
V = SP[1]
if K == 'virtual size': ## 分配磁盘空间大小
RE_search = re.search('[0-9]+ bytes', V) # 从 ' 200G (214748364800 bytes)' 中提取:1个及以上数字+空格+bytes 的字符串,如 '214748364800 bytes'
if RE_search:
SIZE = float(RE_search.group().split()[0])/1024/1024/1024 # bytes 转成 GB 单位(并转成浮点类型数值)
VM_TOT_DISK_VS += SIZE
else:
print "提取 virtual size 的 bytes 数值失败,先忽略(不计入硬盘总分配空间)", VM_DISK_FILE, DiskSize
elif K == 'disk size': ## 当前实际使用磁盘空间大小
RE_search = re.search('B|K|M|G|T|P', V) # 从 ': 1.4G' 中提取:B K M G T P
if RE_search:
if RE_search.group() == 'B':
SIZE = float(V.split(RE_search.group())[0])/1024/1024/1024
if RE_search.group() == 'K':
SIZE = float(V.split(RE_search.group())[0])/1024/1024
elif RE_search.group() == 'M':
SIZE = float(V.split(RE_search.group())[0])/1024
elif RE_search.group() == 'G':
SIZE = float(V.split(RE_search.group())[0])
elif RE_search.group() == 'T':
SIZE = float(V.split(RE_search.group())[0])*1024
elif RE_search.group() == 'P':
SIZE = float(V.split(RE_search.group())[0])*1024*1024
else:
SIZE = 0
print "识别 disk size 单位失败,先忽略(不计入硬盘总分配空间)", VM_DISK_FILE, DiskSize
VM_TOT_DISK_DS += SIZE
else:
print "识别 disk size 的数值失败,先忽略(不计入硬盘总分配空间)", VM_DISK_FILE, DiskSize
else:
print "WARNING RE过滤结果有多余内容", DiskSize
else:
print "ERROR 执行命令", CMD, "失败", OP
D['TOT_VS'] = VM_TOT_DISK_VS
D['TOT_DS'] = VM_TOT_DISK_DS
return(D)
## 宿主机ARP表转成MAC为KEY,IP为Value的字典
D_MAC_IP = {}
def DEF_D_MAC_IP():
CMD = "arp -n"
(S,O) = commands.getstatusoutput(CMD)
if S == 0:
L_ARP = O.split('\n') # 命令回显内容以换行符合分割做成列表
if len(L_ARP) > 1:
for i in L_ARP[1:]:
ARP = i.split()
IP = ARP[0]
MAC = ARP[2]
if MAC in D_MAC_IP:
D_MAC_IP[MAC].append(IP)
else:
D_MAC_IP[MAC] = [IP]
DEF_D_MAC_IP()
#print(D_MAC_IP)
## 显示程序帮助信息
def HELP_PRINT():
print "可以接受一个参数,控制显示内容"
print sys.argv[0], 't : 不显示各虚拟机详细信息,只显示统计信息'
print sys.argv[0], 'n : 显示各虚拟机网络信息及统计信息'
print sys.argv[0], 's : 显示各虚拟机配置信息及统计信息'
if len(sys.argv) == 1: # 没有参数
HELP_PRINT()
print "没有参数,使用默认显示"
SET_SHOW = 'ALL_INFO'
elif len(sys.argv) == 2:
if sys.argv[1] in ['t', 'tot']:
SET_SHOW = 'TOT_INFO'
elif sys.argv[1] in ['n', 'net']:
SET_SHOW = 'NET_INFO'
elif sys.argv[1] in ['s', 'sys']:
SET_SHOW = 'SYS_INFO'
else:
HELP_PRINT()
print "参数错误,使用默认设置,显示全部内容"
SET_SHOW = 'ALL_INFO'
else:
HELP_PRINT()
print "参数过多,使用默认显示"
SET_SHOW = 'ALL_INFO'
#print SET_SHOW
L_XML = []
L_Dir_File = os.listdir(Dir_VM_XML)
#print L_Dir_File
for F in L_Dir_File:
F_FULLNAME = Dir_VM_XML+'/'+F
if os.path.isfile(F_FULLNAME):
L_XML.append(F_FULLNAME)
#print L_XML
L_D_VM_INFO = []
for i in L_XML:
D_VM_INFO = VM_INFO(i)
#print(D_VM_INFO)
L_D_VM_INFO.append(D_VM_INFO)
#print(L_D_VM_INFO)
## 统计全部虚拟机的资源使用
VMs_TOT_MEM = 0
VMs_TOT_CPU = 0
VMs_TOT_DISK_VS = 0
VMs_TOT_DISK_DS = 0
for i in L_D_VM_INFO:
VMs_TOT_MEM += i['MEM'][0]
VMs_TOT_CPU += i['VCPU']
VMs_TOT_DISK_VS += i['DISK_SIZE']['TOT_VS']
VMs_TOT_DISK_DS += i['DISK_SIZE']['TOT_DS']
## 获取KVM 宿主机自身 CPU MEM 信息
KVM_MEM = 0
CMD = "/usr/bin/free | /usr/bin/grep Mem | awk '{print $2}'"
(S,O) = commands.getstatusoutput(CMD)
if S == 0:
KVM_MEM += int(O)
KVM_CPU = 0
CMD = 'cat /proc/cpuinfo| grep "processor"| wc -l'
(S,O) = commands.getstatusoutput(CMD)
if S == 0:
KVM_CPU += int(O)
## 获取各虚拟机的运行状态
(status,output) = commands.getstatusoutput('virsh list --all')
#print status
#print output
L_VMs_RUN = []
L_VMs_STOP = []
L_VMs_DEFINE = []
if status == 0:
L_output = output.split('\n')
#print L_output[2:-1]
for VM_STATUS in L_output[2:-1]:
#print VM_STATUS.split()
SP = VM_STATUS.split()
NAME = SP[1]
STATUS = SP[2]
L_VMs_DEFINE.append(NAME)
if STATUS == 'running':
L_VMs_RUN.append(NAME)
else:
L_VMs_STOP.append(NAME)
#print "DEFINE", L_VMs_DEFINE
#print "RUN", L_VMs_RUN
#print "STOP", L_VMs_STOP
## 统计全部运行中的虚拟机的资源使用
VMs_RUN_TOT_MEM = 0
VMs_RUN_TOT_CPU = 0
VMs_RUN_TOT_DISK_VS = 0
VMs_RUN_TOT_DISK_DS = 0
for i in L_D_VM_INFO:
if i['NAME'] in L_VMs_RUN:
VMs_RUN_TOT_MEM += i['MEM'][0]
VMs_RUN_TOT_CPU += i['VCPU']
VMs_RUN_TOT_DISK_VS += i['DISK_SIZE']['TOT_VS']
VMs_RUN_TOT_DISK_DS += i['DISK_SIZE']['TOT_DS']
## 统计结果打印
print "=== VMs ==="
for i in L_D_VM_INFO:
VM_MAC = 'NET:'
for j in i['NET_INT']:
if j in D_MAC_IP:
VM_MAC += '[%s - %s]' % (j, D_MAC_IP[j])
else:
VM_MAC += '[%s - noARP]' % j
VM_VNC = 'VMC:' + i['VNC']
#VM_NAME = 'NAME:' + i['NAME']
VM_NET_INFO = '%s | %s |' % (VM_MAC, VM_VNC)
VM_CPU = 'VCPUs:%d' % i['VCPU']
VM_MEM = 'MEM:%d%s' % (i['MEM'][0], i['MEM'][1])
VM_DISK = 'DISK:%d/%dGB' % (i['DISK_SIZE']['TOT_DS'], i['DISK_SIZE']['TOT_VS'])
VM_DISK_FILE = 'DISK_FILEs:%s' % i['DISK_FILE']
VM_SYS_INFO = '%s | %s | %s | %s |' % (VM_CPU, VM_MEM, VM_DISK, VM_DISK_FILE)
#print "VM_NET_INFO", VM_NET_INFO
#print "VM_SYS_INFO", VM_SYS_INFO
if i['NAME'] in L_VMs_RUN:
print "RUN |",
if SET_SHOW == 'NET_INFO':
print VM_NET_INFO, i['NAME']
elif SET_SHOW == 'SYS_INFO':
print VM_SYS_INFO, i['NAME']
elif SET_SHOW == 'TOT_INFO':
print i['NAME']
else:
print i['NAME']
print "\t\t", VM_NET_INFO
print "\t\t", VM_SYS_INFO
print ""
elif i['NAME'] in L_VMs_STOP:
print "STOP |",
if SET_SHOW == 'NET_INFO':
print VM_NET_INFO, i['NAME']
elif SET_SHOW == 'SYS_INFO':
print VM_SYS_INFO, i['NAME']
elif SET_SHOW == 'TOT_INFO':
print i['NAME']
else:
print i['NAME']
print "\t\t", VM_NET_INFO
print "\t\t", VM_SYS_INFO
print ""
else:
print "WARNING undefine VM", i, i['NAME']
print "==="
print "=== ALL VMs 全虚拟机统计 ==="
print "CPU : 总可用数量 %d, 已分配 %d, 剩余可分配 %d" % (KVM_CPU, VMs_TOT_CPU, KVM_CPU - VMs_TOT_CPU)
print "MEM : 总可用内存(GB) %d, 已分配 %d, 剩余可分配 %d" % ((KVM_MEM/1024/1024), VMs_TOT_MEM/1024/1024, (KVM_MEM - VMs_TOT_MEM)/1024/1024)
print "DISK: 总分配(GB) %d, 实际使用 %d" % (VMs_TOT_DISK_VS, round(VMs_TOT_DISK_DS, 2))
print "==="
print "=== RUN VMs 只统计运行中的虚拟机 ==="
print "CPU : 总可用数量 %d, 已分配 %d, 剩余可分配 %d" % (KVM_CPU, VMs_RUN_TOT_CPU, KVM_CPU - VMs_RUN_TOT_CPU)
print "MEM : 总可用内存(GB) %d, 已分配 %d, 剩余可分配 %d" % ((KVM_MEM/1024/1024), VMs_RUN_TOT_MEM/1024/1024, (KVM_MEM - VMs_RUN_TOT_MEM)/1024/1024)
print "DISK: 总分配(GB) %d, 实际使用 %d" % (VMs_RUN_TOT_DISK_VS, round(VMs_RUN_TOT_DISK_DS, 2))
print "==="
更多推荐
已为社区贡献1条内容
所有评论(0)