为 ping 添加时间戳后台运行实时输出保存日志

2021-06-09 16:15:13 +08:00
 wsgzao

前言

ping 命令是一种比较好用的网络诊断工具,常用来验证链路问题,例如 ping traceroute mtr 都使用的 “ICMP” 包来测试 Internet 两点之间的网络连接状况。生产环境中, 网络是否稳定(网络时延)是一个很重要的指标. 为了方便检查网络时延的大小, 我们可以通过 ping 命令实现长时间的网络监控。

本文主要记录了 Linux 环境如何使用 ping 命令+时间戳实时输出保存到文件里面的解决方案

更新历史

2021 年 06 月 06 日 - 初稿

阅读原文 - https://wsgzao.github.io/post/ping/


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)来转化,但是比较麻烦,最好的方式时回显时就是可读性较好的时间格式。

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: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

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 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

使用 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 &
1710 次点击
所在节点    Linux
3 条回复
ruanimal
2021-06-09 16:53:10 +08:00
ping 127.0.0.1 -c 5 | ts '[%Y-%m-%d %H:%M:%S]'
yanqiyu
2021-06-14 11:59:55 +08:00
systemd-run --user ping
ping 的输出会带着时间等等信息被存到 journal,然后用 journalctl 输出 json 格式再处理或者直接输出带时间的文本保存就行。
5up3r
2021-06-19 11:11:11 +08:00
ping baidu.com | while read line; do echo -e "$(date +"%Y-%m-%d %T") $line"; done

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/782436

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX