[add] initial commit

This commit is contained in:
2021-02-16 18:33:47 -05:00
commit 2ad6788a51
6 changed files with 519 additions and 0 deletions

94
plotter/pinger.gnuplot Normal file
View File

@@ -0,0 +1,94 @@
# config
csv_file="../data/ping.csv"
# space seperates list of SERVER:LABEL where SERVER is the filter for col_server
server_list=" \
127.0.0.1:my_pc \
0.0.0.0.:still_my_pc \
localhost:my_other_local \
example.com:example \
"
# timezone offset in seconds
tz=0
# table setup
col_time=1
col_server=2
col_packet_loss=3
col_min=4
col_average=5
col_max=6
col_deviation=7
if(exists("TZ")) tz=TZ*3600
# gnuplot does not like spaces in -e so we recreate them here via system call to sed
if(exists("SERVERS")) server_list=system("echo '".SERVERS."' | sed 's|;| |g'")
if(exists("CSV_FILE")) csv_file=CSV_FILE
# helper function
server(n) = word(server_list ,n)
# csv settings
set datafile separator ','
# output settings
#set terminal pngcairo size 800,600 enhanced font 'Segoe UI,10' # pngcairo cleaner than png
set output 'ping.png'
set encoding utf8
# data settings
set xdata time # tells gnuplot the x axis is time data
set timefmt "%s" # for iso 8601 use: "%Y-%m-%dT%H:%M:%S%:z"
set format x "%d.%m.%y - %H:%M"
set key autotitle columnhead
# styling
## legend
set key box lt rgb "#000000"
set key width 1.5
set key height 0.5
set key samplen 0.1
set key center top
## axis
set y2tics # enable second axis
set ytics nomirror # dont show the tics on that side
set y2range [5:100]
if (exists("Y_MAX")) set yrange [*:Y_MAX]
if (exists("X_MAX")) set xrange [*:X_MAX+tz]
if (exists("X_MIN")) set xrange [X_MIN+tz:*]
if (exists("X_MIN") && exists("X_MAX")) set xrange [X_MIN+tz:X_MAX+tz]
#set format y2 "%s perc"
## labels
set xlabel sprintf("Time (UTC: %+03d:00)", tz/3600)
set ylabel "Latency (ms)"
set y2label "Package Loss (%)" # label for second axis
set xtics rotate # rotate labels on the x axis
## grid
set style line 100 lt 1 lc rgb "grey" lw 0.5 # linestyle for the grid
set grid ls 100 # enable grid with specific linestyle
## lines and points
set style line 1 lt rgb "#1e88e5"
set style line 2 lt rgb "#43a047"
set style line 3 lt rgb "#d81b60"
set style line 4 lt rgb "#f57c00"
#plot for [server in server_list] csv_file using 1:(stringcolumn(3) eq server[1:strstrt(server, ":")-1] ? column(7) : NaN) ti server
# [ping] + [packet loss] + [packet loss border] + [packet loss legend]
plot for [i=1:words(server_list)] \
csv_file using (column(col_time) + tz):(stringcolumn(col_server) eq server(i)[1:strstrt(server(i), ":")-1] ? column(col_average) : NaN) \
ti server(i)[strstrt(server(i), ":")+1:*] \
ls i \
pointtype 7 ps 0.5, \
for [i=1:words(server_list)] \
csv_file using (column(col_time) + tz):(stringcolumn(col_server) eq server(i)[1:strstrt(server(i), ":")-1] ? column(col_packet_loss) : NaN) \
notitle \
axis x1y2 \
ls i lt rgb "#000000" \
pointtype 13 lw 0.5, \
for [i=1:words(server_list)] \
csv_file using (column(col_time) + tz):(stringcolumn(col_server) eq server(i)[1:strstrt(server(i), ":")-1] ? column(col_packet_loss) : NaN) \
notitle \
axis x1y2 \
ls i \
pointtype 13 ps 0.65, \
NaN with points pt 12 lc rgb "black" title "Packet Loss"

241
plotter/plot.sh Executable file
View File

@@ -0,0 +1,241 @@
#!/bin/bash
function help() { cat; }<<EOF
Backup Script Version $script_version
usage: SERVER:LABEL [...]
[--file|-f CSV_FILE] [--limit-y|-l Y_MAX] [--time-zone|-t UTC_HOURS]
[--start-date|-S DATE] [--end-date|-E DATE] [--show-hours|-H HOURS]
args: SERVER:LABEL [...]
Space sperated list of servers to plot. Needs to be before any other args.
SERVER matches column 2 of the csv file and LABEL is the text displayed in the plot's legend.
NOTE: This can be ommited if a servers.env file is present in the parent[1] or scripts[2] directory.
The args always take precedence over the file.
--file|-f CSV_FILE
CSV_FILE gives the path to csv file to parse. If this option is ommitted the csv file defaults to:
$default_csv
--limit-y|-l Y_MAX
Y_MAX defaults to $default_ymax and limits the Y Axis.
--time-zone|-t UTC_HOURS
The current timezone ($(date +%-:::z)) is always passed to gnuplot.
Disable this by passing no argument.
--start-date|-S DATE
DATE defaults to 1 week ago and sets the X Axis starting point.
Will be overwritten by -H if declared later.
--end-date|-E DATE
DATE defaults to the current date and time and sets the X Axis end point.
Can be used in conjunction with -S but not -H.
--show-hours|-H HOURS
HOURSE defaults to $default_hours and sets the Y Axis starting point HOURS before the end point.
Will be overwritten by -s if declared later.
example: ${BASH_SOURCE[0]} example.com:example 0.0.0.0:localhost --limit-y 100 --show-hours 5 --end-date "$(date +"%Y-%m-%d %H:%M")" --time-zone $(date +%-:::z)
${BASH_SOURCE[0]} example.com:example 0.0.0.0:localhost -S "$(date --date='yesterday' +"%Y-%m-%d")" -E "$(date +"%Y-%m-%d")" -f data.csv
Author: pascal@pdev.dev
EOF
##############################
# configuration
script_path=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)
plot_file="$script_path/pinger.gnuplot"
log_file="" # leave empty for stdout
# defaults
default_csv="$script_path/../data/ping.csv"
default_ymax=250
default_start_date=$(date --date="1 week ago" -Is)
default_end_date=$(date -Is)
default_hours=24
default_tz=$(date +%-:::z)
# end configuration
##############################
# variables
declare -A plot_env
#functions
function log()
{
local time=$(date +%F_%T)
local prefix="LOG"
case $1 in
ERR | ERROR)
prefix="ERR"
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 date_to_epoch()
{
echo $(date --date="$1" +"%s")
}
function load_server_env()
{
if [ -f "$script_path/../servers.env" ]; then
echo $(cat "$script_path/../servers.env" 2>/dev/null) | sed 's|\s|;|g'
elif [ -f "$script_path/servers.env" ]; then
echo $(cat "$script_path/servers.env" 2>/dev/null) | sed 's|\s|;|g'
else
echo ''
fi
}
# set X_MIN relative to X_MAX is set
function set_relative_X_MIN()
{
local hours=$1
if [[ -z "${plot_env[X_MAX]}" ]]; then
plot_env[X_MIN]=$(date_to_epoch $(date --date="$hours hours ago" -Is))
else
plot_env[X_MIN]=$(( ${plot_env[X_MAX]} - $hours * 3600 ))
fi
}
function create_env()
{
local env=""
for env_var in "${!plot_env[@]}"; do
env+=" -e $env_var=${plot_env[$env_var]}"
done
echo "$env"
}
main()
{
local unknown_args=()
local servers=$(load_server_env)
local csv_file="$default_csv" limit time_zone="$default_tz" start_date end_date hours
# if servers passed as args reset list and parse
[[ $# -gt 0 ]] && [[ $1 != -* ]] && servers=""
while [[ $# -gt 0 ]] && [[ $1 != -* ]]; do
servers="$servers;$1"
shift
done
# parse args
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
--file|-f)
if [[ $2 == -* ]] || [[ -z "$2" ]]; then
echo "log WAR main Invalid csv file, using default: $csv_file"
shift # past argument, no value
else
csv_file=$2
shift # past argument
shift # past value
fi
;;
--limit-y|-l)
if [[ $2 == -* ]] || [[ -z "$2" ]]; then
limit=$default_ymax
shift # past argument, no value
else
limit=$2
shift # past argument
shift # past value
fi
;;
--time-zone|-t)
if [[ $2 == -* ]] || [[ -z "$2" ]]; then
time_zone=''
shift # past argument, no value
else
time_zone=$2
shift # past argument
shift # past value
fi
;;
--start-date|-S)
if [[ $2 == -* ]] || [[ -z "$2" ]]; then
start_date=$(date_to_epoch $default_start_date)
shift # past argument, no value
else
start_date=$(date_to_epoch "$2")
shift # past argument
shift # past value
fi
;;
--end-date|-E)
if [[ $2 == -* ]] || [[ -z "$2" ]]; then
end_date=$(date_to_epoch $default_end_date)
shift # past argument, no value
else
end_date=$(date_to_epoch "$2")
shift # past argument
shift # past value
fi
;;
--show-hours|-H)
if [[ $2 == -* ]] || [[ -z "$2" ]]; then
hours=$default_hours
shift # past argument, no value
else
hours=$2
shift # past argument
shift # past value
fi
;;
--help|-h)
help
exit
;;
*) # unknown option
unknown_args+=("$1") # save it in an array for later
shift # past argument
;;
esac
done
# exit with error if no servers to plot
if [[ -z "$servers" ]]; then
log ERR main no servers to plot
exit 1
fi
# assign env in order to set relative X_MIN
[[ ! -z "$servers" ]] && plot_env[SERVERS]=\"$servers\"
[[ ! -z "$csv_file" ]] && plot_env[CSV_FILE]=\"$csv_file\"
[[ ! -z "$limit" ]] && plot_env[Y_MAX]=$limit
[[ ! -z "$time_zone" ]] && plot_env[TZ]=$time_zone
[[ ! -z "$start_date" ]] && plot_env[X_MIN]=$start_date
[[ ! -z "$end_date" ]] && plot_env[X_MAX]=$end_date
[[ ! -z "$hours" ]] && set_relative_X_MIN $hours
[[ ${#unknown_args[@]} -ne 0 ]] && log main WARNING "ignored unknown args: ${unknown_args[@]}"
log main "plot ARGS: $(create_env)"
gnuplot $(create_env) -p $plot_file
}
main "$@"