定时ping取返回值并绘图

时间:2019-10-10
本文章向大家介绍定时ping取返回值并绘图,主要包括定时ping取返回值并绘图使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

定时ping取返回值并绘图

  前些天一个朋友有要ping交易所前置以及绘制成折线图的需求,帮忙做了两天,感慨颇多,故写篇博客记录一下.

实际需求

  首先,我们的需求是,在window或者linux机器上定时执行ping + 网址 的语句,最终取到平均延迟,然后将这些延迟绘制成折线图.所以分析下来我们需要以下几个模块来实现这个功能.

需求分析

定时功能:

  datetime模块

用window机器远程控制linux机器,并发送指令:

  paramiko模块

绘制折线图:

  matplotlib模块

window机器上取本机的ping数据:

  subprocess模块

那么下面我们逐一分析这些模块,以及怎么样使用,完成最后的需求.

模块简介

datetime模块

相信我们都使用过这个模块,那么我们要实现每天定时来执行程序,就可以用以下方式来实现:

 
 
 
 
 
 
 
 
1
import datetime
2
import time
3
4
def main():
5
    while True:
6
        while True:
7
            now = datetime.datetime.now()# 这里可以取到系统的当前时间
8
            if now.hour == 6 and now.minute == 30:# 取当前时间的小时和分钟,这样每天到这个设定好的小时和分钟内的时候我们就会跳出这个内循环,进入到外循环,从而执行主函数
9
                # 当然设定时间我们也可以设定秒,但是其实设定到秒的情况下有可能无法进入函数,时间太短系统无法判定
10
                break
11
            if now.hour == 9 and now.minute == 30:
12
                break
13
            if now.hour == 12 and now.minute == 30:
14
                break
15
            if now.hour == 14 and now.minute == 30:
16
                break
17
            time.sleep(20)
18
        # 主函数
19
        time.sleep(60)# 这里加入睡眠60秒是为了让主函数不至于在这一分钟内一直执行,仅执行一次就好
20
 
 

subprocess模块

这个模块主要用于python调用系统的cmd窗口并返回结果,具体实现如下.

 
 
 
xxxxxxxxxx
1
26
 
 
 
 
1
# encoding=utf-8
2
import subprocess # 导入模块,没装的话自己去pip install subprocess
3
import sys
4
5
# 常用编码
6
GBK = 'gbk'
7
UTF8 = 'utf-8'
8
9
# 解码方式,一般 py 文件执行为utf-8 ,但是cmd 命令为 gbk
10
current_encoding = GBK
11
12
popen = subprocess.Popen(['ping', 'www.baidu.com'],
13
                         stdout=subprocess.PIPE,
14
                         stderr=subprocess.PIPE,
15
                         bufsize=1)
16
17
# 重定向标准输出
18
while popen.poll() is None:  # None表示正在执行中
19
    r = popen.stdout.readline().decode(current_encoding)
20
    sys.stdout.write(r)  # 可修改输出方式,比如控制台、文件等
21
22
# 重定向错误输出
23
if popen.poll() != 0:  # 不为0表示执行错误
24
    err = popen.stderr.read().decode(current_encoding)
25
    sys.stdout.write(err)  # 可修改输出方式,比如控制台、文件等
 
 

matplotlib折线图

 
 
 
x
 
 
 
 
1
'''
2
折线图绘制的时候主要碰到了下面几个问题:
3
1. 标签和折线的名称不能使用中文
4
解决:导入一个字体模块或者不用中文,用全拼或者英文
5
2. 绘图时候要控制图层的大小
6
解决: 在刚开始绘图的时候加入plt.figure(figsize=(10, 8)),可以调整图层的大小,后面的(10,8)实际大小是乘以100,也就是1000*800的图片大小
7
3. 最后保存图片的时候保存jpg格式出错
8
解决:需要额外装一个模块,语句 pip install pillow
9
'''
10
# 例程如下
11
from font_set import font_set# 这里我自己写了一个字体的模块,读者应该没有,可以忽略
12
import matplotlib.pyplot as plt
13
from pylab import mpl
14
15
mpl.rcParams['font.sans-serif'] = ['SimHei']  # SimHei是黑体的意思
16
17
x1 = ['06:00', '12:00', '18:00', '24:00']# 横轴
18
y1 = [4, 6, 8, 23]
19
z1 = [5, 5, 7, 15]
20
a1 = [2, 9, 10, 6]
21
22
# x = np.random.random_integers(1, 20, 10)
23
# # y = range(len(x))
24
25
26
fig = plt.figure(figsize=(10, 8))# 控制图层的大小
27
ax = fig.add_subplot(1, 1, 1)
28
ax.plot(x1, y1)
29
for x, y in zip(x1, y1):
30
    plt.text(x, y + 0.3, '%.0f' % y, ha='center', va='bottom', fontsize=10.5)
31
ax.plot(x1, z1)
32
for x, y in zip(x1, z1):
33
    plt.text(x, y + 0.3, '%.0f' % y, ha='center', va='bottom', fontsize=10.5)
34
ax.plot(x1, a1)
35
for x, y in zip(x1, a1):
36
    plt.text(x, y + 0.3, '%.0f' % y, ha='center', va='bottom', fontsize=10.5)
37
38
plt.xlabel(u'时间', FontProperties=font_set)
39
plt.ylabel(u'延迟', FontProperties=font_set)
40
plt.title(u"各交易所交易延时", FontProperties=font_set)
41
plt.legend([u"中金所", u"上期所", u"大商所"], prop=font_set)
42
plt.savefig("1.jpg")# 这里要注意,要先保存再show,如果先show了保存图片就会是空白
43
plt.show()
 
 

paramiko模块

 
 
 
x
81
 
 
 
 
1
'''
2
  paramiko模块主要作用是用python来远程连接服务器,发送请求以及取数据,由于使用的是python这样的能够跨平台运行的语言,所以所有python支持的平台,如Linux, Solaris, BSD, MacOS X, Windows等,paramiko都可以支持,因此,如果需要使用SSH从一个平台连接到另外一个平台,进行一系列的操作时,paramiko是最佳工具之一。
3
'''
4
5
class Ping_jifang:# 定义一个ping的类
6
7
    def __init__(self, host_ip, username, password, command, port=22):
8
        self.ssh = paramiko.SSHClient()
9
        self.host_ip = host_ip
10
        self.username = username
11
        self.password = password
12
        self.command = command
13
        self.port = port
14
15
    def ssh_jifang(self):
16
        self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
17
        try:
18
            self.ssh.connect(self.host_ip, self.port, self.username, self.password, timeout=8)
19
            return True
20
        except Exception as fail:
21
            return False
22
23
    def exec_ssh_command(self):
24
        stdin, stdout, stderr = self.ssh.exec_command(self.command)
25
        result_all = stdout if stdout else stderr
26
        # print(result_all.readlines())
27
        return result_all.readline()
28
        # return stdout
29
        # print(self.command)
30
        # result_all = os.popen(self.command)
31
        # return result_all
32
33
    def logout(self):
34
        self.ssh.close()
35
36
def main():
37
    print('进入主函数')
38
    ip_dit = {
39
        "yidong1": {
40
            "info": ["ip地址", "用户名", "密码"]
41
        },
42
        "yidong2": {
43
            "info": ["ip地址", "用户名", "密码"]
44
        },
45
        "shuxun": {
46
            "info": ["ip地址", "用户名", "密码"]
47
        },
48
        "languang": {
49
            "info": ["ip地址", "用户名", "密码"]
50
        }
51
    }
52
53
    # 这个语句就是我们用当前操作机来发送给linux机器的语句
54
    command_ping = "ping 114.114.114.114 -c 100 -i 0.001 -f | grep 'rtt' | awk -F '[ =/]+' '{print $7}'"
55
56
    for i in ip_dit:
57
58
        client_ping = Ping_jifang(ip_dit[i]["info"][0], ip_dit[i]["info"][1], ip_dit[i]["info"][2], command_ping)
59
        if client_ping.ssh_jifang():
60
            result = client_ping.exec_ssh_command()
61
            result = eval(result[:-2])# 因为绘图需要列表,列表内要是int或者float数据,所以这里我们切割掉\n,然后用eval去掉引号,从而使列表内是符合要求的可以绘图的数据
62
63
            # print(i)
64
            # print(type(a),yidong2.append(a),yidong2)
65
            if i == "yidong1":
66
                yidong1.append(result)
67
            elif i == "yidong2":
68
                yidong2.append(result)
69
            elif i == "shuxun":
70
                shuxun.append(result)
71
            elif i == "languang":
72
                languang.append(result)
73
            else:
74
                pass
75
            client_ping.logout()
76
77
    print(yidong1)
78
    print(yidong2)
79
    print(shuxun)
80
    print(languang)
 
 

模块的使用就如上介绍,下面放上在linux和window机器上分别可以使用的完整程序.

window版本程序

 
 
 
xxxxxxxxxx
1
112
 
 
1
'''
2
此程序是取本机(windows)对于其他网址的ping延迟
3
'''
4
import subprocess, sys, time, re, datetime
5
import numpy as np
6
import matplotlib.pyplot as plt
7
from matplotlib.font_manager import FontProperties
8
from pylab import mpl
9
from threading import Thread
10
11
mpl.rcParams['font.sans-serif'] = ['SimHei']  # SimHei是黑体的意思
12
plt.style.use('ggplot')
13
14
np.random.seed(1)
15
16
# 字体要导一下,还有别的导字体方法,这只是一种
17
font_set = FontProperties(fname=r"D:\\msyh.ttc", size=12)
18
19
count = 0
20
21
22
# %Y-%m-%d
23
def delay(host):
24
    popen = subprocess.Popen(['ping', host],
25
                             stdout=subprocess.PIPE,
26
                             stderr=subprocess.PIPE,
27
                             bufsize=1)
28
    while popen.poll() is None:
29
        r = popen.stdout.readline().decode('gbk')
30
        # sys.stdout.write(r)
31
32
        # 这里是取字段的功能,linux里面应该是按avg取,windows里面是按汉字'平均'取得
33
        res = re.findall(r'平均 = (.*?)ms', r)
34
        if res:
35
            return res[0]
36
    if popen.poll() != 0:
37
        err = popen.stderr.read()
38
        sys.stdout.write(err)
39
40
41
def run():
42
    print('进入程序主体')
43
    global time_x
44
    time_x.append(time_now)
45
    res1 = delay('www.qq.com')
46
    global lis1
47
    lis1.append(eval(res1))
48
    res2 = delay('www.baidu.com')
49
    global lis2
50
    lis2.append(eval(res2))
51
    res3 = delay('www.jianshu.com')
52
    global lis3
53
    lis3.append(eval(res3))
54
    res4 = delay('www.runoob.com')
55
    global lis4
56
    lis4.append(eval(res4))
57
58
    print(len(lis1))
59
    print(lis1)
60
    time.sleep(1)
61
    if len(lis1) == 4:  # 当取到四个延迟数据,也就是一天过去的时候,会生成折线图
62
        print('进入绘图函数')
63
        plt.figure(figsize=(10, 8))  # 调整图层大小
64
        plt.plot(time_x, lis1, marker='o', mec='b', mfc='w', label=u'QQ')
65
        for x, y in zip(time_x, lis1):
66
            plt.text(x, y + 0.3, '%.0f' % y, ha='center', va='bottom', fontsize=10.5)
67
68
        plt.plot(time_x, lis2, marker='v', mec='g', mfc='w', label=u'百度')
69
70
        plt.plot(time_x, lis3, marker='^', mec='r', mfc='w', label=u'简书')
71
        plt.plot(time_x, lis4, marker='s', mec='y', mfc='w', label=u'菜鸟编程')
72
        plt.plot([0, 15, 30, 45], "rd")
73
        plt.margins(0)
74
        plt.subplots_adjust(bottom=0.10)
75
        plt.xlabel(u'时间', FontProperties=font_set)  # X轴标签
76
        plt.ylabel(u'延迟ms', FontProperties=font_set)  # Y轴标签
 
 
77
        plt.title(u"各交易所交易延时", FontProperties=font_set)
78
79
        plt.grid(True)
80
        plt.legend(loc=0)
81
        global count
82
        count += 1
83
        plt.tight_layout()
84
        plt.savefig(f"{date}-{count}.jpg")  # 保存的文件名
85
        # plt.show()
86
        plt.close()  # 这里要注意,一定要关闭当前图层,不然之后画出来的图会和之前的图合并出现
87
        print('重置列表')
88
        time_x.clear()
89
        lis1.clear()
90
        lis2.clear()
91
        lis3.clear()
92
        lis4.clear()
93
94
95
if __name__ == '__main__':
96
    # 设定的开始时间,即第一次等于这个时间的时候开始进入程序,得到第一个延迟数据,之后可以一直不关,这个时间会一直保持增长
97
    sched_Timer = datetime.datetime(2019, 9, 27, 10, 38, 00)
98
99
    lis1 = list()
100
    lis2 = list()
101
    lis3 = list()
102
    lis4 = list()
103
    time_x = list()
104
    while True:
105
        date = time.strftime('%Y-%m-%d', time.localtime(time.time()))
106
        time_now = time.strftime('%H:%M:%S', time.localtime(time.time()))
107
        now = datetime.datetime.now()  # 取到当前系统的时间
108
        # if sched_Timer < now < (sched_Timer + datetime.timedelta(seconds=1)):
109
        if 1 == 1:
110
            t1 = Thread(target=run)  # 子线程
111
            t1.start()
112
            t1.join()
113
            # 这里是延迟时间,即设定为hour=6就是六个小时ping一次数据,minutes=1就是一分钟ping一次,累计四次才会生成一个图片
114
            sched_Timer = sched_Timer + datetime.timedelta(minutes=1)
115
 
 

linux版本程序

 
 
 
x
4
147
 
 
 
 
1
'''
2
此程序是本机通过远程linux机器来取不同linux机器的ping的延迟
3
'''
4
import paramiko
5
import time
6
import datetime
7
import matplotlib.pyplot as plt
8
9
# font_set = FontProperties(fname=r"D:\\msyh.ttc", size=12)
10
# font_set = FontProperties(fname='utf-8', size=12)
11
12
13
class Ping_jifang:
14
15
    def __init__(self, host_ip, username, password, command, port=22):
16
        self.ssh = paramiko.SSHClient()
17
        self.host_ip = host_ip
18
        self.username = username
19
        self.password = password
20
        self.command = command
21
        self.port = port
22
23
    def ssh_jifang(self):
24
        self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
25
        try:
26
            self.ssh.connect(self.host_ip, self.port, self.username, self.password, timeout=8)
27
            return True
28
        except Exception as fail:
29
            return False
30
31
    def exec_ssh_command(self):
32
        stdin, stdout, stderr = self.ssh.exec_command(self.command)
33
        result_all = stdout if stdout else stderr
34
        # print(result_all.readlines())
35
        return result_all.readline()
36
        # return stdout
37
        # print(self.command)
38
        # result_all = os.popen(self.command)
39
        # return result_all
40
41
    def logout(self):
42
        self.ssh.close()
43
44
45
def main():
46
    print('进入主函数')
47
    ip_dit = {
48
        "yidong1": {
49
            "info": ["10.0.0.99", "root", "1"]
50
        },
51
        "yidong2": {
52
            "info": ["10.221.1.190", "root", "htqh@2019"]
53
        },
54
        "shuxun": {
55
            "info": ["10.225.1.94", "root", "123456"]
56
        },
57
        "languang": {
58
            "info": ["10.121.137.58", "root", "htqh@1234"]
59
        }
60
    }
61
62
    command_ping = "ping 114.114.114.114 -c 100 -i 0.001 -f | grep 'rtt' | awk -F '[ =/]+' '{print $7}'"
63
64
    for i in ip_dit:
65
66
        client_ping = Ping_jifang(ip_dit[i]["info"][0], ip_dit[i]["info"][1], ip_dit[i]["info"][2], command_ping)
67
        if client_ping.ssh_jifang():
68
            result = client_ping.exec_ssh_command()
69
            result = eval(result[:-2])
70
71
            # print(i)
72
            # print(type(a),yidong2.append(a),yidong2)
73
            if i == "yidong1":
74
                yidong1.append(result)
75
            elif i == "yidong2":
76
                yidong2.append(result)
77
            elif i == "shuxun":
78
                shuxun.append(result)
79
            elif i == "languang":
80
                languang.append(result)
81
            else:
82
                pass
83
            client_ping.logout()
84
85
    print(yidong1)
86
    print(yidong2)
87
    print(shuxun)
88
    print(languang)
89
90
    # 绘图函数
91
    if len(yidong2) == 4:  # 当取到四个延迟数据,也就是一天过去的时候,会生成折线图
92
        plt.figure(figsize=(10, 8))  # 调整图层大小
93
        time_x = ['06:00', '09:00', '12:00', '15:00']
94
        date = time.strftime('%Y-%m-%d', time.localtime(time.time()))
95
        print('进入绘图函数')
96
        # plt.plot(time_x, yidong1, marker='o', mec='b', mfc='w', label=u'QQ')
97
        for x, y in zip(time_x, yidong2):
98
            plt.text(x, y + 0.3, '%.0f' % y, ha='center', va='bottom', fontsize=10.5)
99
        plt.plot(time_x, yidong2, marker='v', mec='g', mfc='w', label=u'shuxun')
100
        plt.plot(time_x, shuxun, marker='^', mec='r', mfc='w', label=u'zhongjinsuo')
101
        plt.plot(time_x, languang, marker='s', mec='y', mfc='w', label=u'yidong')
102
        plt.ylim(0, 20) # 纵坐标范围
103
        y = range(0, 20, 1)
104
        plt.yticks(y)   # 纵坐标刻度
105
        plt.margins(0)
106
        plt.subplots_adjust(bottom=0.10)
107
        plt.xlabel(u'time')  # X轴标签
108
        plt.ylabel(u'ms')  # Y轴标签
109
        plt.title(u"timedelate")
110
111
        plt.legend(loc=0)
112
        global count
113
        count += 1
114
        plt.tight_layout()
115
        plt.savefig(f"{date}-{count}.jpg")  # 保存的文件名
116
        # plt.show()
117
        plt.close()  # 这里要注意,一定要关闭当前图层,不然之后画出来的图会和之前的图合并出现
118
        print('重置列表')
119
        time_x.clear()
120
        yidong1.clear()
121
        yidong2.clear()
122
        shuxun.clear()
123
        languang.clear()
124
125
126
if __name__ == "__main__":
127
    yidong1 = []
128
    yidong2 = []
129
    shuxun = []
130
    languang = []
131
    count = 0
132
    while True:
133
        while True:
134
            now = datetime.datetime.now()
135
            print(f'\r当前时间:{now}', end='')
136
            if now.hour == 16 and now.minute == 1:
137
                break
138
            if now.hour == 16 and now.minute == 15:
139
                break
140
            if now.hour == 16 and now.minute == 16:
141
                break
142
            if now.hour == 16 and now.minute == 17:
143
                break
144
            time.sleep(1)
145
        time.sleep(61)
146
        main()
147
 
 

原文地址:https://www.cnblogs.com/Xu-PR/p/11650298.html