mirror of
git://f0xx.org/android_cast
synced 2026-07-29 04:38:53 +03:00
sync infra
This commit is contained in:
203
examples/network/wan-snapshot.sh
Executable file
203
examples/network/wan-snapshot.sh
Executable file
@@ -0,0 +1,203 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user