138 lines
4.1 KiB
Bash
138 lines
4.1 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
# shellcheck disable=SC1091
|
|
source "${SCRIPT_DIR}/common.sh"
|
|
|
|
STEP="5g-link-logger"
|
|
|
|
resolve_target_ip() {
|
|
if [[ -n "${BLITZ_TIME_SERVER_IP:-}" ]]; then
|
|
printf '%s\n' "${BLITZ_TIME_SERVER_IP}"
|
|
return 0
|
|
fi
|
|
|
|
for candidate in ${BLITZ_5G_ROUTE_TARGETS//,/ }; do
|
|
if [[ -n "${candidate}" ]]; then
|
|
printf '%s\n' "${candidate}"
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
emit_sample_json() {
|
|
local interface_name="${1:-}"
|
|
local target_ip="${2:-}"
|
|
|
|
python3 - "${interface_name}" "${target_ip}" <<'PY'
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
|
|
interface_name = sys.argv[1]
|
|
target_ip = sys.argv[2]
|
|
|
|
payload = {
|
|
"ts_unix_ms": time.time_ns() // 1_000_000,
|
|
"interface": interface_name,
|
|
"target_ip": target_ip,
|
|
"link_present": False,
|
|
"route_output": "",
|
|
"route_ok": False,
|
|
"probe_ok": False,
|
|
"ping_rtt_ms": None,
|
|
"rx_bytes": 0,
|
|
"tx_bytes": 0,
|
|
"rx_packets": 0,
|
|
"tx_packets": 0,
|
|
"rx_errors": 0,
|
|
"tx_errors": 0,
|
|
"rx_drops": 0,
|
|
"tx_drops": 0,
|
|
}
|
|
|
|
if interface_name:
|
|
try:
|
|
output = subprocess.check_output(
|
|
["ip", "-j", "-s", "link", "show", "dev", interface_name],
|
|
text=True,
|
|
stderr=subprocess.DEVNULL,
|
|
)
|
|
stats = json.loads(output)
|
|
if stats:
|
|
item = stats[0]
|
|
payload["link_present"] = True
|
|
rx = item.get("stats64", {}).get("rx", {})
|
|
tx = item.get("stats64", {}).get("tx", {})
|
|
if not rx and not tx:
|
|
rx = item.get("stats", {}).get("rx", {})
|
|
tx = item.get("stats", {}).get("tx", {})
|
|
payload["rx_bytes"] = int(rx.get("bytes") or 0)
|
|
payload["tx_bytes"] = int(tx.get("bytes") or 0)
|
|
payload["rx_packets"] = int(rx.get("packets") or 0)
|
|
payload["tx_packets"] = int(tx.get("packets") or 0)
|
|
payload["rx_errors"] = int(rx.get("errors") or 0)
|
|
payload["tx_errors"] = int(tx.get("errors") or 0)
|
|
payload["rx_drops"] = int(rx.get("dropped") or 0)
|
|
payload["tx_drops"] = int(tx.get("dropped") or 0)
|
|
except Exception:
|
|
pass
|
|
|
|
if target_ip:
|
|
try:
|
|
route = subprocess.check_output(
|
|
["ip", "route", "get", target_ip],
|
|
text=True,
|
|
stderr=subprocess.STDOUT,
|
|
).strip()
|
|
payload["route_output"] = route.splitlines()[0] if route else ""
|
|
payload["route_ok"] = bool(payload["route_output"]) and (
|
|
not interface_name or f" dev {interface_name}" in payload["route_output"]
|
|
)
|
|
except Exception as exc:
|
|
payload["route_output"] = str(exc)
|
|
|
|
ping_cmd = ["ping", "-c", "1", "-W", "2", target_ip]
|
|
if interface_name:
|
|
ping_cmd[1:1] = ["-I", interface_name]
|
|
ping = subprocess.run(ping_cmd, capture_output=True, text=True)
|
|
payload["probe_ok"] = ping.returncode == 0
|
|
output = (ping.stdout or "") + "\n" + (ping.stderr or "")
|
|
for token in output.replace("\n", " ").split():
|
|
if token.startswith("time="):
|
|
value = token.split("=", 1)[1].rstrip("ms")
|
|
try:
|
|
payload["ping_rtt_ms"] = float(value)
|
|
except ValueError:
|
|
pass
|
|
break
|
|
|
|
print(json.dumps(payload, separators=(",", ":"), ensure_ascii=False))
|
|
PY
|
|
}
|
|
|
|
if [[ "${OMNI_BOOT_MODE:-0}" == "1" ]]; then
|
|
blitz_load_boot_env
|
|
blitz_require_run_context
|
|
fi
|
|
|
|
if [[ -z "${BLITZ_RUN_DIR:-}" && -f "${BLITZ_RUN_CONTEXT_FILE:-}" ]]; then
|
|
blitz_load_run_context_env || true
|
|
fi
|
|
blitz_ensure_instance_id
|
|
|
|
export BLITZ_5G_LINK_LOG_PATH="${BLITZ_5G_LINK_LOG_PATH:-${BLITZ_RUN_DIR}/b-5g-link-quality.${BLITZ_INSTANCE_ID}.jsonl}"
|
|
target_ip="$(resolve_target_ip || true)"
|
|
|
|
blitz_log "${STEP}" "start" "start" "path=${BLITZ_5G_LINK_LOG_PATH} interval_sec=${BLITZ_5G_LINK_LOG_INTERVAL_SEC}" 0
|
|
|
|
while true; do
|
|
interface_name="$(blitz_resolve_5g_interface || true)"
|
|
line="$(emit_sample_json "${interface_name}" "${target_ip}")"
|
|
blitz_jsonl_append_line "${BLITZ_5G_LINK_LOG_PATH}" "${line}"
|
|
sleep "${BLITZ_5G_LINK_LOG_INTERVAL_SEC}"
|
|
done
|