#!/usr/bin/env bash # 生产机一屏体检。不改任何状态,随时可跑。 set -uo pipefail APP=/opt/chan STATE=/var/lib/chan-live/state CONF=/etc/chan-live/live.env hr() { printf '─── %s\n' "$1"; } hr "服务" for u in chan-live-ship chan-live-exec; do act="$(systemctl is-active "$u" 2>/dev/null)" since="$(systemctl show -p ActiveEnterTimestamp --value "$u" 2>/dev/null)" nrs="$(systemctl show -p NRestarts --value "$u" 2>/dev/null)" printf ' %-16s %-8s 自 %s · 重启 %s 次\n' \ "$u" "$act" "${since:-?}" "${nrs:-0}" done hr "时钟(staleness 闸依赖它)" if command -v chronyc >/dev/null; then chronyc tracking 2>/dev/null | grep -E "Reference ID|System time" | sed 's/^/ /' else echo " ⚠ 没装 chrony" fi hr "信号总线" bus="${SIGNAL_BUS:-$STATE/signals_live.jsonl}" [[ -f "$CONF" ]] && bus="$(grep -E '^SIGNAL_BUS=' "$CONF" | tail -1 | cut -d= -f2-)" bus="${bus:-$STATE/signals_live.jsonl}" if [[ -s "$bus" ]]; then n="$(wc -l < "$bus")" last_ts="$(tail -1 "$bus" | grep -o '"kline_ts":[0-9]*' | cut -d: -f2)" if [[ -n "$last_ts" ]]; then age=$(( $(date +%s) - last_ts / 1000 )) printf ' %s 条 · 最近一条 %d 分钟前\n' "$n" "$((age / 60))" else echo " $n 条(最后一行没有 kline_ts)" fi # 信号 6.8 个/天,所以「几小时没有」是正常的。真要看的是搬运连着没有 echo " 注:6.8 个/天,长时间没有新信号是正常的;要判健康看下面的搬运心跳" else echo " 空或不存在:$bus" fi hr "闸的状态" # 在场仓位**不落盘**:重启时由 reconcile 查交易所并平掉(见 live_exec.py # 的 reconcile 注释)。所以这里只报当日计数,仓位要看交易所或下面的成交流 if [[ -f "$STATE/live_state.json" ]]; then python3 - "$STATE/live_state.json" <<'PY' import json, sys, time d = json.load(open(sys.argv[1])) today = time.strftime("%Y-%m-%d") day = d.get("day", "?") stale = "" if day == today else f" ⚠ 是 {day} 的,跨日后首次开仓时才归零" print(f" 当日 {day}{stale}") pnl, n = d.get("pnl_day", 0.0), d.get("n_day", 0) # pnl 恒为 0 而又确实开过仓,说明 watch() 没在记账 → MAX_DAY_LOSS 是死的 warn = " ⚠ 开过仓但盈亏仍为 0,查 watch() 是否在跑" if n and pnl == 0 else "" print(f" 已开 {n} 笔 · 盈亏 {pnl:+.2f} USDT{warn}") print(f" 已处理信号键 {len(d.get('done', []))} 个(幂等去重用,留最近 5000)") PY else echo " 还没有状态文件(没开过仓)" fi hr "最近成交" if [[ -s "$STATE/live_trades.jsonl" ]]; then tail -5 "$STATE/live_trades.jsonl" | sed 's/^/ /' else echo " 还没有成交记录" fi hr "搬运心跳(最近 3 条)" journalctl -u chan-live-ship -n 200 --no-pager 2>/dev/null \ | grep -F "[心跳]" | tail -3 | sed 's/^/ /' \ || echo " 还没有心跳(每 5 分钟一条)" hr "最近报错" journalctl -u chan-live-exec -u chan-live-ship -n 400 --no-pager -p warning 2>/dev/null \ | tail -8 | sed 's/^/ /' || echo " 无"