102

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
John Mee
  • 50,179
  • 34
  • 152
  • 186

16 Answers16

153

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

Community
  • 1
  • 1
richk
  • 1,719
  • 3
  • 12
  • 12
  • 1
    This doesn't appear to work on debian wheezy. Just stays there without output until ctrl+c – KBeezie Aug 06 '13 at 20:18
  • 1
    @KBeezie 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? – richk Oct 29 '13 at 12:29
  • 8
    I actually like this approach much better as it does not use perl or awk. – Alexey Kamenskiy Apr 14 '15 at 09:23
  • 5
    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 `echo`ing 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. – 7heo.tk Jul 19 '16 at 10:47
  • 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... :) – levifig May 29 '18 at 05:52
  • @richk there is nothing really bash specific about this, it should work in posix shells. works in the public domain korn shell. – minusf Aug 09 '18 at 07:38
  • Here is the fish version: `ping google.fr | while read pong; echo (date)": $pong"; end` – Byscripts Mar 24 '20 at 10:05
  • 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; done` – Purag Oct 14 '20 at 19:06
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
Phrogz
  • 296,393
  • 112
  • 651
  • 745
Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
  • although i removed the 'bytes from' filter since I want the timestamps on every line... especially the timeouts. – John Mee May 21 '12 at 06:22
  • 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. – Nicholas Blasgen Apr 24 '14 at 13:31
  • 1
    @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). – Dennis Williamson Apr 24 '14 at 14:12
  • This answer would be much better, IMHO, if the datetime format was in ISO8601. – Phrogz Oct 21 '15 at 03:52
  • @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`. – Dennis Williamson Oct 22 '15 at 17:16
  • Great point about the OP's format! And thanks for including the iso8601 equivalent. – Phrogz Oct 22 '15 at 17:18
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.

Jonathan Soifer
  • 2,715
  • 6
  • 27
  • 50
31

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
Nicolas Grison
  • 326
  • 3
  • 2
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 &

Community
  • 1
  • 1
xuanyuanaosheng
  • 1,684
  • 1
  • 11
  • 9
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.

Bromo
  • 286
  • 3
  • 5
10

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
Clintm
  • 4,505
  • 3
  • 41
  • 54
9

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.

John Mee
  • 50,179
  • 34
  • 152
  • 186
mario
  • 144,265
  • 20
  • 237
  • 291
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
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
nutria
  • 71
  • 1
  • 1
4

Pipe the result to awk:

 ping host | awk '{if($0 ~ /bytes from/){print strftime()"|"$0}else print}'
Prince John Wesley
  • 62,492
  • 12
  • 87
  • 94
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

rubo77
  • 19,527
  • 31
  • 134
  • 226
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
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
v3nM
  • 952
  • 1
  • 12
  • 19
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
Thomas Szteliga
  • 402
  • 4
  • 15
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/

DBALUKE HUANG
  • 247
  • 1
  • 10
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.

nDCasT
  • 71
  • 2
-1

just use sed and loop:

ping google.com|while read; do sed -r "s/(.*)/$(date) \1/g"<<<"$REPLY";done
Saboteur
  • 1,331
  • 5
  • 12