文章目錄
- 一、簡介
- 二、效果
- 三、源碼
- 3.1、核心程序
- 3.2、配置文件
- 3.3、ReadMe
一、簡介
由于項目的需要,需要做一個簡單監控服務器的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
#############################################
# 作者:沙振宇
# 時間:
2019
年
8
月初
# 說明:簡單監控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 文件
#############################################
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
