How do I timestamp every ping result?
Asked Answered
N

16

104

Ping returns this by default:

64 bytes from 203.173.50.132: icmp_seq=0 ttl=244 time=57.746 ms

Is there some way I can get it to add the timestamp?

For example,

Mon 21 May 2012 15:15:37 EST | 64 bytes from 203.173.50.132: icmp_seq=0 ttl=244 time=57.746 ms

I'm on OS X v10.7 (Lion) which seems to have some BSD version of ping.

Negron answered 21/5, 2012 at 5:17 Comment(0)
I
32

On OS X you can simply use the --apple-time option:

ping -i 2 --apple-time www.apple.com

Produces results like:

10:09:55.691216 64 bytes from 72.246.225.209: icmp_seq=0 ttl=60 time=34.388 ms
10:09:57.687282 64 bytes from 72.246.225.209: icmp_seq=1 ttl=60 time=25.319 ms
10:09:59.729998 64 bytes from 72.246.225.209: icmp_seq=2 ttl=60 time=64.097 ms
Implicit answered 22/8, 2017 at 10:10 Comment(1)
This doesn't handle timeouts.Amblyoscope
S
158

I could not redirect the Perl based solution to a file for some reason so I kept searching and found a bash only way to do this:

ping www.google.fr | while read pong; do echo "$(date): $pong"; done

Wed Jun 26 13:09:23 CEST 2013: PING www.google.fr (173.194.40.56) 56(84) bytes of data.
Wed Jun 26 13:09:23 CEST 2013: 64 bytes from zrh04s05-in-f24.1e100.net (173.194.40.56): icmp_req=1 ttl=57 time=7.26 ms
Wed Jun 26 13:09:24 CEST 2013: 64 bytes from zrh04s05-in-f24.1e100.net (173.194.40.56): icmp_req=2 ttl=57 time=8.14 ms

The credit goes to https://askubuntu.com/a/137246

Suppletory answered 26/6, 2013 at 11:13 Comment(8)
This doesn't appear to work on debian wheezy. Just stays there without output until ctrl+cBecame
@Became Not sure what the problem was in your case. I've just tried it on debian wheezy and it worked fine. Are you using bash as your shell?Suppletory
I actually like this approach much better as it does not use perl or awk.Daff
To also see the timeouts, all that is needed is to redirect stderr to stdout before the pipe (|), like so: ping $host 2>&1 | while read pong; do echo "$(date): $pong"; done. If you wish to write (or append) that to a file, you can redirect the whole command (after the done). Also, if you wish not to spawn a subshell, the date command supports echoing arbitrary input, like so: ping $host 2>&1 | while read pong; do date "+%c: $pong"; done. Please note that the format argument of date (that starts with +) can be customized at will. See man date for further information.Kobylak
FWIW, my default shell is ZSH and it wasn't working. When I ran it in Bash it worked fine. OP does mention that in the first paragraph of his comment... :)Soane
@Suppletory there is nothing really bash specific about this, it should work in posix shells. works in the public domain korn shell.Register
Here is the fish version: ping google.fr | while read pong; echo (date)": $pong"; endBrout
this is so helpful. i am also teeing the output like so: ping -i 5 google.com | while read pong; do echo "$(date): $pong" | tee -a uptime.log; donePantelegraph
B
81

If your AWK doesn't have strftime():

ping host | perl -nle 'print scalar(localtime), " ", $_'

To redirect it to a file, use standard shell redirection and turn off output buffering:

ping host | perl -nle 'BEGIN {$|++} print scalar(localtime), " ", $_' > outputfile

If you want ISO8601 format for the timestamp:

ping host | perl -nle 'use Time::Piece; BEGIN {$|++} print localtime->datetime, " ", $_' > outputfile
Braggadocio answered 21/5, 2012 at 5:59 Comment(6)
although i removed the 'bytes from' filter since I want the timestamps on every line... especially the timeouts.Negron
Works well, but it suppresses STDERR for the summary results at the end when you press Control+C. Same issue exists for the BASH answer.Shaitan
@NicholasBlasgen: That's because the Ctrl-C goes to the last process in the pipe and the ping only receives a SIGPIPE. You can use process substitution instead of a pipe: ping host > >(perl -nle 'print scalar(localtime), " ", $_') and the Ctrl-C will go to ping and do what you want. You can do the same thing with the while loop. By the way, on my system the summary goes to STDOUT rather than STDERR (so it gets timestamped, too).Braggadocio
This answer would be much better, IMHO, if the datetime format was in ISO8601.Orlena
@Phrogz: I agree that that's a more desirable format, but my answer comes close to matching what the OP asked for (depending on locale). To get ISO8601 format you can use Time::Piece; print localtime->datetime (and other appropriate settings) starting with 5.10 or use a CPAN module or strftime.Braggadocio
Great point about the OP's format! And thanks for including the iso8601 equivalent.Orlena
P
37

From man ping:

   -D     Print timestamp (unix time + microseconds as in gettimeofday) before each line.

It will produce something like this:

[1337577886.346622] 64 bytes from 4.2.2.2: icmp_req=1 ttl=243 time=47.1 ms

Then timestamp could be parsed out from the ping response and converted to the required format with date.

Picot answered 21/5, 2012 at 5:20 Comment(2)
sorry. adsl dropped out as I was adding tags... it's OSX Lion - doesn't have a "-D" option :-(Negron
someone good with perl and regex could pipe this to format to a human readable date time =]Airscrew
I
32

On OS X you can simply use the --apple-time option:

ping -i 2 --apple-time www.apple.com

Produces results like:

10:09:55.691216 64 bytes from 72.246.225.209: icmp_seq=0 ttl=60 time=34.388 ms
10:09:57.687282 64 bytes from 72.246.225.209: icmp_seq=1 ttl=60 time=25.319 ms
10:09:59.729998 64 bytes from 72.246.225.209: icmp_seq=2 ttl=60 time=64.097 ms
Implicit answered 22/8, 2017 at 10:10 Comment(1)
This doesn't handle timeouts.Amblyoscope
C
22
  1. terminal output:

    ping -i 5 google.com | xargs -L 1 -I '{}' date '+%Y-%m-%d %H:%M:%S: {}'

  2. file output:

    ping -i 5 google.com | xargs -L 1 -I '{}' date '+%Y-%m-%d %H:%M:%S: {}' > test.txt

  3. terminal + file output:

    ping -i 5 google.com | xargs -L 1 -I '{}' date '+%Y-%m-%d %H:%M:%S: {}' | tee test.txt

  4. file output background:

    nohup ping -i 5 google.com | xargs -L 1 -I '{}' date '+%Y-%m-%d %H:%M:%S: {}' > test.txt &

Carthusian answered 27/5, 2016 at 6:2 Comment(0)
S
14

My original submission was incorrect because it did not evaluate date for each line. Corrections have been made.

Try this

 ping google.com | xargs -L 1 -I '{}' date '+%+: {}'

produces the following output

Thu Aug 15 10:13:59 PDT 2013: PING google.com (74.125.239.103): 56 data bytes
Thu Aug 15 10:13:59 PDT 2013: 64 bytes from 74.125.239.103: icmp_seq=0 ttl=55 time=14.983 ms
Thu Aug 15 10:14:00 PDT 2013: 64 bytes from 74.125.239.103: icmp_seq=1 ttl=55 time=17.340 ms
Thu Aug 15 10:14:01 PDT 2013: 64 bytes from 74.125.239.103: icmp_seq=2 ttl=55 time=15.898 ms
Thu Aug 15 10:14:02 PDT 2013: 64 bytes from 74.125.239.103: icmp_seq=3 ttl=55 time=15.720 ms
Thu Aug 15 10:14:03 PDT 2013: 64 bytes from 74.125.239.103: icmp_seq=4 ttl=55 time=16.899 ms
Thu Aug 15 10:14:04 PDT 2013: 64 bytes from 74.125.239.103: icmp_seq=5 ttl=55 time=16.242 ms
Thu Aug 15 10:14:05 PDT 2013: 64 bytes from 74.125.239.103: icmp_seq=6 ttl=55 time=16.574 ms

The -L 1 option causes xargs to process one line at a time instead of words.

Shevlo answered 9/8, 2013 at 0:52 Comment(2)
Doesn't print during periods of 'Request timeout'; saves them all up and they get dumped with the same timestamp when request timeouts stop.Haney
@DavidEison try ping -D -n -O -i1 -W1 8.8.8.8Fluter
S
12

The simpler option is just using ts(1) from moreutils (fairly standard on most distros).

$ ping 1.1.1.1 | ts 

Feb 13 12:49:17 PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data. 
Feb 13 12:49:17 64 bytes from 1.1.1.1: icmp_seq=1 ttl=57 time=5.92 ms
Feb 13 12:49:18 64 bytes from 1.1.1.1: icmp_seq=2 ttl=57 time=5.30 ms
Feb 13 12:49:19 64 bytes from 1.1.1.1: icmp_seq=3 ttl=57 time=5.71 ms
Feb 13 12:49:20 64 bytes from 1.1.1.1: icmp_seq=4 ttl=57 time=5.86 ms

or

 ping 1.1.1.1 -I eth0 | ts "[%FT%X]"

Allows for the same strftime format strings as the shell/date workaround.

Shaggy answered 13/2, 2021 at 0:32 Comment(0)
K
11

On macos you can do

ping --apple-time 127.0.0.1

The output looks like

16:07:11.315419 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.064 ms
16:07:12.319933 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.157 ms
16:07:13.322766 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.066 ms
16:07:14.324649 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.148 ms
16:07:15.328743 64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.092 ms
Kingcraft answered 19/10, 2017 at 22:10 Comment(1)
This approach does seem to work okay for replies, but the timestamp is excluded for timeouts.Jampan
B
7

Try this:

ping www.google.com | while read endlooop; do echo "$(date): $endlooop"; done

It returns something like:

Wednesday 18 January  09:29:20 AEDT 2017: PING www.google.com (216.58.199.36) 56(84) bytes of data.
Wednesday 18 January  09:29:20 AEDT 2017: 64 bytes from syd09s12-in-f36.1e100.net (216.58.199.36): icmp_seq=1 ttl=57 time=2.86 ms
Wednesday 18 January  09:29:21 AEDT 2017: 64 bytes from syd09s12-in-f36.1e100.net (216.58.199.36): icmp_seq=2 ttl=57 time=2.64 ms
Wednesday 18 January  09:29:22 AEDT 2017: 64 bytes from syd09s12-in-f36.1e100.net (216.58.199.36): icmp_seq=3 ttl=57 time=2.76 ms
Wednesday 18 January  09:29:23 AEDT 2017: 64 bytes from syd09s12-in-f36.1e100.net (216.58.199.36): icmp_seq=4 ttl=57 time=1.87 ms
Wednesday 18 January  09:29:24 AEDT 2017: 64 bytes from syd09s12-in-f36.1e100.net (216.58.199.36): icmp_seq=5 ttl=57 time=2.45 ms
Blindage answered 17/1, 2017 at 16:40 Comment(0)
D
4

Pipe the result to awk:

 ping host | awk '{if($0 ~ /bytes from/){print strftime()"|"$0}else print}'
Diphthong answered 21/5, 2012 at 5:28 Comment(2)
has promise! doesn't like the strftime so i'm working on thatNegron
Check this code with a non existing host or when the net is down, I'm not happy with this result ;-)Fluter
O
3

You can create a function in your ~/.bashrc file, so you get a ping command ping-t on your console:

function ping-t { ping "$1" | while read pong; do echo "$(date): $pong"; done; }

Now you can call this on the console:

ping-t example.com

Sa 31. Mär 12:58:31 CEST 2018: PING example.com (93.184.216.34) 56(84) bytes of data.
Sa 31. Mär 12:58:31 CEST 2018: 64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=1 ttl=48 time=208 ms
Sa 31. Mär 12:58:32 CEST 2018: 64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=2 ttl=48 time=233 ms

Obtain answered 31/3, 2018 at 10:59 Comment(0)
T
1

You did not specify any time stamp or interval for how long you would require such output, so I considered it to be an infinite loop. You can change it accordingly as per your need.

while true
do
   echo -e "`date`|`ping -n -c 1 <IP_TO_PING>|grep 'bytes from'`"
   sleep 2
done
Tresatrescha answered 21/5, 2012 at 18:25 Comment(3)
You should change the grep part to ` egrep '(bytes from|errors)'Obtain
@Obtain Can you elaborate why to use 'egrep' instead of 'grep'Tresatrescha
egrep only to add a regular expression to get an output for errors tooObtain
F
1
ping -D -n -O -i1 -W1 8.8.8.8

or maybe

while true; do \
    ping -n -w1 -W1 -c1 8.8.8.8 \
    | grep -E "rtt|100%" \
    | sed -e "s/^/`date` /g"; \
    sleep 1; \
done
Fluter answered 31/10, 2014 at 2:16 Comment(0)
P
1

I also need this to monitor the network issue for my database mirroring time out issue. I use the command code as below:

ping -t Google.com|cmd /q /v /c "(pause&pause)>nul & for /l %a in () do (set /p "data=" && echo(!date! !time! !data!)&ping -n 2 Google.com>nul" >C:\pingtest.txt

You just need to modify Google.com to your server name. It works perfectly for me. and remember to stop this when you finished. The pingtest.txt file will increase by 1 KB per second (around).

Thank for raymond.cc. https://www.raymond.cc/blog/timestamp-ping-with-hrping/

Picket answered 15/9, 2017 at 13:35 Comment(1)
Update: The pingtest.txt file will increase by 4.5 KB per min (around).Picket
P
0

Try this line.

while sleep 1;do echo "$(date +%d-%m-%y-%T) $(ping -c 1 whatever.com | gawk 'FNR==2{print "Response from:",$4,$8}')" | tee -a /yourfolder/pingtest.log;done

You'll have to cancel it with ctrl-c tho.

Photoflood answered 22/11, 2016 at 1:50 Comment(1)
good idea with using tee, but the problem with -c 1 is losing the overall stats...Register
S
-1

just use sed and loop:

ping google.com|while read; do sed -r "s/(.*)/$(date) \1/g"<<<"$REPLY";done
Sponsor answered 13/2, 2021 at 3:0 Comment(2)
Does not work because it only ever gets the timestamp from the start of the command.Kashakashden
Updated my answer. Really need to rerun sed for each separate line, so I have added loop for that.Sponsor

© 2022 - 2024 — McMap. All rights reserved.