diff --git a/src/staylong/api/app.py b/src/staylong/api/app.py index 576f004..efe5aa9 100644 --- a/src/staylong/api/app.py +++ b/src/staylong/api/app.py @@ -1,5 +1,6 @@ """Authenticated FastAPI case-flow API with an injectable persistence boundary.""" +import logging import secrets from collections.abc import Callable from dataclasses import dataclass @@ -26,6 +27,14 @@ from staylong.services.taskmaster import TaskmasterWorkflow, WorkflowSnapshot +def configure_runtime_logging() -> None: + """Allow privacy-safe application INFO logs to reach Cloud Run stdout.""" + root_logger = logging.getLogger() + root_logger.setLevel(logging.INFO) + if not root_logger.handlers: + logging.basicConfig(level=logging.INFO) + + class ConcernRequest(BaseModel): """The non-clinical concern accepted by the case-flow API.""" diff --git a/src/staylong/api/main.py b/src/staylong/api/main.py index 2f714a4..3005510 100644 --- a/src/staylong/api/main.py +++ b/src/staylong/api/main.py @@ -3,7 +3,7 @@ import os from staylong.agents.intake import IntakeAgent -from staylong.api.app import create_app +from staylong.api.app import configure_runtime_logging, create_app from staylong.api.runtime import ( build_calendar_oauth, build_public_sandbox_config, @@ -81,6 +81,7 @@ def _runtime_components() -> tuple[TaskmasterWorkflow, object | None, object | N ) +configure_runtime_logging() _workflow, _calendar_oauth, _public_sandbox = _runtime_components() app = create_app( api_token=runtime_token(os.environ), diff --git a/tests/api/test_logging_config.py b/tests/api/test_logging_config.py new file mode 100644 index 0000000..d96858b --- /dev/null +++ b/tests/api/test_logging_config.py @@ -0,0 +1,20 @@ +import logging + +from staylong.api import app as api_app + + +def test_runtime_logging_emits_info_records_to_existing_root_handlers(caplog) -> None: + """Protects the Cloud Run timing signal from Python's WARNING default.""" + root_logger = logging.getLogger() + original_level = root_logger.level + root_logger.setLevel(logging.WARNING) + + try: + configure_runtime_logging = getattr(api_app, "configure_runtime_logging", None) + assert callable(configure_runtime_logging) + configure_runtime_logging() + logging.getLogger("staylong.services.taskmaster").info("timing signal") + finally: + root_logger.setLevel(original_level) + + assert "timing signal" in caplog.messages