调用阿里云api获取阿里云数据同步服务(DTS)并且作图发送邮件的整个流程

前言

https://rorschachchan.github.io/2018/02/24/阿里云获取DTS服务延迟的脚本/ 文章里已经说了“领导要求每天查看阿里云dts同步的延迟情况和同步速率情况”,并且在https://rorschachchan.github.io/2018/02/27/使用matplotlib画图的一个脚本/ 里面也放了一个使用python matplotlib画图的demo,这篇文章的目的就是把整个过程实现,并且把dts图形以每日邮件的形式发送给领导的效果!

实现需求的思路

本次需求有四个动作,分别是获取一天以内的DTS延迟和同步速率将获取到的DTS值做成PNG图像将生成的PNG图像上传到阿里云云存储OSS把图片展示到邮件里并发送给相关领导。由于第一步获取一天以内的DTS延迟和同步速率需要将这个脚本每小时执行一次,执行24次,才可以执行生成png图像这一步,所以后三个其实可以写成一个大脚本。不过在本文为了表述的清楚,就把各自不同用途写成了不同的脚本。

获取阿里云DTS延迟和同步速率的脚本

这个脚本之前写过了,这里再拿出来晒一遍:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/usr/bin/env python
#coding=utf-8
#这个脚本是用来获取dts延迟数字的
from aliyunsdkcore import client
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
import time,json,sys
sys.path.append('/解压缩路径/aliyunsdkdts/request/v20160801/') #这里看不懂去看https://rorschachchan.github.io/2018/02/24/阿里云获取DTS服务延迟的脚本/
import DescribeSynchronizationJobStatusRequest

# 创建 Client 实例
clt = client.AcsClient('这里填写ak','这里填写sk','cn-shenzhen')

# 创建 request,并设置参数
request = DescribeSynchronizationJobStatusRequest.DescribeSynchronizationJobStatusRequest()
request.set_SynchronizationJobId("这里填写DTS的ID号")

response = clt.do_action_with_exception(request)

delay = json.loads(response)
rate = str(delay["Performance"]["FLOW"])[0:4] #由于同步速率默认是带单位的,这里就取前四位

#用A.txt来存储延迟时长
fd = open("/存储路径/A.txt","a")
fd.write(str(delay["DataSynchronizationStatus"]["Delay"]))
fd.write('\n')
fd.close()

#用B.txt来存储同步速率
fr = open("/存储路径/rate.txt","a")
fr.write(rate)
fr.write('\n')
fr.close()

将获取到的值做成图片的脚本

由于脚本执行环境是无图像的阿里云服务器,系统是centos 7ps.slow这一步会爆错RuntimeError: could not open display,所以只能采取把生成的PNG图像文件保存到本地路径里的方法。脚本内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import matplotlib as mpl
mpl.use('Agg') #在无法生成图像的环境下要添加了上面两句话
import matplotlib.pyplot as plt
import numpy as np
import pylab as pl

x=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]
#横坐标的内容
labels=['10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','1','2','3','4','5','6','7','8','9']

#y1是delay延迟时长
with open('/存储路径/A.txt', 'r') as f:
y1 = []
for line in f:
lst = line.split('\n') #增加一个换行符,不然数字是不换行的
y1.append(float(lst[0]))

#y2是rate同步速率
with open('/存储路径/B.txt', 'r') as f:
y2 = []
for line in f:
lst = line.split('\n')
y2.append(float(lst[0]))

#输入对应的坐标,后面是颜色
plot1,=pl.plot(x,y1,'r')
plot2,=pl.plot(x,y2,'b')

pl.xticks(x,labels)

pl.title('这里写标题',size=20) #中文会显示乱码,推荐还是英文
pl.xlabel('这里是X轴标题', size=14)
pl.ylabel('这里写Y轴标题', size=14)
pl.ylim(0.0,5.0)

#曲线对应注释
pl.legend([plot1,plot2],('Delay','Sync rate'),'best',numpoints=1)

#开启网格
pl.grid()

#图片保存路径
plt.savefig('/保存路径/图片名称.png', format='png')

将生成的图片上传到阿里云OSS的脚本

由于不想让“领导去手动点开附件查看图像”,所以我们干脆把图片作为邮件的正文展示出来,那么就在html里就需要img src=图片的网络地址的方法。于是就把刚刚生成的图片上传到阿里云OSS里,这样就可以获得图片的网络地址。而且阿里云OSS是“相同文件名会覆盖”,所以不用再去删除。整个脚本内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# -*- coding: utf-8 -*-
import os
import shutil
import oss2

access_key_id = os.getenv('OSS_TEST_ACCESS_KEY_ID', '这里填写ak')
access_key_secret = os.getenv('OSS_TEST_ACCESS_KEY_SECRET', '这里填写sk')
bucket_name = os.getenv('OSS_TEST_BUCKET', '这里填写bucket名称')
endpoint = os.getenv('OSS_TEST_ENDPOINT', '这里填写内网end-point')

# 确认上面的参数都填写正确了
for param in (access_key_id, access_key_secret, bucket_name, endpoint):
assert '<' not in param, '请设置参数:' + param

# 创建Bucket对象,所有Object相关的接口都可以通过Bucket对象来进行
bucket = oss2.Bucket(oss2.Auth(access_key_id, access_key_secret), endpoint, bucket_name)
bucket.put_object_from_file('上传到OSS的图片名称.png', '/服务器保存路径/图片名称.png')

将图片作为内容发邮件的脚本

整个脚本内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import os,time,re,smtplib,logging
from email.mime.text import MIMEText
from email.header import Header

def send_mail(to_list, cc_list, html, sub):
me = mail_user
msg = MIMEText(html, _subtype='html', _charset='utf-8') # 格式化邮件内容为html,编码为utf-8
msg['Subject'] = sub # 邮件主题
msg['From'] = me # 发件人
msg['To'] = ";".join(to_list) # 收件人,将列表转换为字符串
msg['Cc'] = ";".join(cc_list) # 抄送人,将列表转换为字符串

try:
send_smtp = smtplib.SMTP() # 实例化
send_smtp.connect(mail_host) # 连接smtp服务器
send_smtp.login(mail_user, mail_pass) # 使用定义的账号密码进行登录
send_smtp.sendmail(me, to_list+cc_list, msg.as_string()) # 发送邮件
send_smtp.close() # 关闭连接
return True
except Exception, e:
logging.basicConfig(filename='logger.log', level=logging.DEBUG)
logging.debug(e)
print ("ERROR!!!!")
return False

if __name__ == '__main__':
mail_host = 'mail.dahuatech.com'
mail_user = '这里填写发件人地址'
mail_pass = '填写对应的密码'
mailto_list = ['收件人邮箱地址']
mailcc_list = ['抄送人1的邮箱地址''抄送人2的邮箱地址']
html = """
<body>
<br><img src="这里填写的是图片的http地址"></br>
<table color="CCCC33" width="800" border="1" cellspacing="0" cellpadding="5" text-align="center">
<tr>
<td test-align="center">上图是阿里云深圳VPC区数据同步过去24小时的情况。<br />
注意事项 1:dts的延迟时间是5秒计算一次,api请求会取到最新的延迟时间,而控制台是每隔20秒才刷新一次;
注意事项 2:api在延迟时间取值为整数,即1.x显示为2,请知悉;
注意事项 3:此邮件是系统自动发出,如果有任何疑问请联系运维人员;
</tr></br>
</table>
</body> """

sub = "阿里云深圳VPC数据同步情况"
if send_mail(mailto_list,mailcc_list,html,sub):
logging.debug("Send mail succed!")
else:
logging.debug("Send mail failed")

上面四个脚本整个执行下来,效果如下,至此大功告成!
paradin

参考资料

https://github.com/aliyun/aliyun-oss-python-sdk/blob/master/examples/object_basic.py
https://hk.saowen.com/a/fe355cb5cc3ab17dbc84e9489621d2ab31da72b511092839832bc9e89d63bf71
http://blog.csdn.net/baoli1008/article/details/47980779
https://www.digglife.net/articles/html-mail-with-inline-images-python-perl.html

感谢您请我喝咖啡~O(∩_∩)O,如果要联系请直接发我邮箱chenx1242@163.com,我会回复你的
-------------本文结束感谢您的阅读-------------