martian7777
feat: implement backend core with ORM models, authentication, and AI-driven telemetry diagnostics
e5be436 | """Structured logging setup using structlog. | |
| Produces human-friendly console logs in development and JSON logs in | |
| production so they can be ingested by log aggregators. | |
| """ | |
| from __future__ import annotations | |
| import logging | |
| import sys | |
| import structlog | |
| from app.core.config import settings | |
| def configure_logging() -> None: | |
| """Configure stdlib logging + structlog. Idempotent.""" | |
| log_level = logging.DEBUG if settings.debug else logging.INFO | |
| logging.basicConfig( | |
| format="%(message)s", | |
| stream=sys.stdout, | |
| level=log_level, | |
| ) | |
| shared_processors: list = [ | |
| structlog.contextvars.merge_contextvars, | |
| structlog.processors.add_log_level, | |
| structlog.processors.TimeStamper(fmt="iso"), | |
| structlog.processors.StackInfoRenderer(), | |
| structlog.processors.format_exc_info, | |
| ] | |
| if settings.environment == "production": | |
| renderer: structlog.types.Processor = structlog.processors.JSONRenderer() | |
| else: | |
| renderer = structlog.dev.ConsoleRenderer(colors=True) | |
| structlog.configure( | |
| processors=[*shared_processors, renderer], | |
| wrapper_class=structlog.make_filtering_bound_logger(log_level), | |
| logger_factory=structlog.PrintLoggerFactory(), | |
| cache_logger_on_first_use=True, | |
| ) | |
| def get_logger(name: str | None = None) -> structlog.stdlib.BoundLogger: | |
| return structlog.get_logger(name) | |