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 -D
PING 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)来转化,但是比较麻烦,最好的方式时回显时就是可读性较好的时间格式。
常用参数
-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:23
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=40 time=83.4 ms 10:41:24
64 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:45
64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=40 time=83.3 ms 2021-06-09 10:42:46
64 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 ms
2021.06.09 10:43:29 64 bytes from 220.181.38.148 (220.181.38.148): icmp_seq=2 ttl=46 time=177 ms
2021.06.09 10:43:30 64 bytes from 220.181.38.148 (220.181.38.148): icmp_seq=3 ttl=46 time=174 ms
注意:使用 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 ms
2021-06-09 10:45:55 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=40 time=83.3 ms
2021-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 ping
user00 5778 30382 0 10:45 pts/2 00:00:00 ping baidu.com
user00 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
pingpong 是一种数据缓存的手段,通过 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 &
1
ruanimal 2021-06-09 16:53:10 +08:00 1
ping 127.0.0.1 -c 5 | ts '[%Y-%m-%d %H:%M:%S]'
|
2
yanqiyu 2021-06-14 11:59:55 +08:00 1
systemd-run --user ping
ping 的输出会带着时间等等信息被存到 journal,然后用 journalctl 输出 json 格式再处理或者直接输出带时间的文本保存就行。 |