定時ping取返回值並繪圖

 

定時ping取返回值並繪圖

  前些天一個朋友有要ping交易所前置以及繪製成折線圖的需求,幫忙作了兩天,感慨頗多,故寫篇博客記錄一下.node

實際需求

  首先,咱們的需求是,在window或者linux機器上定時執行ping + 網址 的語句,最終取到平均延遲,而後將這些延遲繪製成折線圖.因此分析下來咱們須要如下幾個模塊來實現這個功能.python

需求分析

定時功能:linux

  datetime模塊web

用window機器遠程控制linux機器,併發送指令:編程

  paramiko模塊windows

繪製折線圖:服務器

  matplotlib模塊併發

window機器上取本機的ping數據:app

  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
相關文章
相關標籤/搜索