"""Structured JSON logging configuration. In **production** (``AEGIS_ENV=production``), emits one JSON object per line so that log aggregators (ELK, CloudWatch, Datadog) can ingest them without custom parsing. In **development** (default), uses a human-readable text format for comfortable local work. """ from __future__ import annotations import json import logging import os import sys from datetime import datetime, timezone class _JSONFormatter(logging.Formatter): """Emit each log record as a single-line JSON object.""" def format(self, record: logging.LogRecord) -> str: payload: dict = { "timestamp": datetime.fromtimestamp(record.created, tz=timezone.utc).isoformat(), "level": record.levelname, "logger": record.name, "message": record.getMessage(), } if record.exc_info and record.exc_info[1] is not None: payload["exception"] = self.formatException(record.exc_info) extra = getattr(record, "_extra", None) if extra: payload.update(extra) return json.dumps(payload, default=str) _DEV_FORMAT = "%(asctime)s %(levelname)-8s %(name)s — %(message)s" def setup_logging() -> None: """Configure the root logger based on the environment.""" is_production = os.environ.get("AEGIS_ENV", "").lower() == "production" level_name = os.environ.get("LOG_LEVEL", "INFO").upper() level = getattr(logging, level_name, logging.INFO) root = logging.getLogger() root.setLevel(level) if root.handlers: root.handlers.clear() handler = logging.StreamHandler(sys.stdout) handler.setLevel(level) if is_production: handler.setFormatter(_JSONFormatter()) else: handler.setFormatter(logging.Formatter(_DEV_FORMAT)) root.addHandler(handler) logging.getLogger("uvicorn.access").setLevel(logging.WARNING) logging.getLogger("sqlalchemy.engine").setLevel(logging.WARNING)