前言

ping命令是一种比拟好用的网络诊断工具,罕用来验证链路问题,例如 ping traceroute mtr 都应用的 “ICMP” 包来测试 Internet 两点之间的网络连接情况。生产环境中, 网络是否稳固(网络时延)是一个很重要的指标. 为了不便查看网络时延的大小, 咱们能够通过ping命令实现长时间的网络监控。

本文次要记录了Linux环境如何应用ping命令+工夫戳实时输入保留到文件外面的解决方案

更新历史

2021年06月06日 - 初稿

浏览原文 - https://wsgzao.github.io/post...


ping简介

ping大家可能每天都在应用,不多做介绍了

ping(呯)是一种计算机网络工具,用来测试数据包是否透过IP协定达到特定主机。ping的运作原理是向指标主机传出一个ICMP的申请回显数据包,并期待接管回显回应数据包。程序会按工夫和胜利响应的次数估算失落数据包率(丢包率)和数据包往返工夫(网络时延,Round-trip delay time)。

间接ping ip即可。

若显示ping的回显工夫,此命令也提供了参数 -D来回显工夫戳。

# ping baidu.com -DPING baidu.com (39.156.69.79) 56(84) bytes of data.[1623205720.047547] 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=1 ttl=23 time=274 ms[1623205720.321747] 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=23 time=274 ms[1623205721.322361] 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=23 time=274 ms[1623205722.323220] 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=4 ttl=23 time=274 ms[1623205723.324359] 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=5 ttl=23 time=274 ms

然而,工夫戳可读性较差,尽管能够利用网上的一些工具(unitxtime)来转化,然而比拟麻烦,最好的形式时回显时就是可读性较好的工夫格局。

ping命令的应用

罕用参数

-i: 每次执行ping操作的间隔时间, 默认是1s;

-c: 执行ping操作的次数, 默认是始终执行, 除非被中断;

-s: 指定执行ping操作时发送的包的大小, 默认是56B, 增加报文头之后, 最终发送的是64B.

# 在终端 ping 某个地址, 执行10次ping baidu.com -c 10 | awk '{ print $0"\t" strftime("%H:%M:%S",systime()) } '64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=1 ttl=40 time=83.3 ms       10:41:2364 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=40 time=83.4 ms       10:41:2464 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=40 time=83.4 ms       10:41:25# 日期在前面ping baidu.com | awk '{ print $0"\t" strftime("%Y-%m-%d %H:%M:%S",systime()); fflush()}'64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=1 ttl=40 time=83.2 ms       2021-06-09 10:42:4564 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=40 time=83.3 ms       2021-06-09 10:42:4664 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=40 time=83.3 ms       2021-06-09 10:42:47# 日前在后面ping baidu.com | awk '{ print strftime("%Y.%m.%d %H:%M:%S",systime())"\t" $0; fflush() }'2021.06.09 10:43:28     64 bytes from 220.181.38.148 (220.181.38.148): icmp_seq=1 ttl=46 time=162 ms2021.06.09 10:43:29     64 bytes from 220.181.38.148 (220.181.38.148): icmp_seq=2 ttl=46 time=177 ms2021.06.09 10:43:30     64 bytes from 220.181.38.148 (220.181.38.148): icmp_seq=3 ttl=46 time=174 ms

ping将输入重定向到指定文件

应用fflush

留神:应用fflush(),不然文件不会有信息,因为awk也是有缓存的。

为避免脚本被中断, 能够通过 nohup 令脚本在后盾执行:

# 上面未加fflush(),执行命令生成文件会等一会才会有信息打印到文件里nohup ping baidu.com | awk '{ print strftime("%Y-%m-%d %H:%M:%S",systime())"\t" $0; fflush() }' >> long_ping.txt &$ tail -f long_ping.txt 2021-06-09 10:45:54     64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=40 time=83.3 ms2021-06-09 10:45:55     64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=40 time=83.3 ms2021-06-09 10:45:56     64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=4 ttl=40 time=83.3 ms# 要完结后盾过程, 可通过下述形式查找并kill$ ps -ef |grep pinguser00    5778 30382  0 10:45 pts/2    00:00:00 ping baidu.comuser00    7133 30382  0 10:48 pts/2    00:00:00 grep --color=auto ping$ kill -9 5778[1]+  Done                    nohup ping baidu.com | awk '{ print strftime("%Y.%m.%d %H:%M:%S",systime())"\t" $0; fflush() }' >> long_ping.txt

应用pong

  1. 什么是pingpong?

pingpong是一种数据缓存的伎俩,通过pingpong操作能够进步数据传输的效率。

  1. 什么时候须要pingpong?

在两个模块间替换数据时,上一级解决的后果不能马上被下一级所解决实现,这样上一级必须期待下一级解决实现才能够送新的数据,这样就会对性能产生很大的损失。

引入pingpong后咱们能够不去期待下一级解决完结,而是将后果保留在pong路的缓存中,pong路的数据筹备好的时刻,ping路的数据也处理完毕(下一级),而后无需期待间接解决pong路数据,上一级也无需期待,转而将后果存储在ping路。这样便进步了解决效率。

nohup ping baidu.com -i 1 | while read pong; do echo "$(date +"%Y-%m-%d %H:%M:%S") | $pong"; done | tee -a ping-baidu.com.log &

date工夫戳

数据戳转化

date能够将工夫戳转化为localtime。

# date -d @1623205723.324359Wed Jun  9 10:28:43 CST 2021# date --date=@1623205723.324359Wed Jun  9 10:28:43 CST 2021利用awk进行转化,比拟麻烦。

awk拼接

# 格局能够自定义调整ping baidu.com | awk '{"date" | getline date; print date,$0}'Wed Jun  9 10:33:01 CST 2021 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=40 time=83.3 msWed Jun  9 10:33:01 CST 2021 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=40 time=83.5 msWed Jun  9 10:33:01 CST 2021 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=4 ttl=40 time=83.3 ms# 工夫格局可依据date自定义ping baidu.com | awk -v date="$(date +"%Y-%m-%d %r")" '{print date, $0}'2021-06-09 10:33:38 AM 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=1 ttl=40 time=83.3 ms2021-06-09 10:33:38 AM 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=40 time=83.5 ms2021-06-09 10:33:38 AM 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=40 time=83.6 ms

perl

如果 awk 没有 strftime()

Notice:报错“Can’t locate Time/Piece.pm in @INC”,须要执行命令yum -y install perl-Time-Piece来进行必要包的装置。

# 要将其重定向到文件,请应用规范shell重定向并敞开输入缓冲:ping baidu.com | perl -nle 'print scalar(localtime), " ", $_'Wed Jun  9 10:36:14 2021 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=40 time=83.4 msWed Jun  9 10:36:15 2021 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=40 time=83.5 msWed Jun  9 10:36:16 2021 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=4 ttl=40 time=83.3 ms# 如果显示ISO8601工夫格局ping baidu.com | perl -nle 'BEGIN {$|++} print scalar(localtime), " ", $_'Wed Jun  9 10:36:41 2021 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=1 ttl=40 time=83.3 msWed Jun  9 10:36:42 2021 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=40 time=83.3 msWed Jun  9 10:36:43 2021 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=40 time=83.5 msping baidu.com | perl -nle 'use Time::Piece; BEGIN {$|++} print localtime->datetime, " ", $_'2021-06-09T10:37:08 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=1 ttl=40 time=83.4 ms2021-06-09T10:37:09 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=40 time=83.4 ms2021-06-09T10:37:10 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=40 time=83.2 ms

常识补充

strftime补充:函数strftime()的操作有些相似于sprintf():辨认以百分号(%)开始的格局命令汇合,格式化输入后果放在一个字符串中。格式化命令阐明串strDest中各种日期和工夫信息的确切示意办法。格局串中的其余字符原样放进串中。格局命令列在上面,它们是辨别大小写的。%a 星期几的简写%A 星期几的全称%b 月份的简写%B 月份的全称%c 规范的日期的工夫串%C 年份的前两位数字%d 十进制示意的每月的第几天%D 月/天/年%e 在两字符域中,十进制示意的每月的第几天%F 年-月-日%g 年份的后两位数字,应用基于周的年%G 年份,应用基于周的年%h 简写的月份名%H 24小时制的小时%I 12小时制的小时%j 十进制示意的每年的第几天%m 十进制示意的月份%M 十时制示意的分钟数%n 新行符%p 本地的AM或PM的等价显示%r 12小时的工夫%R 显示小时和分钟:hh:mm%S 十进制的秒数%t 程度制表符%T 显示时分秒:hh:mm:ss%u 每周的第几天,星期一为第一天 (值从1到7,星期一为1)%U 第年的第几周,把星期日作为第一天(值从0到53)%V 每年的第几周,应用基于周的年%w 十进制示意的星期几(值从0到6,星期天为0)%W 每年的第几周,把星期一做为第一天(值从0到53)%x 规范的日期串%X 规范的工夫串%y 不带世纪的十进制年份(值从0到99)%Y 带世纪局部的十制年份%z,%Z 时区名称,如果不能失去时区名称则返回空字符。%% 百分号语法strftime(format,timestamp)参数 形容format 可选。规定如何返回后果。timestamp 可选。工夫戳,默认是以后本地的awk补充:awk工作流程是这样的:先执行BEGING,而后读取文件,读入有/n换行符宰割的一条记录,而后将记录按指定的域分隔符划分域,填充域,$0则示意所有域,$1示意第一个域,$n示意第n个域,随后开始执行模式所对应的动作action。接着开始读入第二条记录······直到所有的记录都读完,最初执行END操作。print与printf补充:print 中不能应用%s ,%d 或%c;print 主动换行,printf 没有主动换行