"""Environment-variable-based observability configuration. Follows the codebase's existing plain-`os.getenv` convention (see `DEPLOYMENT_ENV` in `app/routers/health.py` and friends) rather than introducing a Settings/pydantic-settings framework. Reads are done fresh on every call -> callers that need a stable snapshot across a request should hold onto the returned `ObservabilityConfig` themselves. """ from __future__ import annotations import os from pathlib import Path from pydantic import BaseModel, ConfigDict from app.observability.contracts import TelemetryMode _VALID_MODES: frozenset[str] = frozenset({"disabled", "local", "full"}) _TRUE_STRINGS = {"1", "true", "yes", "on"} class ObservabilityConfig(BaseModel): """Resolved observability configuration for the current process.""" model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True) enabled: bool mode: TelemetryMode otlp_endpoint: str signoz_ui_url: str artifact_root: Path capture_content: bool = False def _read_bool(name: str, default: bool) -> bool: raw = os.getenv(name) if raw is None: return default return raw.strip().lower() in _TRUE_STRINGS def get_observability_config() -> ObservabilityConfig: """Read observability configuration from the environment. `OTEL_MODE` gets special handling for evaluation runs: an evaluation run (`EVALUATION_RUN=true`) raises a descriptive `ValueError` if `OTEL_MODE` is set to a genuinely invalid string (not one of "disabled", "local", or "full") instead of silently falling back to "disabled" the way ordinary product startup does. An explicit `OTEL_MODE=disabled` (or unset, which defaults to "disabled") remains a legitimate, non-raising configuration under `EVALUATION_RUN=true` -- a benchmark run explicitly opting out of telemetry is a valid choice, not a misconfiguration. Ordinary product startup additionally requires `OTEL_ENABLED=true`; `DEPLOYMENT_ENV=demo` always forces the effective mode to disabled. """ evaluation_run = _read_bool("EVALUATION_RUN", default=False) demo_deployment = os.getenv("DEPLOYMENT_ENV", "desktop").strip().lower() == "demo" enabled = _read_bool("OTEL_ENABLED", default=False) and not demo_deployment raw_mode = os.getenv("OTEL_MODE", "disabled") mode_is_valid = raw_mode in _VALID_MODES if evaluation_run and not mode_is_valid: raise ValueError( f"OTEL_MODE={raw_mode!r} is invalid for an evaluation run " f"(EVALUATION_RUN=true); expected one of {sorted(_VALID_MODES)}." ) mode: TelemetryMode = raw_mode if mode_is_valid else "disabled" # type: ignore[assignment] # Product telemetry is explicitly opt-in and is never started on the # constrained public demo backend. Evaluation runs retain their own # explicit OTEL_MODE contract so disabled/local/full comparisons work. if demo_deployment or (not enabled and not evaluation_run): mode = "disabled" otlp_endpoint = os.getenv("OTEL_EXPORTER_OTLP_ENDPOINT", "http://127.0.0.1:4318") signoz_ui_url = os.getenv("SIGNOZ_UI_URL", "http://127.0.0.1:8080") artifact_root_raw = os.getenv("OBSERVABILITY_ARTIFACT_ROOT", "~/.studybuddy/observability") return ObservabilityConfig( enabled=enabled, mode=mode, otlp_endpoint=otlp_endpoint, signoz_ui_url=signoz_ui_url, artifact_root=Path(artifact_root_raw).expanduser(), # Raw diagnostic content is local-only. Full/SigNoz export ignores the # flag even when accidentally enabled. capture_content=( mode == "local" and _read_bool("OBSERVABILITY_CAPTURE_CONTENT", default=False) ), )