获取操作系统信息应该是运维的基础工作了,我认为作为一个运维人员,对自己所管理的机器配置应该是很清楚的,因为这对我们快速处理问题很有帮助,比如随着业务增长,突然某些机器负载上涨的厉害,这时候要排查原因,除了从应用程序、架构上分析外,当前硬件性能的分析应该是必不可少的一环,之前我写过一篇用第三方模块psutil来获得系统信息,但有个问题就是每台就机器都要安装这个模块,否则运行会报错,那今天我们就来个清爽版的,不用第三方模块,用python自带模块和系统提供的运行信息来获取我们需要的信息,这个脚本除了硬件外,还抓取了当前系统进程数和网卡流量功能,所以这个版本实现的功能基本对应了之前psutil实现的内容,多的不说了,直接贴代码:
#!/usr/bin/env python
from collections import OrderedDict
from collections import namedtuple
import os
import glob
import re
def cpuinfo():
cpuinfo=OrderedDict()
procinfo=OrderedDict()
nprocs = 0
with open('/proc/cpuinfo') as f:
for line in f:
if not line.strip():
cpuinfo['proc%s' % nprocs] = procinfo
nprocs=nprocs+1
procinfo=OrderedDict()
else:
if len(line.split(':')) == 2:
procinfo[line.split(':')[0].strip()] = line.split(':')[1].strip()
else:
procinfo[line.split(':')[0].strip()] = ''
return cpuinfo
def meminfo():
meminfo=OrderedDict()
with open('/proc/meminfo') as f:
for line in f:
meminfo[line.split(':')[0]] = line.split(':')[1].strip()
return meminfo
def netdevs():
with open('/proc/net/dev') as f:
net_dump = f.readlines()
device_data={}
data = namedtuple('data',['rx','tx'])
for line in net_dump[2:]:
line = line.split(':')
if line[0].strip() != 'lo':
device_data[line[0].strip()] = data(float(line[1].split()[0])/(1024.0*1024.0),
float(line[1].split()[8])/(1024.0*1024.0))
return device_data
def process_list():
pids = []
for subdir in os.listdir('/proc'):
if subdir.isdigit():
pids.append(subdir)
return pids
dev_pattern = ['sd.*','xv*']
def size(device):
nr_sectors = open(device+'/size').read().rstrip('\n')
sect_size = open(device+'/queue/hw_sector_size').read().rstrip('\n')
return (float(nr_sectors)*float(sect_size))/(1024.0*1024.0*1024.0)
def detect_devs():
for device in glob.glob('/sys/block/*'):
for pattern in dev_pattern:
if re.compile(pattern).match(os.path.basename(device)):
print('Device:: {0}, Size:: {1} GiB'.format(device, size(device)))
if __name__=='__main__':
cpuinfo = cpuinfo()
for processor in cpuinfo.keys():
print(cpuinfo[processor]['model name'])
meminfo = meminfo()
print('Total memory: {0}'.format(meminfo['MemTotal']))
print('Free memory: {0}'.format(meminfo['MemFree']))
netdevs = netdevs()
for dev in netdevs.keys():
print('{0}: {1} MiB {2} MiB'.format(dev, netdevs[dev].rx, netdevs[dev].tx))
pids = process_list()
print('Total number of running processes:: {0}'.format(len(pids)))
detect_devs()
#!/usr/bin/env python
fromcollectionsimportOrderedDict
fromcollectionsimportnamedtuple
importos
importglob
importre
defcpuinfo():
cpuinfo=OrderedDict()
procinfo=OrderedDict()
nprocs=0
withopen('/proc/cpuinfo')asf:
forlineinf:
ifnotline.strip():
cpuinfo['proc%s'%nprocs]=procinfo
nprocs=nprocs+1
procinfo=OrderedDict()
else:
iflen(line.split(':'))==2:
procinfo[line.split(':')[0].strip()]=line.split(':')[1].strip()
else:
procinfo[line.split(':')[0].strip()]=''
returncpuinfo
defmeminfo():
meminfo=OrderedDict()
withopen('/proc/meminfo')asf:
forlineinf:
meminfo[line.split(':')[0]]=line.split(':')[1].strip()
returnmeminfo
defnetdevs():
withopen('/proc/net/dev')asf:
net_dump=f.readlines()
device_data={}
data=namedtuple('data',['rx','tx'])
forlineinnet_dump[2:]:
line=line.split(':')
ifline[0].strip()!='lo':
device_data[line[0].strip()]=data(float(line[1].split()[0])/(1024.0*1024.0),
float(line[1].split()[8])/(1024.0*1024.0))
returndevice_data
defprocess_list():
pids=[]
forsubdirinos.listdir('/proc'):
ifsubdir.isdigit():
pids.append(subdir)
returnpids
dev_pattern=['sd.*','xv*']
defsize(device):
nr_sectors=open(device+'/size').read().rstrip('\n')
sect_size=open(device+'/queue/hw_sector_size').read().rstrip('\n')
return(float(nr_sectors)*float(sect_size))/(1024.0*1024.0*1024.0)
defdetect_devs():
fordeviceinglob.glob('/sys/block/*'):
forpatternindev_pattern:
ifre.compile(pattern).match(os.path.basename(device)):
print('Device:: {0}, Size:: {1} GiB'.format(device,size(device)))
if__name__=='__main__':
cpuinfo=cpuinfo()
forprocessorincpuinfo.keys():
print(cpuinfo[processor]['model name'])
meminfo=meminfo()
print('Total memory: {0}'.format(meminfo['MemTotal']))
print('Free memory: {0}'.format(meminfo['MemFree']))
netdevs=netdevs()
fordevinnetdevs.keys():
print('{0}: {1} MiB {2} MiB'.format(dev,netdevs[dev].rx,netdevs[dev].tx))
pids=process_list()
print('Total number of running processes:: {0}'.format(len(pids)))
detect_devs()
以下是脚本的解释部分:
1、OrderedDict,这个功能是可以生成有序字典,大家都知道在python中字典是无序的,当然你也可以根据kye来排序,但用OrderedDict就可以直接生成有序字典,有序字典的顺序只跟你添加的顺序有关。
2、namedtuple,功能是可以给元组的索引起个名字,一般我们访问元组,只能用索引去访问,但如果给索引定义了名字,你就可以用定义的这个名字去访问了,为方便大家理解,我们举个栗子:
>>> from collections import namedtuple
>>> data = namedtuple('data',['rx','tx'])
>>> d = data(123,456)
>>> print d
data(rx=123, tx=456)
>>> print d.rx
123
1
2
3
4
5
6
7
>>>fromcollectionsimportnamedtuple
>>>data=namedtuple('data',['rx','tx'])
>>>d=data(123,456)
>>>printd
data(rx=123,tx=456)
>>>printd.rx
123
3、glob,在这行for device in glob.glob(‘/sys/block/*’)用到了这个功能,它主要方法就是glob,它返回所有匹配的文件列表。
4、re.compile(pattern).match(os.path.basename(device)),这句是将正则表达式编译为Pattern对象,然后使用Pattern匹配文本,获得匹配结果,匹配成功返回真,无法匹配时将返回None。