• 定时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数据,所以这里我们切割掉
    ,然后用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'
    当前时间:{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
     
     
  • 相关阅读:
    exploded archive 和packaged archive 区别
    MyEclipse6.5使用设置技巧及快捷键
    本机上设置域名解析
    Cookie的生命周期问题
    简单的函数柯里化
    cookie操作
    自定义事件
    解耦应用逻辑/事件处理程序
    dragdrop + 自定义事件
    在窃取函数中用作用域安全的构造函数
  • 原文地址:https://www.cnblogs.com/Xu-PR/p/11650298.html
Copyright © 2020-2023  润新知