需求
- 每天定时推送服务器流量使用情况,发送到邮箱
- 服务器上运行着代理流量等服务,一天下来需要查看流量使用量,推送到邮箱,手机上可登录邮箱查看
效果图
实现步骤
1. 依赖系统 vnstat
工具,读取流量数据
2. Python读取vnstat流量数据,推送到邮箱
3. vnstat提供了,json,xml格式数据
4. 添加计划任务到点执行脚本,实现定时推送消息
安装vnstat
Centos系统
yum install vnstat
Debian系统
apt-get install vnstat
因为vnstat工具以后台运行,来记录保存流量使用情况,所以需要vnstat需要开机自启动
设置vnstat开机自启
systemctl enable vnstat
启动服务
systemctl start vnstat
查看网卡天流量,等五分钟会刷新数据
vnstat -i eth0 -d
Python实现
步骤1.获取系统当天时间
因为需要获取当天
流量情况time.strftime
函数
传入值%Y %m %d
%Y=年 %m=月 %d=天
def get_system_time(date):
date = time.strftime(date)
return date
步骤2.获取xml格式流量数据
执行如下系统命令,会返回xml格式流量数据
使用正规表达式匹配 来取值
vnstat -i eth0 -d --xml
注意设置要取值得网卡eth0,第六行
def get_data():
time.strftime("%Y%m%d")
year = get_system_time('%Y')
month = get_system_time('%m')
day = get_system_time('%d')
system_eval = "vnstat\t-i\teth0\t--xml"
get_xml = os.popen(system_eval).read()
#open_file = open('./value.xml','r',encoding='utf-8')
#get_xml = open_file.read()
find_file_value = re.findall(r'<date><year>'+year+'</year><month>'+month+'</month><day>'+day+"</day></date><rx>(\w+)</rx><tx>(\w+)</tx></top>",get_xml)
get_day_data = find_file_value[-1]
#open_file.close()
return get_day_data
步骤3.处理流量数据
因为vnstat返回得是Bytes流量值,我们需要MB,GB值,
在计算机操作系统中,存储单位为1024进制
1024Byte(字节)=1KB
1024KB=1MB
1024MB=1GB
1024GB=1TB
1024TB=1PB
用Byte值除1024 得到KB值,以此类推
def print_today_data(company):
rx_bytes = int(get_data()[0])
rx_kb = rx_bytes / 1024
rx_mb = rx_kb / 1024
rx_gb = rx_mb / 1024
tx_bytes = int(get_data()[1])
tx_kb = tx_bytes / 1024
tx_mb = tx_kb / 1024
tx_gb = tx_mb / 1024
if company == "MB":
return (round(rx_mb,2),round(tx_mb,2))
elif company == "GB":
return (round(rx_gb,2),round(tx_gb,2))
else:
print("\u8bf7\u8f93\u5165\u5355\u4f4d\uff1a\u006d\u0062\u0020\u6216\u0020\u0067\u0062")
步骤4.获取系统公网IP
向 https://www.bt.cn/Api/getIpAddress 发送http请求返回系统公网IP
def get_ip_addr():
get_ip_aip = "https://www.bt.cn/Api/getIpAddress"
headers = {'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0"}
get_http_info = urllib.request.Request(url=get_ip_aip,headers=headers)
run_http = urllib.request.urlopen(get_http_info)
return run_http.read().decode('utf-8')
步骤5.登录邮箱,发送数据到邮件
QQ邮箱,163邮件等等,支持SMTP SSL邮箱,需要开通此服务,网上教程多
def main():
print("\u005b\u002b\u005d\t\u6b63\u5728\u8bfb\u53d6\u6570\u636e\u002e\u002e\u002e")
#填写SMTP邮箱服务器,如下QQ邮箱 SMTP邮箱服务器
Email_host = 'smtp.qq.com'
#要登录邮箱用户,QQ邮箱
from_addr = '[email protected]'
#邮箱登录密码
from_passwd = '123456'
#接收邮件地址
to_addr = '[email protected]'
#设置读取单位 GB或者MB
data_company = "GB"
format_data = print_today_data(data_company)
get_all_data = print_today_data(data_company)[0] + print_today_data(data_company)[1]
msg = MIMEText("\u670d\u52a1\u5668\u0049\u0050\uff1a"+str(get_ip_addr())+str(get_system_time('\n\n%Y{y}%m{m}%d{d}').format(y="\u5e74", m="\u6708", d="\u53f7"))+"\n\n\u4e0a\u4f20\u6d41\u91cf\uff1a"+str(format_data[0])+data_company+"\n\u4e0b\u8f7d\u6d41\u91cf\uff1a"+str(format_data[1])+data_company+"\n\u4eca\u603b\u6d41\u91cf\uff1a"+str(get_all_data)+data_company)
msg['Subject'] = "\u6d41\u91cf\u65e5\u5fd7"
msg["From"] = "运行日志"+"<"+from_addr
msg["To"] = to_addr
try:
Email = smtplib.SMTP_SSL(Email_host,465)
login = Email.login(from_addr,from_passwd)
except smtplib.SMTPAuthenticationError as e:
print("\u005b\u002d\u005d\t\u767b\u5f55\u5931\u8d25\u002e\u53ef\u80fd\u7528\u6237\u6216\u5bc6\u7801\u9519\u8bef")
pass
except Exception as e:
print("\u005b\u002d\u005d\t\u90ae\u7bb1\u670d\u52a1\u5668\u8fde\u63a5\u5931\u8d25")
pass
else:
try:
Email.sendmail(from_addr, to_addr, msg.as_string())
Email.quit()
except UnboundLocalError as e:
print("\u005b\u002d\u005d\t\u767b\u5f55\u5931\u8d25")
else:
print("\u005b\u002b\u005d\t\u90ae\u7bb1\u53d1\u9001\u6210\u529f")
最后完整Python脚本
链接 >> https://www.nstns.com/api/download.php?file=/xs/code/py/pushnetworktraffic.zip
import smtplib
import os
import time
from email.mime.text import MIMEText
import xml
import re
import urllib.request
##Python推送流量使用情况到邮箱
##参考 >> https://www.nstns.com/pushnetworktraffic.html
#Yozz 2021-12.26
def get_system_time(date):
date = time.strftime(date)
return date
def get_data():
time.strftime("%Y%m%d")
year = get_system_time('%Y')
month = get_system_time('%m')
day = get_system_time('%d')
system_eval = "vnstat\t-i\teth0\t--xml"
get_xml = os.popen(system_eval).read()
#open_file = open('./value.xml','r',encoding='utf-8')
#get_xml = open_file.read()
find_file_value = re.findall(r'<date><year>'+year+'</year><month>'+month+'</month><day>'+day+"</day></date><rx>(\w+)</rx><tx>(\w+)</tx></top>",get_xml)
get_day_data = find_file_value[-1]
#open_file.close()
return get_day_data
def print_today_data(company):
rx_bytes = int(get_data()[0])
rx_kb = rx_bytes / 1024
rx_mb = rx_kb / 1024
rx_gb = rx_mb / 1024
tx_bytes = int(get_data()[1])
tx_kb = tx_bytes / 1024
tx_mb = tx_kb / 1024
tx_gb = tx_mb / 1024
if company == "MB":
return (round(rx_mb,2),round(tx_mb,2))
elif company == "GB":
return (round(rx_gb,2),round(tx_gb,2))
else:
print("\u8bf7\u8f93\u5165\u5355\u4f4d\uff1a\u006d\u0062\u0020\u6216\u0020\u0067\u0062")
def get_ip_addr():
get_ip_aip = "https://www.bt.cn/Api/getIpAddress"
headers = {'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0"}
get_http_info = urllib.request.Request(url=get_ip_aip,headers=headers)
run_http = urllib.request.urlopen(get_http_info)
return run_http.read().decode('utf-8')
def main():
print("\u005b\u002b\u005d\t\u6b63\u5728\u8bfb\u53d6\u6570\u636e\u002e\u002e\u002e")
#填写SMTP邮箱服务器,如下QQ邮箱 SMTP邮箱服务器
Email_host = 'smtp.qq.com'
#要登录邮箱用户
from_addr = '[email protected]'
#邮箱登录密码
from_passwd = '123456'
#接收邮件地址
to_addr = '[email protected]'
#设置读取单位 GB或者MB
data_company = "GB"
format_data = print_today_data(data_company)
get_all_data = print_today_data(data_company)[0] + print_today_data(data_company)[1]
msg = MIMEText("\u670d\u52a1\u5668\u0049\u0050\uff1a"+str(get_ip_addr())+str(get_system_time('\n\n%Y{y}%m{m}%d{d}').format(y="\u5e74", m="\u6708", d="\u53f7"))+"\n\n\u4e0a\u4f20\u6d41\u91cf\uff1a"+str(format_data[0])+data_company+"\n\u4e0b\u8f7d\u6d41\u91cf\uff1a"+str(format_data[1])+data_company+"\n\u4eca\u603b\u6d41\u91cf\uff1a"+str(get_all_data)+data_company)
msg['Subject'] = "\u6d41\u91cf\u65e5\u5fd7"
msg["From"] = "运行日志"+"<"+from_addr
msg["To"] = to_addr
try:
Email = smtplib.SMTP_SSL(Email_host,465)
login = Email.login(from_addr,from_passwd)
except smtplib.SMTPAuthenticationError as e:
print("\u005b\u002d\u005d\t\u767b\u5f55\u5931\u8d25\u002e\u53ef\u80fd\u7528\u6237\u6216\u5bc6\u7801\u9519\u8bef")
pass
except Exception as e:
print("\u005b\u002d\u005d\t\u90ae\u7bb1\u670d\u52a1\u5668\u8fde\u63a5\u5931\u8d25")
pass
else:
try:
Email.sendmail(from_addr, to_addr, msg.as_string())
Email.quit()
except UnboundLocalError as e:
print("\u005b\u002d\u005d\t\u767b\u5f55\u5931\u8d25")
else:
print("\u005b\u002b\u005d\t\u90ae\u7bb1\u53d1\u9001\u6210\u529f")
if __name__ == '__main__':
main()
#获取公网IP
#print(get_ip_addr())
#获取系统时间
#print(get_system_time('%Y{y}%m{m}%d{d}').format(y="\u5e74", m="\u6708", d="\u53f7"))
#获取总流量单位GB
#print(print_today_data("GB")[0]+print_today_data("GB")[1])
#h获取总流量单位MB
#print(print_today_data("MB")[0]+print_today_data("MB")[1])
exit()
定时执行
定时去执行脚本,完成定时重启
在Linux下的crontab
计划任务软件
末尾添加
sudo vim /etc/crontab
每天第23小时50分执行脚本,推送消息
50 23 * * * root /usr/bin/python3.6 /data/py/pushnetworktraffic.py > /tmp/pushnetworktraffic.log
任务格式
* * * * * user command
分 时 日 月 周 用户 命令