#!/usr/bin/env bash # 采集器健康速查。跨地部署时两台都跑一遍,对着看。 set -uo pipefail NAME="${NAME:-shadow}" REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" OUT="$REPO_ROOT/research/out" say() { printf '\n\033[1m==> %s\033[0m\n' "$*"; } say "容器" docker ps -a --filter "name=^${NAME}$" \ --format 'table {{.Names}}\t{{.Status}}\t{{.RunningFor}}' || true say "时钟" if command -v chronyc >/dev/null 2>&1; then chronyc tracking | grep -E 'System time|Last offset|Leap status' fi say "最近心跳" docker logs "$NAME" 2>&1 | grep '\[心跳\]' | tail -3 || echo "还没到第一次心跳(每 5 分钟一次)" say "告警与异常" docker logs "$NAME" 2>&1 \ | grep -E '⚠|错误|失效|损坏|停滞|Traceback|退化' | tail -10 \ || echo "无" say "输出规模" for f in shadow_latency.csv shadow_drift.csv shadow_signals.csv; do p="$OUT/$f" if [[ -s "$p" ]]; then printf ' %-22s %8d 行\n' "$f" "$(( $(wc -l <"$p") - 1 ))" elif [[ -f "$p" ]]; then # 已建但表头还没冲刷:signals 只在有信号时才 flush,门控后每天仅 4~6 个 printf ' %-22s %8s\n' "$f" "0(待首条)" else printf ' %-22s %8s\n' "$f" "无" fi done for f in shadow_books.jsonl.gz shadow_tape.jsonl.gz; do p="$OUT/$f" [[ -f "$p" ]] && printf ' %-22s %8s\n' "$f" "$(du -h "$p" | cut -f1)" \ || printf ' %-22s %8s\n' "$f" "无" done say "各站点行数(确认 site 列生效)" p="$OUT/shadow_latency.csv" if [[ -f "$p" ]]; then awk -F, 'NR>1{c[$1]++} END{for(s in c) printf " %-16s %8d 行\n", s, c[s]}' "$p" else echo " 尚无数据" fi say "到达延迟中位(本站,跨地对比的主指标)" # 按列名取下标,不写死数字:加了 site 列之后字段整体右移过一次, # 写死 $8 会静默变成读 lag_signal_ms if [[ -s "$p" ]]; then for sym in BTC ETH SOL; do med=$(awk -F, -v s="$sym" ' NR==1 { for (i=1;i<=NF;i++) { if ($i=="sym") si=i; if ($i=="lag_data_ms") li=i } ; next } $si==s && $li!="" { print $li }' "$p" | sort -n | awk ' { v[NR]=$1 } END { if (NR) printf "%.0f %d", v[int((NR+1)/2)], NR }') [[ -n "$med" ]] && printf ' %-5s 中位 %6sms (n=%s)\n' "$sym" ${med} \ || printf ' %-5s 尚无数据\n' "$sym" done echo " 参考:本机(新加坡)补丁后实测 350~650ms,理论下限约 500ms" fi