fix(monitor+xt_eod): 0929 晨复盘三修——ETF 漏采守卫+mirror 假黄根修+seats 带校准 [vps] [nas]
①xt_eod.py ETF 清单空 rc=1 抬码: 昨夜 21:00 桥板块接口死(universe 2266→0 + redis rpc timeout), bj_codes(本地 sqlite 恒 39)掩护合并空守卫→rc=0 静默漏采, 0928 全 ETF 停 0924(监控 dbbardata_daily RED 首战抓到); 修=ETF 清单空仍写北交所但 rc=1, schtask last_result=1 触发告警; 当晨已重跑 sanguo-xt-daily 补 0928 ETF 窗口(幂等 INSERT OR REPLACE) ②nas_monitor_check vps-mirror 连黄根修: push.log DONE 行只带 [HH:MM:SS] 不带日期, 旧按 want_day 过滤行永剩 start 行(0926~28 连黄实锤, 实际镜像日日 DONE fail=0); 改按 want_day 的 start 段内出现 DONE fail=0 判(+回归测试) ③dragon_tiger_seats 带 (0,400)→(200,2000): 实测 670~810, 旧上限真交易日必黄(0928 670 黄实案) runbook 监控注记同步(xt rc=1 分诊+mirror 修+带校准); tests 620 绿 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -87,7 +87,7 @@
|
||||
| sanguo-strategy-monitor-morn | 每日 08:05 | `strategy_monitor_wrapper.ps1 -Shift morn`(盘前引擎面:期望数/进程数/会话日零重启§11.0/报错风暴/日志新鲜度;08:05 relogin 后 85min) | 策略监控 |
|
||||
| sanguo-strategy-monitor-eve | 每日 21:30 | 同 wrapper -Shift eve(盘后产物+订单链:IS 日报出跑/恒等式 resid/订单残留/成交 vs 台账/周报出跑;错峰 20:45 日报+21:00 xt_eod 之后、23:50 data-eve 之前;infra 09-28 核批无碰撞) | 策略监控 |
|
||||
|
||||
> 监控注记(spec §20.15):监控 wrapper 恒 exit 0(红态由 alerts/health 承载,防污染调度层自检的 Last Result 判读);NAS 监控 v2 挂 `sanguo-vps-mirror` 16:00 班尾(`/volume1/stock/monitor_nas/run_monitor_nas.sh`→事件 JSON scp 至 VPS `data/monitor/inbox/`,VPS 两班摄取落库 host=nas;**runner 属宿主生效位,CI 不覆盖——改 repo 副本后须 `scp -O` 同步 `/volume1/stock/monitor_nas/`**,09-28 已同步);告警消费入口=前端「运维告警」页 `/ops-alerts`(四类 tab+ack,API `GET /api/v1/alerts`)。NAS 检查器语义(**09-28 三修校准**):dmsk=季频披露驱动域,改**季频锚**(最新 dt= 分区 ≥ 最近已过法定披露截止的季末:Q1→04-30/半年→09-30/三季→10-31/年报→次年 04-30;旧 mtime 80h 对季频必假黄,0927 Q2 水位 06-30 停滞实案);vps-mirror 完成度在 16:00 班前查昨日 DONE 行(早班查当日必空)。VPS 侧日历=确认集(dbbardata 000300)∪近 15 日工作日假定集——未确认日缺失降黄、确认日缺失才红(治 dbbardata 晚间源滞后塌期望的循环依赖,09-25 首跑实案);**row-band 豁免按文件日期(latest)判**(09-28 修:lag 型 margin/margin_sse 的 exp=ok[-1-lag]=确认日,旧按 exp 判对闸门空写非确认日 0 行文件永不豁免);**schtask weekday 限 72h**(09-28 修:weekday 任务周五晚→周一晚班次跨度 69h,26h 限周一早班必假黄;真死 >72h 仍黄+next_run=N/A red 兜底;bs-daily `last_result=1`=eod 腿 baostock 网络错等**真源故障照常黄,非口径问题**)。事件摄取=NAS events 文件带 `green_keys` 回传(VPS 据此 resolve NAS 告警);过程层日志窗=26h(防旧失败每日重炒)。
|
||||
> 监控注记(spec §20.15):监控 wrapper 恒 exit 0(红态由 alerts/health 承载,防污染调度层自检的 Last Result 判读;**例外=`sanguo-xt-daily` 09-29 起 ETF/基金清单空时 rc=1 抬码**——桥板块接口死(redis rpc timeout)时 bj_codes(本地 sqlite 恒 39)掩护旧合并守卫致 rc=0 静默漏采 ETF 一晚[0928 全 ETF 停 0924 实案,靠 dbbardata_daily RED 抓到],现 ETF 清单空→仍写北交所但 rc=1,分诊见 last_result=1+日志「FATAL ETF/基金 universe EMPTY」);NAS 监控 v2 挂 `sanguo-vps-mirror` 16:00 班尾(`/volume1/stock/monitor_nas/run_monitor_nas.sh`→事件 JSON scp 至 VPS `data/monitor/inbox/`,VPS 两班摄取落库 host=nas;**runner 属宿主生效位,CI 不覆盖——改 repo 副本后须 `scp -O` 同步 `/volume1/stock/monitor_nas/`**,09-28 已同步);告警消费入口=前端「运维告警」页 `/ops-alerts`(四类 tab+ack,API `GET /api/v1/alerts`)。NAS 检查器语义(**09-28 三修校准**):dmsk=季频披露驱动域,改**季频锚**(最新 dt= 分区 ≥ 最近已过法定披露截止的季末:Q1→04-30/半年→09-30/三季→10-31/年报→次年 04-30;旧 mtime 80h 对季频必假黄,0927 Q2 水位 06-30 停滞实案);vps-mirror 完成度在 16:00 班前查昨日 DONE 行(早班查当日必空;**09-29 修:push.log 的 DONE 行只带 [HH:MM:SS] 不带日期,旧按日期过滤行永剩 start→连黄[0926~28 实锤],改按 want_day 的 start 段内是否出现 DONE fail=0 判**)。VPS 侧日历=确认集(dbbardata 000300)∪近 15 日工作日假定集——未确认日缺失降黄、确认日缺失才红(治 dbbardata 晚间源滞后塌期望的循环依赖,09-25 首跑实案;09-29 首战立功:0928 ETF 缺写即被此规则抓红);**row-band 豁免按文件日期(latest)判**(09-28 修:lag 型 margin/margin_sse 的 exp=ok[-1-lag]=确认日,旧按 exp 判对闸门空写非确认日 0 行文件永不豁免);row-band 数值=经验带(dragon_tiger_seats 09-29 校准 (0,400)→(200,2000),实测 670~810);**schtask weekday 限 72h**(09-28 修:weekday 任务周五晚→周一晚班次跨度 69h,26h 限周一早班必假黄;真死 >72h 仍黄+next_run=N/A red 兜底;bs-daily `last_result=1`=eod 腿 baostock 网络错等**真源故障照常黄,非口径问题**)。事件摄取=NAS events 文件带 `green_keys` 回传(VPS 据此 resolve NAS 告警);过程层日志窗=26h(防旧失败每日重炒)。
|
||||
|
||||
> **策略面监控注记(2026-09-28 v1 上线,方案档=docs/superpowers/plans/2026-09-28-strategy-ops-monitor.md)**:`scripts/strategy_monitor/` 三件套照数据轨——schtask 本机跑(**不经 ssh,生产读权限闸门问题根治**)+只读体检不修数据+wrapper 恒 exit 0+`source="strategy"` 写同一 alerts.db(API 零改动;前端 /ops-alerts 类别=数据/策略)。十检两班:morn=引擎期望数/进程数(wmic needle 自匹配防)/会话日零重启(§11.0 自动化)/日志报错风暴/新鲜度;eve=IS 日报出跑/恒等式 resid≤1e-4/order_events 无残留/成交 vs 台账双对账(容差 0.01 元)/周报出跑;noon 班不注册按需手动。health 落 `data/monitor/health_strategy_{date}_{shift}.json`+`health_strategy_latest.json`(**health_latest.json 是数据域的,永不写**);绿班幂等 resolve_passed 消解(sw_industry 悬死案同纪律);交易日历=确认集∪工作日假定同款语义(`interval='d'`)。阈值初值跑两周后校准(数据轨同款纪律)。schtask 注册=`register_strategy_monitor_schtasks.ps1` 随 promote 上 VPS 后由 infra 执行一次(工法照 factor_monthly register 先例)。
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ _PER_DATE = [
|
||||
_pd("hot_rank", (99, 101), ready="18:30", producer="nas"),
|
||||
_pd("margin", (200, 4000), ready="21:00", lag=1),
|
||||
_pd("margin_sse", (200, 4000), ready="21:00", lag=1),
|
||||
_pd("dragon_tiger_seats", (0, 400)),
|
||||
_pd("dragon_tiger_seats", (200, 2000)), # 实测 670~810(0923~28); 旧(0,400)上限低致真交易日必黄(0928 670 实案)
|
||||
_pd("nb_daily", (30, 150)),
|
||||
]
|
||||
|
||||
|
||||
@@ -91,6 +91,11 @@ def main():
|
||||
if not u:
|
||||
log("FATAL empty universe (miniQMT 未连?)")
|
||||
return 2
|
||||
# 0929 修: 桥板块接口死(universe 2266→0, redis rpc timeout)时 bj_codes
|
||||
# (本地 sqlite 恒 39)掩护合并守卫 → rc=0 静默漏采 ETF 一整晚(0928 全
|
||||
# ETF 停 0924 实案, 靠监控 dbbardata_daily RED 才抓到). ETF 清单空仍写
|
||||
# bj, 但 rc=1 抬出码 → schtask last_result=1 触发监控告警.
|
||||
etf_empty = not etf_codes
|
||||
if args.limit:
|
||||
u = u[:args.limit]
|
||||
|
||||
@@ -168,6 +173,9 @@ def main():
|
||||
|
||||
log(f"DONE ok={ok} empty={empty} fail={fail} rows={rows}"
|
||||
f"{' [DRY-RUN]' if args.dry_run else ''}")
|
||||
if etf_empty:
|
||||
log("FATAL ETF/基金 universe EMPTY (桥板块接口死?) — 本班只写北交所, rc=1")
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
@@ -151,13 +151,25 @@ def build_checks(now):
|
||||
# (09-26 实证: 早班查当日必空=假黄)
|
||||
want_day = now.strftime("%Y-%m-%d") if now.hour >= 17 else \
|
||||
(now - dt.timedelta(days=1)).strftime("%Y-%m-%d")
|
||||
# 0929 修: push.log 里 DONE 行只带 [HH:MM:SS] 不带日期(只有 start 行
|
||||
# 带日期), 旧按 want_day 过滤行永远只剩 start → 连黄(0926~28 实锤).
|
||||
# 改按「want_day 的 start 段内出现过 DONE fail=0」判: 遍历记当前 start
|
||||
# 日期, DONE 归属其最近一次 start.
|
||||
mirror_ok = False
|
||||
try:
|
||||
with open(os.path.join(MIRROR_DIR, "push.log"), encoding="utf-8",
|
||||
errors="replace") as fh:
|
||||
lines = [l for l in fh.read().splitlines() if want_day in l]
|
||||
mirror_ok = any("vps-mirror DONE" in l and "fail=0" in l
|
||||
for l in lines[-20:])
|
||||
cur_day = None
|
||||
done_days = set()
|
||||
for line in fh:
|
||||
if "vps-mirror start" in line:
|
||||
for part in line.split():
|
||||
if len(part) == 10 and part[:2] == "20" and part[4] == "-":
|
||||
cur_day = part
|
||||
break
|
||||
elif "vps-mirror DONE" in line and cur_day and "fail=0" in line:
|
||||
done_days.add(cur_day)
|
||||
mirror_ok = want_day in done_days
|
||||
except OSError:
|
||||
pass
|
||||
add("nas-vps-mirror", "vps-mirror 当日完成", "green" if mirror_ok else "yellow",
|
||||
|
||||
@@ -80,3 +80,30 @@ def test_dmsk_quarterly_cadence(tmp_path, monkeypatch):
|
||||
dmsk = [c for c in checks if c["key"] == "nas-dmsk"][0]
|
||||
assert dmsk["status"] == "yellow"
|
||||
assert dmsk["evidence"]["min_expected"] == "2026-06-30"
|
||||
|
||||
|
||||
def test_mirror_done_line_has_no_date_beside_start_line(tmp_path, monkeypatch):
|
||||
"""push.log 实际格式: start 行带日期, DONE 行只带 [HH:MM:SS] 不带日期
|
||||
(0926~28 连黄实锤=旧按 want_day 过滤行, DONE 永被滤掉只剩 start).
|
||||
修后按「want_day 的 start 段内出现过 DONE fail=0」判绿; 只有 start
|
||||
无 DONE → 黄."""
|
||||
monkeypatch.setattr(nmc, "MIRROR_DIR", str(tmp_path))
|
||||
(tmp_path / "push.log").write_text(
|
||||
"=== 2026-09-27 17:32:31 vps-mirror start (dry=0) ===\n"
|
||||
"PLAN\tpush=4\tbytes=27831650\n"
|
||||
"[17:34:00] vps-mirror DONE pushed=4 fail=0\n"
|
||||
"=== 2026-09-28 17:32:49 vps-mirror start (dry=0) ===\n"
|
||||
"PLAN\tpush=4\tbytes=29334473\n"
|
||||
"[17:33:12] vps-mirror DONE pushed=4 fail=0\n",
|
||||
encoding="utf-8")
|
||||
checks, _ = nmc.build_checks(dt.datetime(2026, 9, 28, 17, 35))
|
||||
mirror = [c for c in checks if c["key"] == "nas-vps-mirror"][0]
|
||||
assert mirror["status"] == "green"
|
||||
# 当日只有 start 无 DONE(未完成/挂死) → 黄
|
||||
(tmp_path / "push.log").write_text(
|
||||
"=== 2026-09-28 17:32:49 vps-mirror start (dry=0) ===\n"
|
||||
"PLAN\tpush=4\tbytes=29334473\n",
|
||||
encoding="utf-8")
|
||||
checks, _ = nmc.build_checks(dt.datetime(2026, 9, 28, 17, 35))
|
||||
mirror = [c for c in checks if c["key"] == "nas-vps-mirror"][0]
|
||||
assert mirror["status"] == "yellow"
|
||||
|
||||
Reference in New Issue
Block a user