- no need to display ping for 100% loss - use ping=-100 to show service not known error - -1 to hard to differentiate from low pings if limit is > 200
138 lines
3.6 KiB
Bash
Executable File
138 lines
3.6 KiB
Bash
Executable File
#!/bin/bash
|
|
DATE_FORMAT=${DATE_FORMAT:-+%s} # +%s = epoch, -Iseconds = iso8601
|
|
CYCLE=${CYCLE:-60s}
|
|
OUTPUT_FILE=${OUTPUT_FILE:-ping.csv}
|
|
PING_COUNT=${PING_COUNT:-10}
|
|
# directories are set relative from the scripts path
|
|
script_path=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)
|
|
OUTPUT_PATH=${OUTPUT_PATH:-"$script_path/../data"}
|
|
SERVER_FILE=${SERVER_FILE:-"$script_path/../servers.env"}
|
|
|
|
# helper functions
|
|
function log()
|
|
{
|
|
local time=$(date +%F_%T)
|
|
local prefix="LOG"
|
|
case $1 in
|
|
ERR | ERROR)
|
|
prefix="ERR"
|
|
shift
|
|
;;
|
|
INF | INFO)
|
|
prefix="INF"
|
|
shift
|
|
;;
|
|
WAR | WARNING)
|
|
prefix="WAR"
|
|
shift
|
|
;;
|
|
esac
|
|
local func=$1; shift
|
|
# remove any \n
|
|
#local text=$(echo "$@"| tr '\n' '#' | sed 's|#|\\n |g')
|
|
case "$log_file" in
|
|
"")
|
|
echo "[$time]:[$prefix]:[$0][$func]: $@" 2>&1
|
|
;;
|
|
*)
|
|
echo "[$time]:[$prefix]:[$0][$func]: $@" >> $log_file
|
|
;;
|
|
esac
|
|
}
|
|
function sleep_wait()
|
|
{
|
|
# waiting on sleep to be able to handle SIGTERM
|
|
sleep $1 &
|
|
wait $!
|
|
}
|
|
|
|
function exit_handler()
|
|
{
|
|
echo "stopping pinger"
|
|
exit
|
|
}
|
|
|
|
trap "exit_handler" SIGINT
|
|
trap "exit_handler" SIGTERM
|
|
|
|
# main functions
|
|
|
|
# this function assumes the following ping output format:
|
|
## valid server
|
|
# --- 192.168.0.1 ping statistics ---
|
|
# 10 packets transmitted, 10 received, 0% packet loss, time 1806ms
|
|
# rtt min/avg/max/mdev = 0.278/0.361/1.010/0.216 ms
|
|
## valid server 100% package loss
|
|
# --- 10.0.0.2 ping statistics ---
|
|
# 10 packets transmitted, 0 received, 100% packet loss, time 1861ms
|
|
# [empty line]
|
|
## invalid server
|
|
# [no output]
|
|
function ping_server()
|
|
{
|
|
local server="$1"
|
|
local packet_loss=""
|
|
|
|
ifs_old=$IFS
|
|
IFS=$'\n'
|
|
ping_output=( $(ping $server -c$PING_COUNT -i0.2 -q 2>/dev/null| tail -n2) )
|
|
IFS=$ifs_old
|
|
|
|
packet_loss=$(echo "${ping_output[0]}" | grep -Eo "[.[:digit:]]{1,10}%")
|
|
satistic="$(echo "${ping_output[1]}" | cut -d' ' -f4 | sed -E 's/\//,/g')"
|
|
|
|
# Name or service not known
|
|
if [ "${#packet_loss}" -eq 0 ]; then
|
|
# make this Error visually apparent in the plot
|
|
packet_loss="100%"
|
|
satistic="-100,-100,-100,-100"
|
|
fi
|
|
|
|
# 100% package loss
|
|
if [ "${#satistic}" -eq 0 ]; then
|
|
# don't need to plot this data as package loss is displayed
|
|
satistic="NaN,NaN,NaN,NaN"
|
|
fi
|
|
|
|
echo "$(date $DATE_FORMAT),$server,$packet_loss,$satistic"
|
|
}
|
|
|
|
function load_server_file()
|
|
{
|
|
local result=""
|
|
if [ -f "$SERVER_FILE" ]; then
|
|
local server_file="$(cat $SERVER_FILE)"
|
|
for server in ${server_file[@]}; do
|
|
result="$result $(echo "$server" | cut -f1 -d":")"
|
|
done
|
|
fi
|
|
echo "$result"
|
|
}
|
|
|
|
main()
|
|
{
|
|
log INFO main DO NOT PING SERVERS YOU DO NOT HAVE PERMISSION TO DO SO!
|
|
# Environment SERVERS > arguments $@ > file $SERVER_FILE
|
|
local servers=( ${SERVERS:-${@:-$(load_server_file)}} )
|
|
local output_file="$OUTPUT_PATH/$OUTPUT_FILE"
|
|
log main "writing to $output_file"
|
|
while true; do
|
|
if [ ! -d $OUTPUT_PATH ]; then
|
|
mkdir -p $OUTPUT_PATH
|
|
fi
|
|
if [ ! -f $output_file ]; then
|
|
echo "Epoch,Server,PacketLoss,Min,Average,Max,Deviation" > $output_file
|
|
fi
|
|
log main "pinging ${servers[@]}"
|
|
for server in "${servers[@]}"; do
|
|
# run in subshell to catch SIGTERM
|
|
ping_server "$server" >> $output_file &
|
|
wait $!
|
|
done
|
|
log main "sleeping $CYCLE"
|
|
sleep_wait $CYCLE
|
|
done
|
|
}
|
|
|
|
main "$@"
|