监控服务器的CPU、硬盘、内存和各个端口的开启情况(Python3实现)

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://shazhenyu.blog.csdn.net/article/details/98615482

一、简介

由于项目的需要,需要做一个简单监控服务器的CPU利用率、CPU负载、硬盘使用率、内存利用率和服务器的各个端口的开启情况的程序,并把结果通知到监控平台,如果出现异常,监控平台打电话或者发短信通知给具体的运维人员。博主写了负责监控的代码,供大家学习参考哈~

二、效果

在这里插入图片描述

三、源码

3.1、核心程序

#-*- coding:utf-8 -*-
"""
功能:监控服务器的CPU、硬盘、内存和各个端口的开启情况
作者:沙振宇
时间:2019年7月
"""
import json
import socket
import os
import platform
import requests
import datetime
import threading
import time

# 打印间隔符
def printL():
	print ("------------------------------")
sysstr = platform.system()
if(sysstr =="Windows"):
	print ("Windows tasks, no fcntl module")
	printL()
elif(sysstr == "Linux"):
	print ("Linux tasks")
	printL()
	# linux 模块
	import fcntl
else:
	print ("Other System tasks, no fcntl module")
	printL()

# @ class method 类方法(不需要实例化类就可以被类本身调用)
class Monitor():
	g_web_ip = ''		# 本机外网IP(这里之所以不自动获取是因为有些机器只有内网权限)
	g_wx_url = ''		# 读取微信地址
	g_wx_id = []		# 读取微信号
	g_email_url = ''   	# email地址
	g_email_id = []		# email账号
	g_php_url = ''		# php接口地址
	g_cpu_used = ''		# CPU利用率
	g_aver_load = ''	# CPU平均负载
	g_mem_used = ''		# 内存使用率
	g_disk_used = ''	# 磁盘使用率
	g_monitor_ports = []# 检测的端口们

	# 读取配置文件
	@classmethod
	def read_conf(cls):
		f_monitor = open('./monitor.conf','r',encoding='utf-8')
		f_monitor_lines = f_monitor.readlines()
		for f_line_num,f_monitor_line in enumerate(f_monitor_lines):
			tup = f_monitor_line.rstrip('\n').rstrip().split('\t')
			if '=' in tup[0]:	# 刨除异常状况
				# print("monitor.conf --- line:",f_line_num, tup[0])	# 读取每一行
				temp = tup[0].split('=')	# 读取每一项元素
				if temp[0] == 'web_ip': # 本机外网IP
					cls.g_web_ip = temp[1]
					print("read g_web_ip:", cls.g_web_ip)
				elif temp[0] == 'wecaht_url': # 读取微信地址
					cls.g_wx_url = temp[1]
					print("read g_wx_url:", cls.g_wx_url)
				elif temp[0] == 'wecaht_id': # 读取微信号
					wx_id = temp[1]
					cls.g_wx_id = wx_id.replace(' ','').split(',')
					print("read g_wx_id:", cls.g_wx_id)
				elif temp[0] == 'email_url': # email地址
					cls.g_email_url = temp[1]
					print("read g_email_url:", cls.g_email_url)
				elif temp[0] == 'email_id': # email账号
					email_id = temp[1]
					cls.g_email_id = email_id.replace(' ','').split(',')
					print("read email_id:", cls.g_email_id)
				elif temp[0] == 'php_url': # php接口地址
					cls.g_php_url = temp[1]
					print("read g_php_url:", cls.g_php_url)
				elif temp[0] == 'cpu_used': # CPU利用率
					cls.g_cpu_used = temp[1]
					print("read cpu_used:",cls.g_cpu_used)
				elif temp[0] == 'aver_load': # CPU平均负载
					cls.g_aver_load = temp[1]
					print("read aver_load:",cls.g_aver_load)
				elif temp[0] == 'mem_used': # 内存使用率
					cls.g_mem_used = temp[1]
					print("read mem_used:",cls.g_mem_used)
				elif temp[0] == 'disk_used': # 磁盘使用率
					cls.g_disk_used = temp[1]
					print("read disk_used:",cls.g_disk_used)
				elif temp[0] == 'monitor_ports': # 检测的端口们
					monitor_ports = temp[1]
					cls.g_monitor_ports = monitor_ports.replace(' ','').split(',')
					print("read monitor_ports:", cls.g_monitor_ports)
		printL()
		f_monitor.close()

	# 获取端口信息
	@classmethod
	def get_ports(cls, port):
		sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		result = sock.connect_ex(('127.0.0.1',int(port)))
		if result != 0:
			send_data = cls.g_web_ip+"服务器的"+port+'端口挂了,快去修复哈'
			cls.send_msg(send_data)
		else:
			print("端口:"+port+"正常")

#######################################################
	# CPU利用率
	@classmethod
	def get_cpu_used(cls):
		f = os.popen("top -bi -n 1| awk '{print $4}'").read().split('\n')[2]
		float_cpu_used = float(f)
		float_g_cpu_used = float(cls.g_cpu_used.split("%")[0])
		print("CPU利用率:",f,"%")
		if float(float_cpu_used) > float(float_g_cpu_used):
			cls.send_msg(cls.g_web_ip+"服务器的CPU利用率超过"+cls.g_cpu_used+"了,快去看看咋回事!")
		printL()

	# CPU平均负载
	@classmethod
	def aver_load(cls):
		f = os.popen("uptime | sed 's/,//g' | awk '{print $8,$9,$10}'")
		str_aver_load = f.read().strip().split(":")[1].strip()
		print("CPU平均负载:",str_aver_load)
		if float(str_aver_load) > float(cls.g_aver_load):
			cls.send_msg(cls.g_web_ip+"服务器的CPU平均负载超过"+cls.g_aver_load+"了,快去看看咋回事!")
		printL()

	#获取硬盘使用率
	@classmethod
	def get_disk_used(cls):
		disk_val = os.popen("df -h | head -2 | tail -1 |awk '{print $5}'").read().strip()
		int_disk_val = int(disk_val.split("%")[0])
		int_g_disk_val = int(cls.g_disk_used.split("%")[0])
		print("硬盘使用率:",disk_val)
		if int_disk_val > int_g_disk_val:
			cls.send_msg(cls.g_web_ip+"服务器的硬盘使用率超过"+cls.g_disk_used+"了,快去看看咋回事!")
		printL()

	# 获取内存使用率
	@classmethod
	def get_mem_used(cls):
		f = os.popen("free -m |grep Mem |awk '{print $3/$2}'")
		str_men = f.read().strip()
		print("内存使用率:",str_men)
		if float(str_men) > float(cls.g_mem_used):
			cls.send_msg(cls.g_web_ip+"服务器的内存使用率超过"+cls.g_mem_used+"了,快去看看咋回事!")
		printL()
#######################################################
	#调用报警函数
	@classmethod
	def send_msg(cls, content):
		cls.send_http(content)
	# 调用http接口
	@classmethod
	def send_http(cls,content):
		printL()
		print("send_http:",type(content),content)
		url_total = cls.g_php_url + "?msg=" + content
		print("url_total:",url_total)
		rp = requests.get(url_total)
		# print("rp:",rp.text)
		printL()
	# 发微信预警消息
	@classmethod
	def send_wx_alarm(cls,content):
		post_url = cls.g_wx_url
		for id in cls.g_wx_id:
			try:
				post_data = '{"operSys":"MCS","content":"服务器监控告警:%s\n%s","phones":"%s"}'%(cls.g_web_ip, content, id)
				print(post_data)
				# data = urllib.parse.urlencode(post_data)
				# data = data.encode('utf-8')

				req = requests.get(url=post_url,data=post_data)
				print("send_wx_alarm req:",req,type(req))
				result = json.loads(req.text())
				print(result)
			except Exception as e:
				print("send_wx_alarm:",e)
	# 发邮件预警消息
	@classmethod
	def send_email_alarm(cls,content):
		post_url = cls.g_email_url
		for id in cls.g_email_id:
			try:
				post_data = '{"subject":"%s服务器监控告警","email":"%s","bccEmail":"","operSys":"LOG","content":"%s"}'%(cls.g_web_ip, id, content)
				print(post_data)
				# data = urllib.parse.urlencode(post_data)
				# data = data.encode('utf-8')

				req = requests.get(url=post_url,data=post_data)
				print("send_email_alarm req:",req,type(req))
				# req.add_header("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
				result = json.loads(req.text())
				print(result)
			except Exception as e:
				print("send_email_alarm:",e)
#######################################################

# 定时检测
def fun_timer():
	print('当前检测时间为:',time.time())
	printL()
	printL()
	print("当前时间:", datetime.datetime.now())
	printL()
	# 读取配置信息
	Monitor.read_conf()

	# CPU利用率
	Monitor.get_cpu_used()

	# 读平均负载
	Monitor.aver_load()

	# 读硬盘使用率
	Monitor.get_disk_used()

	# 读内存使用率
	Monitor.get_mem_used()

	# 检测端口
	for port in Monitor.g_monitor_ports:
		Monitor.get_ports(port)

if __name__ == '__main__':
	while True:
		print(time.strftime('%Y-%m-%d %X',time.localtime()))
		fun_timer()
		time.sleep(300)# 等待300秒钟调用一次fun_timer() 函数

3.2、配置文件

# 本机IP地址(这里之所以不自动获取是因为有些机器只有内网)
web_ip=***

# 检测的端口
monitor_ports=3306, 8088, 6004 ,6379

# CPU利用率
cpu_used=100%

# CPU平均负载
aver_load=1

# 内存使用率
mem_used=0.8

# 磁盘使用率
disk_used=80%

# 通知地址
php_url=http://***:**/TaskMonitor/action

# 微信地址
wecaht_url=http://***:**/wechat/sendWeChat
# 微信ID
wecaht_id=123456,13123

# email地址
email_url=http://***:**/email/sendEmail
# 邮件邮箱
email_id=test@mucfc.com,11223344@qq.com

3.3、ReadMe

#############################################
# 作者:沙振宇
# 时间:20198月初
# 说明:简单监控server的CPU、硬盘、内存
#       和服务器的各个端口
# 适用系统:Linux (注意:不适合Windows)
#############################################
# 文件:monitor.conf main.py
# 文件说明:
#       monitor.conf 为配置文件
#       monitor.py 为python文件
#############################################
# 使用前准备:
# python版本要求:python3.0 以上
# 安装 python 的 psutil 包 和 requests 包
# 安装命令:
# pip install psutil
# pip install requests
#############################################
# python3启动:
# nohup python3 monitor.py > monitor.log 2>&1 &
# 注:需要定期清理 monitor.log 文件
#############################################
展开阅读全文

没有更多推荐了,返回首页