1. Overview
ping is one of the most popular commands to troubleshoot connectivity problems in a network. It displays the round-trip time of each message. However, it doesn’t print timestamps.
In this tutorial, we’ll discuss how to print a timestamp for each message while using ping.
2. The Default Behavior
Let’s start pinging the localhost:
$ ping -c 3 localhost
PING localhost(localhost (::1)) 56 data bytes
64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.021 ms
64 bytes from localhost (::1): icmp_seq=2 ttl=64 time=0.024 ms
64 bytes from localhost (::1): icmp_seq=3 ttl=64 time=0.081 ms
--- localhost ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2030ms
rtt min/avg/max/mdev = 0.021/0.042/0.081/0.027 ms
We sent three ICMP Echo Request messages using the –c option of ping. Consequently, we received the corresponding ICMP Echo Reply messages successfully. The round-trip times are printed after each reply. However, no timestamp is printed.
Sometimes, we may need timestamps in the output of ping. We’ll look for solutions for adding timestamps in the subsequent sections.
3. Using the -D Option of ping and awk
We can use the -D option of ping for printing timestamps:
$ ping -D -c 3 localhost
PING localhost(localhost (::1)) 56 data bytes
[1695919328.066789] 64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.032 ms
[1695919329.098038] 64 bytes from localhost (::1): icmp_seq=2 ttl=64 time=0.070 ms
[1695919330.121734] 64 bytes from localhost (::1): icmp_seq=3 ttl=64 time=0.042 ms
--- localhost ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2054ms
rtt min/avg/max/mdev = 0.032/0.048/0.070/0.016 ms
The timestamps are printed within brackets at the beginning of each ping message. However, they’re epoch times. For example, the epoch time for the first ping is 1695919328.066789.
We can use awk to convert epoch times to a human-readable format:
$ ping -D -c 3 localhost | awk '{if(gsub(/\[|\]/, "", $1)) {$1= strftime("[%F %T]", $1); print} else print }'
PING localhost(localhost (::1)) 56 data bytes
[2023-09-28 11:48:08] 64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.017 ms
[2023-09-28 11:48:09] 64 bytes from localhost (::1): icmp_seq=2 ttl=64 time=0.027 ms
[2023-09-28 11:48:10] 64 bytes from localhost (::1): icmp_seq=3 ttl=64 time=0.083 ms
--- localhost ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2034ms
rtt min/avg/max/mdev = 0.017/0.042/0.083/0.029 ms
As is apparent from the output, the timestamps are now in a human-readable date and time format.
We pass the output of ping -D -c 3 localhost to awk using a pipe. Let’s write the program part of awk in a more user-friendly way to understand what it does:
if(gsub(/\[|\]/, "", $1)) {
$1= strftime("[%F %T]", $1);
print
}
else
print
We try to substitute the opening and closing brackets in the first field with an empty string using gsub(/\[|\]/, “”, $1). The gsub() function of awk returns the number of substitutions made.
In case of a successful substitution, the condition of the if statement becomes true. Then, we format the epoch time using the strftime() function of awk. The format string, *“**[%F %T]*“, specifies how we want to format the epoch time. The date format specification %F is equivalent to %Y-%m-%d. Similarly, the time format specification %T is equivalent to %H:%M:%S.
Having formatted the epoch time, we print the line using print.
If the substitution is unsuccessful, for example, for the first line PING localhost(localhost (::1)) 56 data bytes, then we’re in the else part of the if statement. We just print the line as-is using print in that case.
4. Using date
Another way of adding timestamps to the output is using the date command:
$ ping -c 3 localhost | while read result; do echo "[$(date)] $result";done
[Thu 28 Sep 2023 11:58:34 AM CDT] PING localhost(localhost (::1)) 56 data bytes
[Thu 28 Sep 2023 11:58:34 AM CDT] 64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.026 ms
[Thu 28 Sep 2023 11:58:35 AM CDT] 64 bytes from localhost (::1): icmp_seq=2 ttl=64 time=0.029 ms
[Thu 28 Sep 2023 11:58:36 AM CDT] 64 bytes from localhost (::1): icmp_seq=3 ttl=64 time=0.022 ms
[Thu 28 Sep 2023 11:58:36 AM CDT]
[Thu 28 Sep 2023 11:58:36 AM CDT] --- localhost ping statistics ---
[Thu 28 Sep 2023 11:58:36 AM CDT] 3 packets transmitted, 3 received, 0% packet loss, time 2044ms
[Thu 28 Sep 2023 11:58:36 AM CDT] rtt min/avg/max/mdev = 0.022/0.025/0.029/0.003 ms
We’re successful in adding timestamps to the output. However, timestamps are added to every line this time.
First, we pass each line in the output of ping -c 3 localhost to a while loop using a pipe. Then, we store each line to the result variable using the read command in the while read result statement. Finally, we append the output of the date command to result and print it using echo “[$(date)] $result”.
5. Using ts
The ts command, which is found in some Linux distributions like Debian, is another option for adding timestamps. It’s available in the moreutils package.
We need to pass the output of ping to ts using a pipe:
$ ping -c 3 localhost | ts
Sep 27 14:24:50 PING localhost(localhost (::1)) 56 data bytes
Sep 27 14:24:50 64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.020 ms
Sep 27 14:24:51 64 bytes from localhost (::1): icmp_seq=2 ttl=64 time=0.024 ms
Sep 27 14:24:52 64 bytes from localhost (::1): icmp_seq=3 ttl=64 time=0.023 ms
Sep 27 14:24:52
Sep 27 14:24:52 --- localhost ping statistics ---
Sep 27 14:24:52 3 packets transmitted, 3 received, 0% packet loss, time 2038ms
Sep 27 14:24:52 rtt min/avg/max/mdev = 0.020/0.022/0.024/0.001 ms
We’re successful in adding timestamps. However, ts adds a timestamp to all lines in the output of ping, just like the previous method.
6. Conclusion
In this article, we discussed how to add timestamps to the output of ping.
After seeing the default behavior of ping, we learned how to add timestamps using the -D option of ping. However, since the -D option prints epoch times, we converted the epoch times to a human-readable format using the strftime() function of awk.
Then, we used the date command in a while loop to add timestamps to the output.
Finally, we saw that the ts command, which is available in some Linux distros, could be another option.