2

Preface

The ping command is a relatively easy-to-use network diagnostic tool. It is often used to verify link problems. For example, ping traceroute mtr uses the "ICMP" package to test the network connection between two points on the Internet. In the production environment, whether the network is stable (network delay) is a very important indicator. In order to facilitate checking the size of the network delay, we can implement long-term network monitoring through the ping command.

This article mainly records the solution of how to use the ping command + timestamp in the Linux environment to save the real-time output to the file.

Update history

June 06, 2021-First Draft

Read the original text- https://wsgzao.github.io/post/ping/


Introduction to ping

You may use ping every day, so I won’t introduce more

Ping (呯) is a computer network tool used to test whether a data packet can reach a specific host through the IP protocol. The working principle of ping is to send an ICMP request echo packet to the target host and wait for the echo response packet to be received. The program estimates the packet loss rate (packet loss rate) and packet round-trip time (network delay, Round-trip delay time) based on the time and the number of successful responses.

ping ip directly.

If ping is displayed, this command also provides the parameter -D timestamp.

# 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

However, the time stamp is poor in readability. Although some tools on the Internet ( unitxtime ) can be used to convert, it is more troublesome. The best way is to echo the time format with better readability.

Use of ping command

Common parameters

-i: The interval between each ping operation, the default is 1s;

-c: The number of times to perform the ping operation, the default is to always execute unless it is interrupted;

-s: Specify the size of the packet sent during the ping operation, the default is 56B, after adding the header, the final message sent is 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 redirects the output to the specified file

Use fflush

Note: Use fflush(), otherwise the file will not have information, because awk is also cached.

To prevent the script from being interrupted, you can use nohup to make the script execute in the background:

# 下面未加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

Use pong

  1. What is pingpong?

Pingpong is a means of data caching. Through pingpong operation, the efficiency of data transmission can be improved.

  1. When do you need pingpong?

When exchanging data between the two modules, the result of the upper level processing cannot be processed by the next level immediately, so the upper level must wait for the next level processing to be completed before sending new data, which will have a great impact on performance. Big loss.

After the introduction of pingpong, we can not wait for the end of the next level of processing, but save the results in the cache of the pong road. When the data of the pong road is ready, the data of the ping road is also processed (the next level), and then there is no need Waiting to directly process the pong road data, the upper level does not need to wait, and instead stores the result in the ping road. This improves the processing efficiency.

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 timestamp

Data stamp conversion

date can convert the timestamp to localtime.

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

awk stitching

# 格式可以自定义调整
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 ms
Wed 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 ms
Wed 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 ms
2021-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 ms
2021-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

If awk does not have strftime()

Notice: An error "Can't locate Time/Piece.pm in @INC" is reported, and the command yum -y install perl-Time-Piece needs to be executed to install the necessary packages.

# 要将其重定向到文件,请使用标准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 ms
Wed 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 ms
Wed 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 ms
Wed 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 ms
Wed 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 ms

ping 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 ms
2021-06-09T10:37:09 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=40 time=83.4 ms
2021-06-09T10:37:10 64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=3 ttl=40 time=83.2 ms

Knowledge supplement

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 没有自动换行

王奥OX
1.9k 声望88 粉丝

[链接]