From 76cb981d845a2d66460238e3fcccdd7f85df4d60 Mon Sep 17 00:00:00 2001 From: guke Date: Mon, 6 Jul 2026 10:48:27 +0800 Subject: [PATCH] =?UTF-8?q?feat(observe):=20=E5=8A=A0=20OBSERVE=5F*=20?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=B8=8E=20observe=5Fconfigured=20=E9=97=A8?= =?UTF-8?q?=E6=A7=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- app/core/config.py | 25 +++++++++++++++++++++++++ tests/test_observe.py | 25 +++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 tests/test_observe.py diff --git a/app/core/config.py b/app/core/config.py index 3e27af5..cfb7d04 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -317,6 +317,31 @@ class Settings(BaseSettings): return [] return [o.strip() for o in self.CORS_ALLOW_ORIGINS.split(",") if o.strip()] + # ===== 可观测(OpenObserve 接口指标)===== + # 采集每个接口的 QPS + 耗时 + 错误率,批量直采到 OpenObserve(本地 Docker)。 + # 默认关(prod 安全):未开启 → 中间件透传、worker 不启动,整套 no-op。 + # 开启需 ENABLED=true 且 ENDPOINT/USER/PASSWORD 齐全(见 observe_configured)。 + OBSERVE_ENABLED: bool = False + OBSERVE_ENDPOINT: str = "http://localhost:5080" # OpenObserve base URL + OBSERVE_ORG: str = "default" # 组织名 + OBSERVE_STREAM: str = "app_requests" # stream 名(首次上报自动建) + OBSERVE_USER: str = "" # Basic auth 邮箱 + OBSERVE_PASSWORD: str = "" # Basic auth 密码/token + OBSERVE_FLUSH_INTERVAL_SEC: float = 5.0 # worker 最长攒批间隔 + OBSERVE_BATCH_MAX: int = 200 # 单批最大事件数 + OBSERVE_QUEUE_MAX: int = 10000 # 有界队列上限,满则丢 + OBSERVE_TIMEOUT_SEC: float = 5.0 # 上报 HTTP 超时 + + @property + def observe_configured(self) -> bool: + """观测上报可用 = 总开关开 且 endpoint/账号/密码齐全(缺则整套 no-op)。""" + return bool( + self.OBSERVE_ENABLED + and self.OBSERVE_ENDPOINT + and self.OBSERVE_USER + and self.OBSERVE_PASSWORD + ) + @property def is_prod(self) -> bool: return self.APP_ENV == "prod" diff --git a/tests/test_observe.py b/tests/test_observe.py new file mode 100644 index 0000000..2fca409 --- /dev/null +++ b/tests/test_observe.py @@ -0,0 +1,25 @@ +"""接口指标可观测(observe)单测:配置门槛 / 队列 / 中间件 / worker。 + +沿用仓库约定:TestClient + monkeypatch,绝不打真网络。observe 默认关(conftest 未设 +OBSERVE_*),需要开启的用例用 monkeypatch 改 settings 单例属性。 +""" +from __future__ import annotations + +from app.core.config import settings + + +def test_observe_configured_requires_switch_and_creds(monkeypatch): + # 开关开 + endpoint(默认 localhost)+ user + password 齐全 → True + monkeypatch.setattr(settings, "OBSERVE_ENABLED", True) + monkeypatch.setattr(settings, "OBSERVE_USER", "u") + monkeypatch.setattr(settings, "OBSERVE_PASSWORD", "p") + assert settings.observe_configured is True + + # 缺密码 → False + monkeypatch.setattr(settings, "OBSERVE_PASSWORD", "") + assert settings.observe_configured is False + + # 开关关 → False(即便凭证齐全) + monkeypatch.setattr(settings, "OBSERVE_PASSWORD", "p") + monkeypatch.setattr(settings, "OBSERVE_ENABLED", False) + assert settings.observe_configured is False