#!/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 packet_loss="-1" fi # 100% package loss if [ "${#satistic}" -eq 0 ]; then satistic="-1,-1,-1,-1" 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 "$@"