style: 去掉全部 emoji, 状态用颜色文字表达(一致/不一致/正常/过热/需关注)
emoji 在企微客户端渲染成大色块很扎眼; 改为纯文字+<font color> 三色, 状态词直接着色, 数据保持素色, 版式标题+单行结论+引用详情不变
This commit is contained in:
@@ -102,11 +102,11 @@ def wecom_alert_failure(event: dict | str | None = None) -> dict:
|
||||
ended = detail.get("end_time") or detail.get("expected_start_time")
|
||||
occurred = occurred or ended
|
||||
|
||||
lines = [f"## 🔴 流程失败:{flow_name or resource_name or '未知'}"]
|
||||
lines = [f"## 流程失败:{flow_name or resource_name or '未知'}"]
|
||||
if run_name:
|
||||
lines.append(f"> Run「{run_name}」 · {event_name.split('.')[-1]} · {_fmt_ts(occurred)}")
|
||||
lines.append(f"> Run {run_name} · {event_name.split('.')[-1]} · {_fmt_ts(occurred)}")
|
||||
if state_msg:
|
||||
lines.append(f"> 错误:{state_msg[:150].replace(chr(10), ' ')}")
|
||||
lines.append(f'> 错误:<font color="warning">{state_msg[:150].replace(chr(10), " ")}</font>')
|
||||
if run_id:
|
||||
lines.append(f"> [查看详情]({UI_BASE}/runs/flow-run/{run_id})")
|
||||
else:
|
||||
|
||||
@@ -40,9 +40,12 @@ def _system_lines(name: str, report: dict, goods: dict, lines: list[str]) -> boo
|
||||
|
||||
g = goods or {}
|
||||
zero = g.get("zeroGoodsOrders", 0)
|
||||
goods_txt = f"{g.get('goods', 0):,} 行" + (f"(缺 {zero:,})" if zero else "")
|
||||
order_txt = f"订单 {remote_t:,} ✅" if ok else f"订单 远程 {remote_t:,} / 本地 {local_t:,} ⚠️"
|
||||
lines.append(f"**{name}** {order_txt} · 商品 {goods_txt} {'✅' if not zero else '⚠️'}")
|
||||
goods_txt = f"{g.get('goods', 0):,} 行" + (f'(<font color="warning">缺 {zero:,}</font>)' if zero else "")
|
||||
if ok:
|
||||
order_txt = f"订单 {remote_t:,} <font color=\"info\">一致</font>"
|
||||
else:
|
||||
order_txt = f"订单 远程 {remote_t:,} / 本地 {local_t:,} <font color=\"warning\">不一致</font>"
|
||||
lines.append(f"**{name}** {order_txt} · 商品 {goods_txt}")
|
||||
|
||||
diff_days = [d for d in days_r if not d.get("ok")]
|
||||
diff_units = sum(_affected_units(d.get("diff")) for d in diff_days)
|
||||
@@ -56,7 +59,7 @@ def build_daily_message(
|
||||
goods: dict, ocr_today: dict, ocr_pending: int, failures: list[dict],
|
||||
) -> tuple[str, bool]:
|
||||
"""拼装日报 markdown,返回 (消息, 是否需关注)。单行结论 + 引用详情的紧凑排版。"""
|
||||
lines = [f"## 📊 数据核验日报 {datetime.now():%m-%d %H:%M}(近 {days} 天 {window})"]
|
||||
lines = [f"## 数据核验日报 {datetime.now():%m-%d %H:%M}(近 {days} 天 {window})"]
|
||||
attention = False
|
||||
|
||||
for name, report in (("RIIN", riin), ("SDS", sds)):
|
||||
@@ -67,24 +70,25 @@ def build_daily_message(
|
||||
attention = True
|
||||
|
||||
processed, failed = (ocr_today or {}).get("processed", 0), (ocr_today or {}).get("failed", 0)
|
||||
ocr_txt = f"**OCR 今日** 处理 {processed:,} · 识别失败 {failed:,}" + (" ✅" if not failed else " ⚠️")
|
||||
ocr_txt = f"**OCR** 今日处理 {processed:,} · 识别失败 "
|
||||
ocr_txt += f'<font color="warning">{failed:,}</font>' if failed else "0"
|
||||
if ocr_pending:
|
||||
ocr_txt += f"(累计待处理 {ocr_pending:,})"
|
||||
ocr_txt += f" · 待处理 {ocr_pending:,}"
|
||||
lines.append(ocr_txt)
|
||||
|
||||
if failures:
|
||||
attention = True
|
||||
lines.append(f"**失败任务(24h)** {len(failures)} 次 🔴")
|
||||
lines.append(f'**任务** 失败 <font color="warning">{len(failures)} 次</font>(24h)')
|
||||
for f in failures[:6]:
|
||||
start = (f.get("start") or "")[5:] # MM-DD HH:MM
|
||||
lines.append(f"> {f.get('flow', '?')}「{f.get('name', '?')}」{f.get('state', '?')} · {start}")
|
||||
lines.append(f"> {f.get('flow', '?')}:{f.get('name', '?')} {f.get('state', '?')} {start}")
|
||||
if len(failures) > 6:
|
||||
lines.append(f"> …等共 {len(failures)} 次")
|
||||
else:
|
||||
lines.append("**失败任务(24h)** 0 ✅")
|
||||
lines.append("**任务** 失败 0 次(24h)")
|
||||
|
||||
lines.append('<font color="warning">⚠️ 存在需关注项,见上</font>' if attention
|
||||
else '<font color="info">✅ 数据全部一致,无异常</font>')
|
||||
lines.append('<font color="warning">存在需关注项,见上</font>' if attention
|
||||
else '<font color="info">数据全部一致,无异常</font>')
|
||||
return "\n".join(lines), attention
|
||||
|
||||
|
||||
|
||||
@@ -291,11 +291,11 @@ def _check_services() -> dict:
|
||||
|
||||
|
||||
def _mark(pct: float | None, threshold: int) -> str:
|
||||
"""百分比展示:超阈值用 warning 色加粗+🔴。"""
|
||||
"""百分比展示:超阈值用 warning 色加粗。"""
|
||||
if pct is None:
|
||||
return "—"
|
||||
if pct >= threshold:
|
||||
return f'<font color="warning">**{pct:.0f}%** 🔴</font>'
|
||||
return f'<font color="warning">**{pct:.0f}%**</font>'
|
||||
return f"{pct:.0f}%"
|
||||
|
||||
|
||||
@@ -343,7 +343,7 @@ def device_check(alarm_threshold: int = 80) -> dict:
|
||||
print(f"[device-check] 磁盘检查失败: {err}")
|
||||
|
||||
threshold = alarm_threshold
|
||||
header = f"## 🖥 设备日报 {datetime.now():%m-%d %H:%M}(24h 采样 {agg['count']} 次"
|
||||
header = f"## 设备日报 {datetime.now():%m-%d %H:%M}(24h 采样 {agg['count']} 次"
|
||||
if agg.get("firstTs"):
|
||||
first = datetime.fromisoformat(agg["firstTs"])
|
||||
if first > datetime.now() - timedelta(hours=23):
|
||||
@@ -397,8 +397,12 @@ def device_check(alarm_threshold: int = 80) -> dict:
|
||||
else:
|
||||
mem_txt = "显存 无数据"
|
||||
temp_peak = g.get("tempPeak")
|
||||
temp_txt = (f"温度峰 {temp_peak:.0f}°C" + (" 🔴过热" if temp_peak >= GPU_TEMP_WARN else " ✅")
|
||||
if temp_peak is not None else "温度 无数据")
|
||||
if temp_peak is None:
|
||||
temp_txt = "温度 无数据"
|
||||
elif temp_peak >= GPU_TEMP_WARN:
|
||||
temp_txt = f'温度峰 {temp_peak:.0f}°C <font color="warning">过热</font>'
|
||||
else:
|
||||
temp_txt = f"温度峰 {temp_peak:.0f}°C 正常"
|
||||
lines.append(f"**GPU** {name} {util_txt} | {mem_txt} | {temp_txt}")
|
||||
else:
|
||||
gpus_now = _check_gpus()
|
||||
@@ -415,22 +419,25 @@ def device_check(alarm_threshold: int = 80) -> dict:
|
||||
if docker.get("running") is None:
|
||||
docker_txt = issues[0]["issue"] if issues else "不可用"
|
||||
else:
|
||||
docker_txt = f"运行 {docker['running']}/{docker.get('total', '?')} · 异常 {len(issues)}" + ("🔴" if issues else "")
|
||||
n_issues = len(issues)
|
||||
docker_txt = "运行 " + f"{docker['running']}/{docker.get('total', '?')} · 异常 "
|
||||
docker_txt += f'<font color="warning">{n_issues}</font>' if n_issues else "0"
|
||||
if svc:
|
||||
docker_txt += f" | OCR {'✅' if svc.get('ocr') else '🔴'} | PG {'✅' if svc.get('pg') else '🔴'}"
|
||||
docker_txt += " · OCR " + ("正常" if svc.get("ocr") else '<font color="warning">异常</font>')
|
||||
docker_txt += " · PG " + ("正常" if svc.get("pg") else '<font color="warning">异常</font>')
|
||||
lines.append(f"**Docker** {docker_txt}")
|
||||
for it in issues[:8]:
|
||||
lines.append(f"> 🔴 {it['name']}:{it['issue']}")
|
||||
lines.append(f"> {it['name']}:{it['issue']}")
|
||||
|
||||
failures = checks.get("prefectFailures") or []
|
||||
if failures:
|
||||
lines.append(f"**失败任务(24h)** {len(failures)} 次 🔴")
|
||||
lines.append(f'**任务** 失败 <font color="warning">{len(failures)} 次</font>(24h)')
|
||||
for f in failures[:5]:
|
||||
lines.append(f"> {f['flow']}「{f['name']}」{f['state']} · {(f.get('start') or '')[5:]}")
|
||||
lines.append(f"> {f['flow']}:{f['name']} {f['state']} {(f.get('start') or '')[5:]}")
|
||||
if len(failures) > 5:
|
||||
lines.append(f"> …共 {len(failures)} 次")
|
||||
else:
|
||||
lines.append("**失败任务(24h)** 0 ✅")
|
||||
lines.append("**任务** 失败 0 次(24h)")
|
||||
|
||||
mem_peak_for_alarm = mem.get("peak") if mem else None
|
||||
swap_peak_for_alarm = swap.get("peak") if swap else None
|
||||
@@ -442,8 +449,8 @@ def device_check(alarm_threshold: int = 80) -> dict:
|
||||
or any((g.get("tempPeak") or 0) >= GPU_TEMP_WARN for g in gpu_stats)
|
||||
or bool(issues) or bool(failures) or not svc.get("ocr") or not svc.get("pg")
|
||||
)
|
||||
lines.append('<font color="warning">🔴 有项目需要处理,见上</font>' if alarms
|
||||
else '<font color="info">✅ 一切正常</font>')
|
||||
lines.append('<font color="warning">有项目需要处理,见上</font>' if alarms
|
||||
else '<font color="info">一切正常</font>')
|
||||
|
||||
content = "\n".join(lines)
|
||||
sent = send_markdown(content)
|
||||
|
||||
Reference in New Issue
Block a user