HEL-543 返工: 补充 observability 运行时可关闭开关 (DATAHUB_OBSERVABILITY)
总工复核 🔴:安全边界要求新增观测功能必须可关闭、关闭后现有功能完全照旧, 但此前实现没有任何运行时开关。修复: - settings.py: 新增 Settings.observability_enabled 字段,沿用既有 DATAHUB_SCHEDULER 的环境变量模式,读取 DATAHUB_OBSERVABILITY (0/false/off 关闭,默认开启)。 - hub.py: Hub.__init__ 把 settings.observability_enabled 挂到 self.db 上,让 pipeline/realtime_serve/steward/admin_api 已经 在传的 db 参数直接带上开关,零额外改造。 - observability.py: 新增 is_enabled(db),缺失该属性时默认按启用处理 (向后兼容裸 HubDB 用例/测试)。关闭时 observe() 变成纯 透传(不计时、不分类、不碰数据库),record_call() 直接 no-op。 - admin_api.py: 4 个新只读端点关闭时返回明确的 {"enabled": false, ...空结构} 而不是静默返回旧数据。 - 新增 10 个测试:开关默认值/环境变量解析、关闭后 observe() 的透传语义 (含异常原样重新抛出)、关闭后 record_call() 零写入、关闭后重新开启恢复 记录、4 个 admin 端点在关闭态的响应结构。 全量测试 183/183 通过(新增 10 个,含此前 173 个零回归)。 Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
co-authored by
Cursor
multica-agent
parent
f014eb11bd
commit
abd4d22a67
@@ -81,6 +81,21 @@ def _logger():
|
||||
return get_logger()
|
||||
|
||||
|
||||
def is_enabled(db: Any) -> bool:
|
||||
"""Runtime kill switch (``Settings.observability_enabled`` /
|
||||
``DATAHUB_OBSERVABILITY``, wired onto the db handle in ``Hub.__init__``).
|
||||
|
||||
Defaults to enabled when the attribute is absent — e.g. a bare ``HubDB``
|
||||
built directly in a test, or any call site that predates HEL-543 — so
|
||||
this can never accidentally disable an existing deployment. Never
|
||||
raises.
|
||||
"""
|
||||
try:
|
||||
return bool(getattr(db, "observability_enabled", True))
|
||||
except Exception: # pragma: no cover - defensive, must never raise
|
||||
return True
|
||||
|
||||
|
||||
def classify_error(message: str) -> tuple[str, str]:
|
||||
"""Best-effort, side-reading classification of an exception message.
|
||||
|
||||
@@ -171,7 +186,7 @@ def record_call(
|
||||
) -> None:
|
||||
"""Fail-open recorder. Never raises; a write failure here must never be
|
||||
able to take down a real, otherwise-successful data path."""
|
||||
if db is None:
|
||||
if db is None or not is_enabled(db):
|
||||
return
|
||||
try:
|
||||
now = isoformat(now_shanghai())
|
||||
@@ -282,8 +297,12 @@ def observe(
|
||||
Returns exactly what ``fn()`` returns and re-raises exactly what
|
||||
``fn()`` raises. ``db`` may be ``None`` (e.g. in call sites that are not
|
||||
wired to a database yet); in that case this is a transparent passthrough
|
||||
with no recording at all.
|
||||
with no recording at all. Same when the ``DATAHUB_OBSERVABILITY`` kill
|
||||
switch is off (see ``is_enabled``): this becomes ``return fn()`` with no
|
||||
timing, no classification, and no db access whatsoever.
|
||||
"""
|
||||
if db is not None and not is_enabled(db):
|
||||
return fn()
|
||||
started = time.perf_counter()
|
||||
try:
|
||||
result = fn()
|
||||
|
||||
Reference in New Issue
Block a user