在同步进程内内置 FastAPI/uvicorn HTTP endpoint (GET /health),返回结构化 健康快照,便于运维/监控被动探活: - 服务健康:cycle_lag(核心指标,超过 3×poll_interval 判 unhealthy)、 队列状态(pending/error/dead/cleaned 实时查)、capture 累计(enqueued/ deferred/aged_out)、最近 cycle 时间/耗时/错误。 - 数据健康:解析最近一次定时 compare_ids 报告(不跑全量 compare 太重)、 实时查 SyncLogArchive 异常痕迹(AgedOut/降级)、SyncQueue dead 行样本。 status 三态:healthy(200) / degraded(503, 有dead/error/aged_out/compare 不一致) / unhealthy(503, 主循环停滞)。状态码映射便于按码告警。 线程模型:uvicorn 占主线程,capture/apply/cleanup 循环跑后台 daemon 线程, NSSM 停服务时主线程退出、daemon 自动终止。health.enabled=false 时退化为 旧行为(同步循环占主线程)。Web 层(routes/)与业务逻辑(HealthChecker) 解耦,后期加运维接口(compare触发/死信管理/metrics)零结构改动。 零 SQL/零 schema 改动。新增依赖 fastapi/uvicorn[standard]。
32 lines
1022 B
Python
32 lines
1022 B
Python
"""GET /health -- passive health-check endpoint.
|
|
|
|
Returns a structured snapshot covering service health (process, cycle lag,
|
|
queue state) and data health (last compare result, drift traces, dead rows).
|
|
|
|
HTTP status follows the body's ``status`` field so off-the-shelf monitors that
|
|
alert on status code work without parsing JSON:
|
|
|
|
* ``200`` -- healthy
|
|
* ``503`` -- degraded or unhealthy
|
|
|
|
This keeps "service unreachable" (network/down) distinguishable from "service
|
|
up but needs attention" (200 would conflate them).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter, Depends, Response
|
|
|
|
from ..deps import get_checker
|
|
from ...health import HealthChecker
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/health", summary="Sync service health check")
|
|
def health(response: Response, checker: HealthChecker = Depends(get_checker)) -> dict:
|
|
snap = checker.snapshot()
|
|
# Map body status to HTTP code for code-based alerting.
|
|
if snap["status"] != "healthy":
|
|
response.status_code = 503
|
|
return snap
|