Spaces:
Sleeping
Sleeping
| """ | |
| Logging setup — structured JSON in production, human-readable in dev. | |
| Switch with env var LOG_FORMAT=json|text (default: text for local dev). | |
| Every /chat request gets a `request_id` UUID; pass it via `extra={...}` on | |
| every log call inside the request, and downstream tooling can trace the | |
| question through retrieve → LLM → response. | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import logging | |
| import os | |
| import sys | |
| from datetime import datetime, timezone | |
| # These keys are part of the default LogRecord and are not user payload — | |
| # everything else found on the record was added via `extra=` and should ship. | |
| _STANDARD_ATTRS = { | |
| "name", "msg", "args", "levelname", "levelno", "pathname", "filename", | |
| "module", "exc_info", "exc_text", "stack_info", "lineno", "funcName", | |
| "created", "msecs", "relativeCreated", "thread", "threadName", | |
| "processName", "process", "message", "taskName", | |
| } | |
| class JsonFormatter(logging.Formatter): | |
| def format(self, record: logging.LogRecord) -> str: | |
| payload: dict = { | |
| "ts": datetime.now(timezone.utc).isoformat(), | |
| "level": record.levelname, | |
| "logger": record.name, | |
| "msg": record.getMessage(), | |
| } | |
| for k, v in record.__dict__.items(): | |
| if k not in _STANDARD_ATTRS and not k.startswith("_"): | |
| payload[k] = v | |
| if record.exc_info: | |
| payload["exc"] = self.formatException(record.exc_info) | |
| return json.dumps(payload, ensure_ascii=False, default=str) | |
| def configure_logging() -> None: | |
| fmt = os.getenv("LOG_FORMAT", "text").lower() | |
| handler = logging.StreamHandler(sys.stdout) | |
| if fmt == "json": | |
| handler.setFormatter(JsonFormatter()) | |
| else: | |
| handler.setFormatter(logging.Formatter( | |
| "%(asctime)s %(levelname)s %(name)s %(message)s" | |
| )) | |
| root = logging.getLogger() | |
| # Replace any pre-existing handlers so uvicorn's default doesn't double-log. | |
| for h in list(root.handlers): | |
| root.removeHandler(h) | |
| root.addHandler(handler) | |
| root.setLevel(os.getenv("LOG_LEVEL", "INFO").upper()) | |