Created
November 29, 2012 01:45
-
-
Save mjf/36502b4fa3812f2d01d3 to your computer and use it in GitHub Desktop.
pingfmt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/awk -f | |
# PINGFMT - Format output of the ping(1) program | |
# Copyright (C) 2012 Matous J. Fialka, <http://mjf.cz/> | |
# Released under the terms of The MIT License | |
BEGIN { | |
# ----- HELP SCREEN ----- | |
help = help "Usage: pingfmt [-h|-help|-usage] [+[no][show]<opt>[=<val>]]\n" | |
help = help "\n" | |
help = help "Options:\n" | |
help = help "\n" | |
help = help " -h|-help|-usage Print this help screen\n" | |
help = help "\n" | |
help = help " +[no]highlight Highlight excessive values\n" | |
help = help "\n" | |
help = help " +label=<txt> Set hostname or IP\n" | |
help = help "\n" | |
help = help " +maxavgpktloss=<val> Set maximal average packetloss\n" | |
help = help " +maxavgrtt=<val> Set maximal average RTT\n" | |
help = help " +maxpktloss=<val> Set maximal packetloss\n" | |
help = help " +maxreq=<val> Set maximal request\n" | |
help = help " +maxrtt=<val> Set maximal RTT\n" | |
help = help " +maxtime=<sec> Set maximal time in seconds\n" | |
help = help "\n" | |
help = help " +[no]resolve Resolve hostname\n" | |
help = help "\n" | |
help = help " +[no]scroll Scroll output\n" | |
help = help " +scrollreq=<num> Scroll output every <num> requests\n" | |
help = help "\n" | |
help = help " +[no]utc Time in UTC\n" | |
help = help "\n" | |
help = help " +[no]showall [Don't] show all values\n" | |
help = help " +[no]showavg [Don't] show average values\n" | |
help = help " +[no]showavgpktloss [Don't] show average packetloss values\n" | |
help = help " +[no]showavgrtt [Don't] show average RTT values\n" | |
help = help " +[no]showcur [Don't] show current values\n" | |
help = help " +[no]showcurpktloss [Don't] show current packetloss values\n" | |
help = help " +[no]showcurrtt [Don't] show current RTT values\n" | |
help = help " +[no]showlabel [Don't] show label values\n" | |
help = help " +[no]showmax [Don't] show maximal values\n" | |
help = help " +[no]showmaxpktloss [Don't] show maximal packetloss values\n" | |
help = help " +[no]showmaxrtt [Don't] show maximal RTT values\n" | |
help = help " +[no]showmin [Don't] show minimal values\n" | |
help = help " +[no]showminpktloss [Don't] show minimal packetloss values\n" | |
help = help " +[no]showminrtt [Don't] show minimal RTT values\n" | |
help = help " +[no]showpktloss [Don't] show packetloss values\n" | |
help = help " +[no]showreq [Don't] show request values\n" | |
help = help " +[no]showrtt [Don't] show RTT\n" | |
help = help " +[no]showtime [Don't] show time (use "ping -D")\n" | |
help = help " +[no]showunits [Don't] show units\n" | |
help = help "\n" | |
help = help "Environment:\n" | |
help = help "\n" | |
help = help " PINGFMT_LABEL Use as host\n" | |
help = help "\n" | |
help = help " PINGFMT_MAXAVGPKTLOSS Use as maximal average packetloss\n" | |
help = help " PINGFMT_MAXAVGRTT Use as maximal average RTT\n" | |
help = help " PINGFMT_MAXCURPKTLOSS Use as maximal packetloss\n" | |
help = help " PINGFMT_MAXREQ Use as maximal request\n" | |
help = help " PINGFMT_MAXCURRTT Use as maximal RTT\n" | |
help = help "\n" | |
help = help "Exit codes:\n" | |
help = help "\n" | |
help = help " No errors occured 0\n" | |
help = help " Invalid option 1\n" | |
help = help " Maximal time reached 126 (see +maxtime)\n" | |
help = help " Maximal request reached 127 (see +maxreq)\n" | |
# ----- DEFAULTS ----- | |
ret = 0 | |
helped = 0 | |
opthighlight = 1 | |
optlabel = NULL | |
optmaxavgpktloss = 0.9 | |
optmaxavgrtt = 9.5 | |
optmaxcurpktloss = 3.0 | |
optmaxcurrtt = 20.0 | |
optmaxreq = 0 | |
optmaxtime = 0 | |
optresolve = 1 | |
optscroll = 1 | |
optscrollreq = 10 | |
optshowall = 0 | |
optshowavg = NULL | |
optshowavgpktloss = 0 | |
optshowavgrtt = 1 | |
optshowcur = NULL | |
optshowcurpktloss = 0 | |
optshowcurrtt = 1 | |
optshowlabel = 0 | |
optshowmax = NULL | |
optshowmaxpktloss = 0 | |
optshowmaxrtt = 1 | |
optshowmin = NULL | |
optshowminpktloss = 0 | |
optshowminrtt = 1 | |
optshowpktloss = NULL | |
optshowreq = 1 | |
optshowrtt = NULL | |
optshowtime = 0 | |
optshowunits = 1 | |
optutc = 1 | |
# ----- ENVIRONMENT ----- | |
if(ENVIRON["PINGFMT_LABEL"]) | |
optlabel = ENVIRON["PINGFMT_LABEL"] | |
if(ENVIRON["PINGFMT_MAXAVGPKTLOSS"]) | |
optmaxavgpktloss = ENVIRON["PINGFMT_MAXAVGPKTLOSS"] | |
if(ENVIRON["PINGFMT_MAXAVGRTT"]) | |
optmaxavgrtt = ENVIRON["PINGFMT_MAXAVGRTT"] | |
if(ENVIRON["PINGFMT_MAXCURPKTLOSS"]) | |
optmaxcurpktloss = ENVIRON["PINGFMT_MAXCURPKTLOSS"] | |
if(ENVIRON["PINGFMT_MAXREQ"]) | |
optmaxreq = ENVIRON["PINGFMT_MAXREQ"] | |
if(ENVIRON["PINGFMT_MAXCURRTT"]) | |
optmaxcurrtt = ENVIRON["PINGFMT_MAXCURRTT"] | |
# ----- ARGUMENTS ----- | |
for(arg = 1; arg < ARGC; arg++) { | |
opt = ARGV[arg] | |
if(opt ~ /^-(h(elp)?|usage)$/) { | |
printf "%s", help | |
helped = 1 | |
exit ret = 0 | |
} | |
if(opt ~ /^\+(no)?highlight$/) { | |
opthighlight = opt !~ /^\+no/ | |
continue | |
} | |
if(opt ~ /^\+label?=./) { | |
optlabel = temp[split(opt, temp, /=/)] | |
delete temp | |
continue | |
} | |
if(opt ~ /^\+(no)?showall$/) { | |
optshowall = opt !~ /^\+no/ | |
optshowavgpktloss = optshowall | |
optshowavgrtt = optshowall | |
optshowcurpktloss = optshowall | |
optshowcurrtt = optshowall | |
optshowlabel = optshowall | |
optshowmaxpktloss = optshowall | |
optshowmaxrtt = optshowall | |
optshowminpktloss = optshowall | |
optshowminrtt = optshowall | |
optshowreq = optshowall | |
optshowtime = optshowall | |
optshowunits = optshowall | |
continue | |
} | |
if(opt ~ /^\+(no)?showavg$/) { | |
optshowavgpktloss = opt !~ /^\+no/ | |
optshowavgrtt = optshowavgpktloss | |
continue | |
} | |
if(opt ~ /^\+(no)?showavgpktloss$/) { | |
optshowavgpktloss = opt !~ /^\+no/ | |
continue | |
} | |
if(opt ~ /^\+(no)?showavgrtt$/) { | |
optshowavgrtt = opt !~ /^\+no/ | |
continue | |
} | |
if(opt ~ /^\+(no)?showcur$/) { | |
optshowcurpktloss = opt !~ /^\+no/ | |
optshowcurrtt = optshowcurpktloss | |
continue | |
} | |
if(opt ~ /^\+(no)?showcurpktloss$/) { | |
optshowcurpktloss = opt !~ /^\+no/ | |
continue | |
} | |
if(opt ~ /^\+(no)?showcurrtt$/) { | |
optshowcurrtt = opt !~ /^\+no/ | |
continue | |
} | |
if(opt ~ /^\+(no)?showlabel$/) { | |
optshowlabel = opt !~ /^\+no/ | |
continue | |
} | |
if(opt ~ /^\+(no)?showmax$/) { | |
optshowmaxpktloss = opt !~ /^no/ | |
optshowmaxrtt = optshowmaxpktloss | |
continue | |
} | |
if(opt ~ /^\+(no)?showmaxpktloss$/) { | |
optshowmaxpktloss = opt !~ /^no/ | |
continue | |
} | |
if(opt ~ /^\+(no)?showmaxrtt$/) { | |
optshowmaxrtt = opt !~ /^no/ | |
continue | |
} | |
if(opt ~ /^\+maxreq=[0-9]+$/) { | |
optmaxreq = temp[split(opt, temp, /=/)] | |
delete temp | |
continue | |
} | |
if(opt ~ /^\+maxrtt=[0-9]+(\.[0-9]+)?$/) { | |
optmaxcurrtt = temp[split(opt, temp, /=/)] | |
delete temp | |
continue | |
} | |
if(opt ~ /^\+maxavgrtt=[0-9]+(\.[0-9]+)?$/) { | |
optmaxavgrtt = temp[split(opt, temp, /=/)] | |
delete temp | |
continue | |
} | |
if(opt ~ /^\+maxpktloss=([1-9][0-9]?|100)(\.[0-9]+)?$/) { | |
optmaxavgrtt = temp[split(opt, temp, /=/)] | |
delete temp | |
continue | |
} | |
if(opt ~ /^\+maxavgpktloss=([1-9][0-9]?|100)(\.[0-9]+)?$/) { | |
optmaxavgpktloss = temp[split(opt, temp, /=/)] | |
delete temp | |
continue | |
} | |
if(opt ~ /^\+maxtime=[0-9]+(\.[0-9]+)?$/) { | |
optmaxtime = temp[split(opt, temp, /=/)] | |
delete temp | |
continue | |
} | |
if(opt ~ /^\+(no)?showmin$/) { | |
optshowminpktloss = opt !~ /^\+no/ | |
optshowminrtt = optshowminpktloss | |
min = NULL | |
continue | |
} | |
if(opt ~ /^\+(no)?showminpktloss$/) { | |
optshowminpktloss = opt !~ /^\+no/ | |
continue | |
} | |
if(opt ~ /^\+(no)?showminrtt$/) { | |
optshowminrtt = opt !~ /^\+no/ | |
continue | |
} | |
if(opt ~ /^\+(no)?showpktloss$/) { | |
optshowcurpktloss = opt !~ /^\+no/ | |
optshowminpktloss = optshowcurpktloss | |
optshowavgpktloss = optshowcurpktloss | |
optshowmaxpktloss = optshowcurpktloss | |
continue | |
} | |
if(opt ~ /^\+(no)?showreq$/) { | |
optshowreq = opt !~ /^\+no/ | |
continue | |
} | |
if(opt ~ /^\+(no)?showrtt$/) { | |
optshowcurrtt = opt !~ /^\+no/ | |
optshowminrtt = optshowcurrtt | |
optshowavgrtt = optshowcurrtt | |
optshowmaxrtt = optshowcurrtt | |
continue | |
} | |
if(opt ~ /^\+(no)?resolve$/) { | |
optresolve = opt !~ /^\+no/ | |
continue | |
} | |
if(opt ~ /^\+(no)?scroll$/) { | |
optscroll = opt !~ /^\+no/ | |
continue | |
} | |
if(opt ~ /^\+scrollreq=[1-9][0-9]*$/) { | |
optscrollreq = temp[split(opt, temp, /=/)] | |
delete temp | |
continue | |
} | |
if(opt ~ /^\+(no)?showunits$/) { | |
optshowunits = opt !~ /^\+no/ | |
continue | |
} | |
if(opt ~ /^\+(no)?utc$/) { | |
optutc = opt !~ /^\+no/ | |
continue | |
} | |
if(opt ~ /^\+(no)?showtime$/) { | |
optshowtime = opt !~ /^\+no/ | |
continue | |
} | |
printf("Unknown option %s\n", opt) > "/dev/stderr" | |
exit ret = 1 | |
} | |
for(arg in ARGV) | |
delete ARGV[arg] | |
delete ARGV | |
# ----- OPTIONS ----- | |
optshowpktloss = \ | |
optshowcurpktloss || | |
optshowminpktloss || | |
optshowavgpktloss || | |
optshowmaxpktloss | |
optshowrtt = \ | |
optshowcurrtt || | |
optshowminrtt || | |
optshowavgrtt || | |
optshowmaxrtt | |
optshowcur = optshowcurpktloss && optshowcurrtt | |
optshowmin = optshowminpktloss && optshowminrtt | |
optshowavg = optshowavgpktloss && optshowavgrtt | |
optshowmax = optshowmaxpktloss && optshowmaxrtt | |
# ----- VARIABLES ----- | |
hostname = NULL | |
ip = NULL | |
pktlosscur = 0.0 | |
pktlossavg = 0.0 | |
pktlosssum = 0.0 | |
pktlossreq = 0.0 | |
pktlossmin = 0.0 | |
pktlossmax = 0.0 | |
reqcur = 0.0 | |
rttcur = 0.0 | |
rttavg = 0.0 | |
rttsum = 0.0 | |
rttreq = 0.0 | |
rttmax = 0.0 | |
rttmin = 0.0 | |
stm = systime() | |
dtm = 0.0 | |
scrreq = optscrollreq | |
scrjst = 0 | |
} | |
# ----- HOSTNAME AND IP ----- | |
/^P/ { | |
hostname = $2 | |
sub(/^\(/, NULL, hostname) | |
sub(/\)$/, NULL, hostname) | |
if(hostname ~ /[A-Z]/) | |
hostname = tolower(hostname) | |
ip = $3 | |
sub(/^\(/, NULL, ip) | |
sub(/\)$/, NULL, ip) | |
if(ip ~ /[A-F]/) | |
ip = tolower(ip) | |
next | |
} | |
# ----- PACKETLOSS ----- | |
/^[0-9]+(\/[0-9]+)? p/ { | |
if($3 ~ /[0-9]+%$/) | |
pktlosscur = $3 | |
else | |
pktlosscur = $6 | |
sub(/%$/, NULL, pktlosscur) | |
if(pktlosscur > pktlossmax) { | |
pktlossmax = pktlosscur | |
if(pktlossmin == 0) | |
pktlossmin = pktlossmax | |
} else | |
if(pktlosscur < pktlossmin) | |
pktlossmin = pktlosscur | |
pktlossavg = (pktlosssum += pktlosscur) / ++pktlossreq | |
} | |
# ----- RTT, OUTPUT AND REQUESTS ----- | |
/^(\[[0-9]+(\.[0-9]+)?\] )?[0-9]+ b/ { | |
if($1 ~ /^\[/) { | |
if(optshowtime || optmaxtime) { | |
sub(/^\[/, NULL, $1) | |
sub(/^\]/, NULL, $1) | |
dtm = $1 - stm | |
} | |
$1 = NULL | |
sub(/ /, NULL, $0) | |
} else | |
if(optshowtime || optmaxtime) | |
dtm = systime() - stm | |
if($9) | |
rttcur = $8 | |
else | |
rttcur = $7 | |
sub(/^.*=/, NULL, rttcur) | |
if(rttcur > rttmax) { | |
rttmax = rttcur | |
if(rttmin == 0) | |
rttmin = rttmax | |
} else | |
if(rttcur < rttmin) | |
rttmin = rttcur | |
rttavg = (rttsum += rttcur) / ++rttreq | |
# ----- OUTPUT ----- | |
++reqcur | |
if(optshowreq) | |
printf "% 7d", reqcur | |
if(optshowtime) { | |
if(optshowreq) | |
printf " | " | |
printf "%s", strftime("%02H:%02M:%02S", dtm, optutc) | |
} | |
if(optshowrtt) { | |
if(optshowreq || optshowtime) | |
printf " | " | |
if(optshowcurrtt) { | |
if(opthighlight) | |
if(rttcur >= optmaxcurrtt) | |
printf "\033[7m" | |
printf "% 7.2F", rttcur | |
if(opthighlight) | |
if(rttcur >= optmaxcurrtt) | |
printf "\033[0m" | |
} | |
if(optshowminrtt) { | |
if(optshowcurrtt) | |
printf "/" | |
printf "%7.2F", rttmin | |
} | |
if(optshowavgrtt) { | |
if(optshowcurrtt || optshowminrtt) | |
printf "/" | |
if(opthighlight) | |
if(rttavg >= optmaxavgrtt) | |
printf "\033[7m" | |
printf "%7.2F", rttavg | |
if(opthighlight) | |
if(rttavg >= optmaxavgrtt) | |
printf "\033[0m" | |
} | |
if(optshowmaxrtt) { | |
if(optshowcurrtt || optshowminrtt || optshowavgrtt) | |
printf "/" | |
if(opthighlight) | |
if(rttmax >= optmaxcurrtt) | |
printf "\033[7m" | |
printf "%7.2F", rttmax | |
if(opthighlight) | |
if(rttmax >= optmaxcurrtt) | |
printf "\033[0m" | |
} | |
if(optshowunits) | |
printf " ms" | |
} | |
if(optshowpktloss) { | |
if(optshowreq || optshowtime || optshowrtt) | |
printf " | " | |
if(optshowcurpktloss) { | |
if(opthighlight) | |
if(pktlosscur >= optmaxcurpktloss) | |
printf "\033[7m" | |
printf "%6.2F", pktlosscur | |
if(opthighlight) | |
if(pktlosscur >= optmaxcurpktloss) | |
printf "\033[0m" | |
} | |
if(optshowminpktloss) { | |
if(optshowcurpktloss) | |
printf "/" | |
printf "%6.2F", pktlossmin | |
} | |
if(optshowavgpktloss) { | |
if(optshowcurpktloss || optshowminpktloss) | |
printf "/" | |
if(opthighlight) | |
if(pktlossavg >= optmaxavgpktloss) | |
printf "\033[7m" | |
printf "%6.2F", pktlossavg | |
if(opthighlight) | |
if(pktlossavg >= optmaxavgpktloss) | |
printf "\033[0m" | |
} | |
if(optshowmaxpktloss) { | |
if(optshowcurpktloss || optshowminpktloss || optshowavgpktloss) | |
printf "/" | |
if(opthighlight) | |
if(pktlossmax >= optmaxcurpktloss) | |
printf "\033[7m" | |
printf "%6.2F", pktlossmax | |
if(opthighlight) | |
if(pktlossmax >= optmaxcurpktloss) | |
printf "\033[0m" | |
} | |
if(optshowunits) | |
printf " %%" | |
} | |
if(optshowlabel) { | |
if(optshowreq || optshowtime || optshowrtt || optshowpktloss) | |
printf " | " | |
if(optlabel == NULL) | |
printf "%s", optresolve ? hostname : ip | |
else | |
printf "%s", optlabel | |
} | |
# ----- SCROLL ----- | |
if(optscroll) { | |
if(scrreq) | |
--scrreq | |
else | |
scrreq = optscrollreq - 1 | |
if(scrreq > 0) { | |
scrjst = 0 | |
printf "\r" | |
} else { | |
scrjst = 1 | |
printf "\n" | |
} | |
} else | |
printf "\r" | |
# ----- BREAK ----- | |
if(optmaxtime) | |
if(dtm >= optmaxtime) | |
exit ret = 126 | |
if(optmaxreq) | |
if(reqcur >= optmaxreq) | |
exit ret = 127 | |
} | |
# ----- EXIT ----- | |
END { | |
if(ret == 1 || helped || scrjst) | |
exit ret | |
printf "\n" | |
exit ret | |
} | |
# ----- LICENSE ----- | |
# Permission is hereby granted, free of charge, to any | |
# person obtaining a copy of this software and associated | |
# documentation files (the "Software"), to deal in the Software | |
# without restriction, including without limitation the | |
# rights to use, copy, modify, merge, publish, distribute, | |
# sublicense, and/or sell copies of the Software, and to | |
# permit persons to whom the Software is furnished to do so, | |
# subject to the following conditions: | |
# | |
# The above copyright notice and this permission notice | |
# shall be included in all copies or substantial portions of | |
# the Software. | |
# | |
# The Software is provided "as is", without warranty of any | |
# kind, express or implied, including but not limited to the | |
# warranties of merchantability, fitness for a particular | |
# purpose and noninfringement. in no event shall the authors | |
# or copyright holders be liable for any claim, damages or | |
# other liability, whether in an action of contract, tort or | |
# otherwise, arising from, out of or in connection with the | |
# Software or the use or other dealings in the Software. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Typical use (ANSI control sequences not visible).