feat(metrics): lightweight read-only GET /metrics raw-signal endpoint (ORCH-099)
FND/F1a: add a versioned read-only JSON endpoint GET /metrics that exposes the
orchestrator's own raw state for the future observability sidecar F1b — active
task stages, job queue, agent-liveness (pid/runtime/cpu_ticks), and cost/tokens.
The orchestrator emits ONLY raw signal it alone knows; thresholds/alerts/history
live in the separate sidecar (observer separated from observed, BRD §1).
- src/metrics.py: new leaf collector build_metrics() (never-raise per section,
serial_gate.snapshot() pattern); envelope schema_version/generated_at/clk_tck +
stages/queue/agents/cost. _read_cpu_ticks(pid) reads utime+stime from
/proc/<pid>/stat (null on None/dead/non-Linux pid — never raises).
- src/main.py: thin @app.get("/metrics") wrapper (style of GET /queue).
- src/db.py: read-only helpers get_running_agents() (dedicated SELECT, not an
extension of the hot-path get_running_jobs()), agent_cost_totals(),
queue_retry_stats(); job_status_counts() default dict gains the cancelled key.
- src/config.py: metrics_endpoint_enabled kill-switch (default True), env
ORCH_METRICS_ENABLED via explicit validation_alias so the documented switch
actually controls the flag.
- docs: README API table row + CHANGELOG entry (contract section already added
by architect); .env.example ORCH_METRICS_ENABLED.
Strictly read-only / never-raise: STAGE_TRANSITIONS / QG_CHECKS / check_* /
machine-verdict keys / DB schema untouched; /health//status//queue byte-for-byte.
Tests: tests/test_metrics.py (TC-01..TC-11) + env-alias tests in test_config.py.
Full suite green (1482).
Refs: ORCH-099
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -320,3 +320,20 @@ def test_deploy_status_guard_settings_env_override(monkeypatch):
|
||||
s = Settings()
|
||||
assert s.deploy_status_guard_enabled is False
|
||||
assert s.deploy_status_guard_repos == "orchestrator,enduro-trails"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ORCH-099 (D8): metrics_endpoint_enabled default + env alias ORCH_METRICS_ENABLED.
|
||||
# The field carries an explicit validation_alias so the DOCUMENTED env var
|
||||
# (README / ADR-001 D8) actually controls the flag, overriding the default
|
||||
# ORCH_ + field-name mapping (which would otherwise be ORCH_METRICS_ENDPOINT_*).
|
||||
# ---------------------------------------------------------------------------
|
||||
def test_metrics_endpoint_enabled_default_true(monkeypatch):
|
||||
monkeypatch.delenv("ORCH_METRICS_ENABLED", raising=False)
|
||||
monkeypatch.delenv("ORCH_METRICS_ENDPOINT_ENABLED", raising=False)
|
||||
assert Settings().metrics_endpoint_enabled is True
|
||||
|
||||
|
||||
def test_metrics_endpoint_enabled_reads_documented_env_alias(monkeypatch):
|
||||
monkeypatch.setenv("ORCH_METRICS_ENABLED", "false")
|
||||
assert Settings().metrics_endpoint_enabled is False
|
||||
|
||||
Reference in New Issue
Block a user