mirror of
git://f0xx.org/android_cast
synced 2026-07-29 07:58:10 +03:00
204 lines
5.8 KiB
Bash
Executable File
204 lines
5.8 KiB
Bash
Executable File
#!/bin/sh
|
|
#
|
|
# Log WAN vs LAN ping quality on the Debian edge router.
|
|
# Use to compare "rocketship" evenings vs slow periods (ISP/upstream vs local).
|
|
#
|
|
# Topology (see docs/INFRA.md):
|
|
# world -> 134.17.26.161 (router 10.7.6.228) -> 10.7.0.10 (FE) -> 10.7.0.0/8 (BE, …)
|
|
#
|
|
# Install on router:
|
|
# sudo cp wan-snapshot.sh /usr/local/bin/wan-snapshot.sh
|
|
# sudo chmod +x /usr/local/bin/wan-snapshot.sh
|
|
# sudo mkdir -p /var/log
|
|
#
|
|
# Cron (every 15 minutes):
|
|
# */15 * * * * root /usr/local/bin/wan-snapshot.sh
|
|
#
|
|
# Env overrides:
|
|
# WAN_SNAPSHOT_LOG=/var/log/wan-quality.log
|
|
# WAN_PING_TARGET=1.1.1.1
|
|
# FE_PING_TARGET=10.7.0.10
|
|
# BE_PING_TARGET=10.7.16.128 (set to "none" to skip)
|
|
# PING_COUNT=10
|
|
# PING_DEADLINE_S=15
|
|
#
|
|
set -eu
|
|
|
|
WAN_SNAPSHOT_LOG="${WAN_SNAPSHOT_LOG:-/var/log/wan-quality.log}"
|
|
WAN_PING_TARGET="${WAN_PING_TARGET:-1.1.1.1}"
|
|
FE_PING_TARGET="${FE_PING_TARGET:-10.7.0.10}"
|
|
BE_PING_TARGET="${BE_PING_TARGET-10.7.16.128}"
|
|
PING_COUNT="${PING_COUNT:-10}"
|
|
PING_DEADLINE_S="${PING_DEADLINE_S:-15}"
|
|
|
|
usage() {
|
|
sed -n '2,22p' "$0"
|
|
printf '\nCommands:\n'
|
|
printf ' (default) append one snapshot line to the log\n'
|
|
printf ' --report summarize today vs yesterday averages\n'
|
|
printf ' --tail [N] print last N log lines (default 24)\n'
|
|
printf ' --help this text\n'
|
|
}
|
|
|
|
need_ping() {
|
|
command -v ping >/dev/null 2>&1 || {
|
|
echo "wan-snapshot: missing ping" >&2
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# ping_summary HOST -> prints: loss_pct avg_ms (or loss_pct=-1 avg_ms=-1 on total failure)
|
|
ping_summary() {
|
|
_host="$1"
|
|
_out=""
|
|
_out="$(ping -c "$PING_COUNT" -w "$PING_DEADLINE_S" "$_host" 2>/dev/null)" || true
|
|
if [ -z "$_out" ]; then
|
|
printf '%s %s' "-1" "-1"
|
|
return 0
|
|
fi
|
|
_loss="$(printf '%s\n' "$_out" | awk '/packet loss/ {
|
|
for (i = 1; i <= NF; i++) if ($i ~ /%$/) { gsub(/%/, "", $i); print $i; exit }
|
|
}')"
|
|
_avg="$(printf '%s\n' "$_out" | awk -F'[=/ ]' '/min\/avg\/max/ { print $8; exit }')"
|
|
[ -n "$_loss" ] || _loss="-1"
|
|
[ -n "$_avg" ] || _avg="-1"
|
|
printf '%s %s' "$_loss" "$_avg"
|
|
}
|
|
|
|
snapshot_once() {
|
|
need_ping
|
|
_ts="$(date -Iseconds 2>/dev/null || date '+%Y-%m-%dT%H:%M:%S%z')"
|
|
_wan="$(ping_summary "$WAN_PING_TARGET")"
|
|
_wan_loss="${_wan%% *}"
|
|
_wan_avg="${_wan#* }"
|
|
_fe="$(ping_summary "$FE_PING_TARGET")"
|
|
_fe_loss="${_fe%% *}"
|
|
_fe_avg="${_fe#* }"
|
|
|
|
_line="ts=$_ts wan=$WAN_PING_TARGET wan_loss=${_wan_loss}% wan_avg_ms=${_wan_avg} fe=$FE_PING_TARGET fe_loss=${_fe_loss}% fe_avg_ms=${_fe_avg}"
|
|
|
|
if [ -n "$BE_PING_TARGET" ] && [ "$BE_PING_TARGET" != "none" ]; then
|
|
_be="$(ping_summary "$BE_PING_TARGET")"
|
|
_be_loss="${_be%% *}"
|
|
_be_avg="${_be#* }"
|
|
_line="$_line be=$BE_PING_TARGET be_loss=${_be_loss}% be_avg_ms=${_be_avg}"
|
|
fi
|
|
|
|
_dir="$(dirname "$WAN_SNAPSHOT_LOG")"
|
|
[ -d "$_dir" ] || mkdir -p "$_dir" 2>/dev/null || true
|
|
printf '%s\n' "$_line" >> "$WAN_SNAPSHOT_LOG"
|
|
printf '%s\n' "$_line"
|
|
}
|
|
|
|
# Average wan_avg_ms / fe_avg_ms for lines matching DATE prefix (YYYY-MM-DD).
|
|
day_avg() {
|
|
_log="$1"
|
|
_date="$2"
|
|
_field="$3"
|
|
[ -r "$_log" ] || return 0
|
|
awk -v d="$_date" -v f="$_field" '
|
|
$0 ~ "^ts=" d {
|
|
for (i = 1; i <= NF; i++) {
|
|
if ($i ~ "^" f "=") {
|
|
split($i, a, "=")
|
|
v = a[2]
|
|
gsub(/%/, "", v)
|
|
if (v + 0 == v && v >= 0) { n++; s += v }
|
|
}
|
|
}
|
|
}
|
|
END {
|
|
if (n > 0) printf "%.2f", s / n
|
|
else print "n/a"
|
|
}
|
|
' "$_log"
|
|
}
|
|
|
|
day_max_loss() {
|
|
_log="$1"
|
|
_date="$2"
|
|
_field="$3"
|
|
[ -r "$_log" ] || return 0
|
|
awk -v d="$_date" -v f="$_field" '
|
|
$0 ~ "^ts=" d {
|
|
for (i = 1; i <= NF; i++) {
|
|
if ($i ~ "^" f "=") {
|
|
split($i, a, "=")
|
|
v = a[2]
|
|
gsub(/%/, "", v)
|
|
if (v + 0 == v && v >= 0 && v > max) max = v
|
|
}
|
|
}
|
|
}
|
|
END {
|
|
if (max == "") print "n/a"
|
|
else printf "%.0f", max
|
|
}
|
|
' "$_log"
|
|
}
|
|
|
|
report() {
|
|
_log="$WAN_SNAPSHOT_LOG"
|
|
_today="$(date '+%Y-%m-%d')"
|
|
_yesterday="$(date -d 'yesterday' '+%Y-%m-%d' 2>/dev/null || date -v-1d '+%Y-%m-%d' 2>/dev/null || echo '')"
|
|
|
|
if [ ! -r "$_log" ]; then
|
|
echo "wan-snapshot: no log at $_log (run default command first)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
_samples_today="$(grep -c "^ts=$_today" "$_log" 2>/dev/null || echo 0)"
|
|
printf 'log=%s\n' "$_log"
|
|
printf 'today=%s samples=%s\n' "$_today" "$_samples_today"
|
|
printf ' wan_avg_ms=%s wan_max_loss%%=%s\n' \
|
|
"$(day_avg "$_log" "$_today" "wan_avg_ms")" \
|
|
"$(day_max_loss "$_log" "$_today" "wan_loss")"
|
|
printf ' fe_avg_ms=%s fe_max_loss%%=%s\n' \
|
|
"$(day_avg "$_log" "$_today" "fe_avg_ms")" \
|
|
"$(day_max_loss "$_log" "$_today" "fe_loss")"
|
|
|
|
if [ -n "$_yesterday" ] && grep -q "^ts=$_yesterday" "$_log" 2>/dev/null; then
|
|
_samples_y="$(grep -c "^ts=$_yesterday" "$_log" 2>/dev/null || echo 0)"
|
|
printf 'yesterday=%s samples=%s\n' "$_yesterday" "$_samples_y"
|
|
printf ' wan_avg_ms=%s wan_max_loss%%=%s\n' \
|
|
"$(day_avg "$_log" "$_yesterday" "wan_avg_ms")" \
|
|
"$(day_max_loss "$_log" "$_yesterday" "wan_loss")"
|
|
printf ' fe_avg_ms=%s fe_max_loss%%=%s\n' \
|
|
"$(day_avg "$_log" "$_yesterday" "fe_avg_ms")" \
|
|
"$(day_max_loss "$_log" "$_yesterday" "fe_loss")"
|
|
fi
|
|
|
|
printf '\nInterpretation:\n'
|
|
printf ' wan bad + fe good -> likely ISP/upstream (world -> 134.17.26.161)\n'
|
|
printf ' wan + fe bad -> router or LAN (10.7.6.228 -> 10.7.0.10)\n'
|
|
printf ' wan + fe good, apps slow -> DNAT/nginx above ping path\n'
|
|
}
|
|
|
|
tail_log() {
|
|
_n="${1:-24}"
|
|
[ -r "$WAN_SNAPSHOT_LOG" ] || {
|
|
echo "wan-snapshot: no log at $WAN_SNAPSHOT_LOG" >&2
|
|
exit 1
|
|
}
|
|
tail -n "$_n" "$WAN_SNAPSHOT_LOG"
|
|
}
|
|
|
|
case "${1:-}" in
|
|
-h|--help|help)
|
|
usage
|
|
;;
|
|
--report|report)
|
|
report
|
|
;;
|
|
--tail|tail)
|
|
tail_log "${2:-24}"
|
|
;;
|
|
"")
|
|
snapshot_once
|
|
;;
|
|
*)
|
|
echo "wan-snapshot: unknown command: $1 (try --help)" >&2
|
|
exit 1
|
|
;;
|
|
esac
|