0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

利用Python写了一个监控服务器资源利用率的脚本!

jf_yLA7iRus 来源:杰哥的IT之旅 2023-01-29 15:08 次阅读

研究了一个脚本,其主要目的是:基于 Python 编程语言来监控服务器的 CPU、内存、/目录、/appslog、/bigdata目录使用率以及网卡接收和发送情况。

该脚本部署场景分为:服务端和客户端。

服务端:一台固定 IP 地址的服务器

客户端:N 台指定固定 IP 地址的服务器

服务端脚本:

#-*-coding:utf-8-*-
importio
importos
importsys
importlogging
fromloggingimporthandlers
importMySQLdb
importsmtplib
fromemail.mime.textimportMIMEText
fromemail.headerimportHeader
fromemail.utilsimportformataddr
importrequests,json
importdatetime
importtime
importshutil,re
importuuid
importsocket
importSocketServer

ifsys.getdefaultencoding()!='utf-8':
reload(sys)
sys.setdefaultencoding('utf-8')

classLogger(object):
level_relations={
'debug':logging.DEBUG,
'info':logging.INFO,
'warning':logging.WARNING,
'error':logging.ERROR,
'crit':logging.CRITICAL
}#日志级别关系映射

def__init__(self,logname,level='info',when='D',backCount=10,fmt='%(asctime)s-%(pathname)s[line:%(lineno)d]-%(levelname)s:%(message)s'):
CURRENT_DIR=os.path.dirname(__file__)
LOG_FILE=os.path.abspath(os.path.join(CURRENT_DIR,logname))
self.logger=logging.getLogger(LOG_FILE)
format_str=logging.Formatter(fmt)#设置日志格式
self.logger.setLevel(self.level_relations.get(level))#设置日志级别
sh=logging.StreamHandler()#往屏幕上输出
sh.setFormatter(format_str)#设置屏幕上显示的格式
th=handlers.TimedRotatingFileHandler(
filename=LOG_FILE,when=when,backupCount=backCount,encoding='utf-8')#往文件里写入#指定间隔时间自动生成文件的处理器
#实例化TimedRotatingFileHandler
#interval是时间间隔,backupCount是备份文件的个数,如果超过这个个数,就会自动删除,when是间隔的时间单位,单位有以下几种:
#S秒
#M分
#H小时、
#D天、
#W每星期(interval==0时代表星期一)
#midnight每天凌晨
th.setFormatter(format_str)#设置文件里写入的格式
#self.logger.addHandler(sh)#把对象加到logger里
ifnotself.logger.handlers:
self.logger.addHandler(th)

classAnalysis(object):
defbuildMsg(self,msg):
print('构造预警信息'+str(msg))
icount=0
if(float(msg[4])>90):
icount+=1
CPU="> CPU预警:使用率高于90%,使用"+str(msg[4])+"%
"
else:
CPU=""
if(float(msg[5])>90):
icount+=1
mem=">内存预警:使用率高于90%,使用"+str(msg[5])+"%
"
else:
mem=""
if(float(msg[6])>85):
icount+=1
disk_root=">磁盘根目录预警:使用率高于85%,使用"+str(msg[6])+"%
"
else:
disk_root=""
if(float(msg[7])>85):
icount+=1
disk_appslog=">业务磁盘预警:使用率高于85%,使用"+str(msg[7])+"%
"
else:
disk_appslog=""
if(float(msg[8])>3000):
icount+=1
networkRecv=">网卡10秒内接收数据预警:接收数据大于4000M,接收"+str(msg[8])+"M
"
else:
networkRecv=""
if(float(msg[9])>3000):
icount+=1
networkSend=">网卡10秒内发送数据预警:发送数据大于4000M,发送"+str(msg[9])+"M
"
else:
networkSend=""
s=alarmName+"
"+msg[2]+":"+msg[3]+"
"+CPU+mem+disk_root+disk_appslog+networkRecv+networkSend
#print(s)
log.logger.info('预警信息:'+s)

#发送预警
if(icount>0):
#发送预警邮件、企业微信
ifmailconf==1:
self.send_mail(s,msg[3])
ifwxconf==1:
self.send_WX(s)

defsend_mail(self,content,ip):
smtpserver='smtp.163.com'
mail_user="xxx@163.com"
mail_pass="passwordxxx"
mail_res=["xxx@163.com","xxx@163.com","xxx@163.com","xxx@163.com","xxx@163.com","xxx@163.com","xxx@163.com"]
sub=time.strftime("%Y-%m-%d%H:%M:%S",time.localtime())
msg=MIMEText(sub+"
"+content,_subtype='plain',_charset='utf-8')
msg['Subject']=Header(alarmName+':'+ip,'utf-8')
#msg['From']=Header("系统预警",'utf-8')
msg['From']=formataddr(pair=('设备预警',mail_user))
msg['To']=','.join(mail_res)
smtp=smtplib.SMTP()
smtp.connect(smtpserver)
smtp.starttls()
smtp.login(mail_user,mail_pass)
smtp.sendmail(mail_user,mail_res,msg.as_string())
smtp.quit()

defsend_WX(self,msg):
headers={"Content-Type":"text/plain"}
#s="服务器预警:{},验证码{}".format({str(printCode)},{str(verifyCode)})
data={
"msgtype":"text",
"text":{
"content":msg,
}
}
r=requests.post(
url='企业微信机器人地址(需要根据实际机器人地址配置)',
headers=headers,json=data)
print(r.text)

defWrite_to_Mysql_alarm(self,valuelist):
#log=Logger('all.log',level='debug')
#业务监控:id,project,tpye,exceptiontype,details(xx,大数据,无es进程/es集群不健康,)
try:
db=MySQLdb.connect("xxx","xxx","xxx","xxx",charset='utf8')
log.logger.info("数据库连接成功")
except:
log.logger.info("数据库连接失败")
#创建游标
cursor=db.cursor()
uid=uuid.uuid1()
result=0
sql=''
try:
sql='insertintotest_serverresourcealarmvalues(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)'
#val=(str(uid),valuelist[1],valuelist[2],valuelist[3],valuelist[4],valuelist[5],valuelist[6],'',valuelist[7],valuelist[8],valuelist[9],valuelist[10],'','','')
val=(str(uid),valuelist[2],valuelist[3],valuelist[4],valuelist[5],valuelist[6],valuelist[7],'',valuelist[8],valuelist[9],valuelist[10],'','','')
cursor.execute(sql,val)
db.commit()
log.logger.error('设备预警信息已入库!')
#发送企业微信预警信息
self.buildMsg(valuelist)
except:
into=sys.exc_info()
#log.logger.error('插入数据失败!')
log.logger.error('设备预警信息入库失败!'+str(into))
result=0
#str=self.obj_to_string(sys.exc_info(),self)
print('error',into)

#关闭游标
db.close()
returnresult

defWrite_to_Mysql_temp(self,valuelist):
#打开数据库连接
#db=MySQLdb.connect("xxx","xxx","xxx","xxx",charset='utf8')
try:
db=MySQLdb.connect("xxx","xxx","xxx","xxx",charset='utf8')
log.logger.info("数据库连接成功")
except:
log.logger.info("数据库连接失败")
#使用cursor()方法获取操作游标
cursor=db.cursor()
uid=uuid.uuid1()
result=0
try:
sql='insertintotest_serverresourcetempvalues(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)'
val=(str(uid),valuelist[2],valuelist[3],valuelist[4],valuelist[5],valuelist[6],valuelist[7],'',valuelist[8],valuelist[9],valuelist[10],'','','')
cursor.execute(sql,val)
db.commit()
result=1
log.logger.info("临时表sql执行状态:"+str(result))
except:
into=sys.exc_info()
result=0
print(into)
log.logger.info('临时表sql执行失败:'+str(into))
#关闭数据库连接

db.close()
returnresult

classMyServer(SocketServer.BaseRequestHandler):
defhandle(self):
conn=self.request
log.logger.info('...connectedfrom{}'.format(self.client_address))
#print('1多线程监控')
Flag=True
whileFlag:
data=conn.recv(1024)
#print(data)
iflen(data)>10:
log.logger.info('接收到的客户端数据:'+data)
conn.sendall('1')
sub=data.strip('
')
str=sub.split('|')
#print(str)
a=Analysis()
#报警信息入库,#将监控数据写入临时表中test_serverresourcetemp_lty
result=a.Write_to_Mysql_temp(str)
if(float(str[4])>90orfloat(str[5])>90orfloat(str[6])>85orfloat(str[7])>85orfloat(str[8])>3000orfloat(str[9])>3000):
result1=a.Write_to_Mysql_alarm(str)
#result=1
ifresult==0:
log.logger.info('预警信息入库失败!')
else:
log.logger.info('预警信息入库完成!')
#发送预警邮件、企业微信
#a.buildMsg(str)

ifdata=='exit':
log.logger.info('...connecteend...')
Flag=False

if__name__=="__main__":
#每分钟执行一次
log=Logger('socketservice.logs')
log.logger.info('----start----')
alarmName='服务器资源预警'
#是否开启邮件报警,1为开启,0为关闭
mailconf=1
#是否开启企业微信报警,1为开启,0为关闭
wxconf=0
server=SocketServer.ThreadingTCPServer(('IP',port),MyServer)
server.serve_forever()

客户端脚本:

#-*-coding:utf-8-*-
importio
importos
importsys
importtime
importdatetime
importsocket
importcommands
importlogging
fromloggingimporthandlers
importpsutil
importstruct
importfcntl

ifsys.getdefaultencoding()!='utf-8':
reload(sys)
sys.setdefaultencoding('utf-8')

classLogger(object):
level_relations={
'debug':logging.DEBUG,
'info':logging.INFO,
'warning':logging.WARNING,
'error':logging.ERROR,
'crit':logging.CRITICAL
}#日志级别关系映射

def__init__(self,logname,level='info',when='D',backCount=10,fmt='%(asctime)s-%(pathname)s[line:%(lineno)d]-%(levelname)s:%(message)s'):
CURRENT_DIR=os.path.dirname(__file__)
LOG_FILE=os.path.abspath(os.path.join(CURRENT_DIR,logname))
self.logger=logging.getLogger(LOG_FILE)
format_str=logging.Formatter(fmt)#设置日志格式
self.logger.setLevel(self.level_relations.get(level))#设置日志级别
sh=logging.StreamHandler()#往屏幕上输出
sh.setFormatter(format_str)#设置屏幕上显示的格式
th=handlers.TimedRotatingFileHandler(
filename=LOG_FILE,when=when,backupCount=backCount,encoding='utf-8')#往文件里写入#指定间隔时间自动生成文件的处理器
#实例化TimedRotatingFileHandler
#interval是时间间隔,backupCount是备份文件的个数,如果超过这个个数,就会自动删除,when是间隔的时间单位,单位有以下几种:
#S秒
#M分
#H小时、
#D天、
#W每星期(interval==0时代表星期一)
#midnight每天凌晨
th.setFormatter(format_str)#设置文件里写入的格式
#self.logger.addHandler(sh)#把对象加到logger里
ifnotself.logger.handlers:
self.logger.addHandler(th)

classclientMonitor(object):
#获取指定网卡ip
defgetIpAddress(self,dev):
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
a=s.fileno()
b=0x8915
c=struct.pack('256s',dev[:15])
res=fcntl.ioctl(a,b,c)[20:24]
returnsocket.inet_ntoa(res)

#获取网络的使用情况,取的是eth0的发送和收取的总字节数
#readNetInfo('eth0')
defreadNetInfo(self,dev):
f=open('/proc/net/dev')
lines=f.readlines()
f.close()
res={'in':0,'out':0}
forlineinlines:
ifline.lstrip().startswith(dev):
#forcentos
line=line.replace(':','')
items=line.split()
res['in']=long(items[1])#/1024
res['out']=long(items[len(items)/2+1])#/1024
returnres

defreadNetInfo_new(self,dev):
res={'in':0,'out':0}
res['in']=psutil.net_io_counters(pernic=True).get(dev).bytes_recv
res['out']=psutil.net_io_counters(pernic=True).get(dev).bytes_sent
returnres

#磁盘使用率,path:磁盘路径
defdisk_stat(self,path):
hd={}
disk=os.statvfs(path)
percent=(disk.f_blocks-disk.f_bfree)*100/(disk.f_blocks-disk.f_bfree+disk.f_bavail)+1
returnpercent

defnet_loop(self,dev):
#end={'in':0,'out':0}
res=self.readNetInfo_new(dev)
#推迟执行的秒数
time.sleep(2)
#new_recv,new_send=get_net_data()
new_res=self.readNetInfo_new(dev)
recv_data=(new_res['in']-res['in'])/1024/1024
send_data=(new_res['out']-res['out'])/1024/1024
print("recv_data:%sM,send_data:%sM"%(recv_data,send_data))
returnrecv_data,send_data

defprocesscheck(self,cmd):
#cmd='ps-aux|sort-k3nr|head-1'
(status,output)=commands.getstatusoutput(cmd)
#Pid=output.split('')[6]
log.logger.info('资源占用top:
'+output)

#查看占用内存最高的进程的PID
#psaux|head-1;psaux|grep-vPID|sort-rn-k+4|head
#ps-aux|sort-k4nr|head-1,-k3cpu占用最高,-k4内存占用最高
#root146681.90.0905043256?Ss4月232811:48/sbin/rngd-f
#索引:-k3 b.split('')[6] 28进程路径(/sbin/rngd)
#索引:-k4 b.split('')[4]
if__name__=="__main__":
#10分钟执行一次,数据上报到服务端,服务端负责报警
#需要修改的参数:custom,deviceType,netName
custom='test'
deviceType='客户端服务器'
#网卡名称
netName='ens3f0'

log=Logger('socketclient.logs')
log.logger.info("----start----")
info=clientMonitor()

locatIp=info.getIpAddress(netName)
recv_data,send_data=info.net_loop(netName)
cpuinfo=psutil.cpu_percent(1)
#svmem(total=67268558848,available=32022245376,percent=52.4,used=34601009152,free=29655695360,active=17274105856,inactive=2927910912,buffers=10100736,cached=3001753600,shared=298610688,slab=11243315200)
svmem=psutil.virtual_memory()
meminfo=svmem[2]
disk_root=info.disk_stat('/')
disk_appslog=info.disk_stat('/appslog')
disk_bigdata=info.disk_stat('/bigdata')
#如果CPU或内存的占用率大于80%,将占用CPU或内存资源最多的进程找出来
issendmsg=1
if(cpuinfo>80ormeminfo>80ordisk_root>80ordisk_appslog>80ordisk_bigdata>80orrecv_data>3000orsend_data>3000):
#发送预警邮件
sendmsg=locatIp+'服务器资源占用高!请检查!
'
sendmsg+="CPU占用:"+str(cpuinfo)+'
'
sendmsg+="内存占用:"+str(meminfo)+'
'
sendmsg+="/目录占用:"+str(disk_root)+'
'
sendmsg+="/appslog目录占用:"+str(disk_appslog)+'
'
sendmsg+="/bigdata目录占用:"+str(disk_bigdata)+'
'
sendmsg+="网卡接收流量:"+str(recv_data)+'M,发送流量'+str(send_data)+'M
'
#sendmsg +="网卡10秒发送流量:"+str(send_data)+'
'
log.logger.info(sendmsg)
ifcpuinfo>80:
info.processcheck('ps-aux|sort-k3nr|head-10')
ifmeminfo>80:
info.processcheck('ps-aux|sort-k4nr|head-10')
issendmsg=1
else:
#log.logger.info(locatIp+"正常")
log.logger.info("CPU使用率:"+str(cpuinfo))
log.logger.info("内存使用率:"+str(meminfo))
log.logger.info("/目录使用率:"+str(disk_root))
log.logger.info("/appslog使用率:"+str(disk_appslog))
log.logger.info("/bigdata使用率:"+str(disk_bigdata))
log.logger.info("网卡接收和发送情况:接收"+str(recv_data)+"M,发送"+str(send_data)+"M")

#Id,custom,deviceType,IP,cpu,mem,disk_root,disk_appslog,disk_bigdata,networkRecv,networkSend,uploadTime,temp2,temp3,temp4
msg='1'+'|'+custom+'|'+deviceType+'|'+locatIp+'|'+str(cpuinfo)+'|'+str(meminfo)+'|'+str(disk_root)+'|'+str(disk_appslog)+'|'+str(disk_bigdata)+'|'+str(recv_data)+'|'+str(send_data)+'|'+time.strftime("%Y-%m-%d%H:%M:%S",time.localtime())

ifissendmsg==1:
ip_port=('IP',port)
sk=socket.socket()
sk.connect(ip_port)
sk.sendall(msg)
data=sk.recv(1024)
ifdata=='1':
log.logger.info("本地预警信息传输成功!")
else:
log.logger.info("本地预警信息传输失败!")
sk.sendall('exit')
sk.close()

服务端和客户端部署好后,执行脚本过程中如遇到缺少 psutil 依赖包的话,则需要进行安装。

因为我这有准备好的 psutil_rpm 包,可执行命令:rpm -ivh python2-psutil-5.6.7-1.el7.x86_64.rpm

psutil_rpm 包获取方式:
链接:https://pan.baidu.com/s/19iMY8b9nVITtgBq8F3Um_A
提取码:PsRm

写个定时任务,以每 2 小时执行一次该脚本。

crontab-e

0*/2***cd/opt/jiaoben;pythontest_socket_resourcemonitor.py

客户端打印日志效果:

tail-200fsocketclient.logs

b0d41f82-96c6-11ed-bfe3-dac502259ad0.png

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 服务器
    +关注

    关注

    12

    文章

    8120

    浏览量

    82522
  • ip地址
    +关注

    关注

    0

    文章

    240

    浏览量

    16742
  • 编程语言
    +关注

    关注

    9

    文章

    1878

    浏览量

    33136
  • python
    +关注

    关注

    51

    文章

    4677

    浏览量

    83467
  • 脚本
    +关注

    关注

    1

    文章

    372

    浏览量

    14636

原文标题:太强了!利用 Python 写了一个监控服务器资源利用率的脚本!

文章出处:【微信号:释然IT杂谈,微信公众号:释然IT杂谈】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    GPU-Z可以监控每个vGPU的总GPU利用率吗?

    我同时运行4VM,每个vGPU是m60-2Q。所有虚拟机都运行bechmark测试。我使用Techpowerup GPU-Z监控每个vGPU。我发现了有趣的结果。如果我将所有vG
    发表于 09-19 16:59

    如何利用UCOSII中的统计任务 OS_TaskStat()知道了CPU利用率100%把利用率降下来?

    冒昧的问下各路大神,假如我们利用UCOSII中的统计任务 OS_TaskStat()知道了CPU利用率100%,则应该怎样操作,把利用率降下来?另外,
    发表于 07-12 04:36

    如何解释Xilinx ISE的资源利用率数据?

    旁边的数字意味着什么的文档和资源的指针?具体来说:1)它们各自意味着什么?,2)它们是在VHDL代码中明确使用的,还是选择了ISE(例如DSP48的数量)来实现我的设计?3)如果我的设计在上面100%的资源利用率,如何更改我的V
    发表于 03-24 10:14

    Post综合后的利用率只不过是实施后的利用率

    嗨,Post综合后的利用率只不过是实施后的利用率......?谢谢娜文G K.
    发表于 05-12 08:57

    CUP利用率怎么计算?

    要计算当前CUP利用率,是不是就使能OS_TASK_STAT_EN就可以了,并不要单独建立任务去执行OSTaskStat(),是这样吗?参看战舰例程,没有找到哪里执行了OSTaskStat()!
    发表于 05-18 22:05

    如何获得每个块的路由资源利用率

    我想知道每个块使用的详细路由资源。 “设计路线状态”仅提供整个设计的网络总数。有谁知道如何获得每个块的路由资源利用率(网络数量,交换机盒等)?
    发表于 05-21 15:35

    请问下如何提高无线信道利用率

    影响无线信道利用率的因素有哪些?无线利用率与网络质量间的关系是什么?调整和提高无线信道利用率的建议有哪些?
    发表于 05-27 06:46

    如何获取栈利用率

    如何获取栈利用率
    发表于 02-16 07:34

    openEuler 资源利用率提升之道 01:概论

    利用率低于 20%,存在巨大的资源浪费。因此,提升数据中心资源利用率是当前急需解决的重要问
    发表于 07-06 09:54

    openEuler 资源利用率提升之道 04:CPU 抢占和 SMT 隔离控制

    达到较好的效果依赖硬件优先级算法,我们可以期待新的鲲鹏服务器。同时在公有云场景对邻居干扰的消减也是很重要的,openEuler 在这方法也做了些探索,“潮汐 affinity”技术取得了不俗的效果,也会在后续的文章中与大家见面。下
    发表于 09-22 16:50

    CPU利用率问题求解

    “你能不能实现理想情况下应该在每个时间片开始时执行的监控任务,并确定前一个时间片的利用率。如果利用率
    发表于 12-06 06:00

    专家谈如何提高服务器利用率

    专家谈如何提高服务器利用率  如今,数据中心节能已成为热点话题,为减少功耗,各大厂商纷纷推出相应产品和解决方案。近日,Microsoft的utility
    发表于 01-27 11:46 666次阅读

    cpu利用率异常排查实践与总结

    昨天下午突然收到运维邮件报警,显示数据平台服务器cpu利用率达到了98.94%,而且最近一段时间一直持续在70%以上,看起来像是硬件资源到瓶颈需要扩容了,但仔细思考就会发现这个利用率
    的头像 发表于 11-15 15:33 3499次阅读

    中标麒麟虚拟化平台软件可大幅度提高资源利用率

    池化并统一管理调度;为您的关键业务提供灵活的基础资源调度,优越的性能和稳定性。系统实现对海光、PowerPC 及X86平台的支持。 中标麒麟虚拟化平台软件能够在提高数据中心空间利用率服务器
    发表于 09-02 10:31 1207次阅读

    监控服务器资源利用率服务脚本

    其主要目的是:基于 Python 编程语言来监控服务器的 CPU、内存、/目录、/appslog、/bigdata目录使用率以及网卡接收和发送情况。 该
    的头像 发表于 01-22 16:02 469次阅读