Files
ai-rpg/app/core/logging.py

49 lines
1.4 KiB
Python
Raw Normal View History

2026-06-20 19:13:05 +03:00
"""Application logging setup using structlog."""
from __future__ import annotations
import logging
import sys
import structlog
from app.config import get_settings
def configure_logging() -> None:
"""Configure structlog + stdlib logging once at startup."""
cfg = get_settings()
level = getattr(logging, cfg.log_level.upper(), logging.INFO)
# stdlib root logger
logging.basicConfig(
level=level,
format="%(message)s",
stream=sys.stdout,
)
# structlog processors — JSON output in prod, pretty console in dev
shared_processors = [
structlog.contextvars.merge_contextvars,
structlog.processors.add_log_level,
structlog.processors.TimeStamper(fmt="iso"),
structlog.processors.StackInfoRenderer(),
structlog.processors.format_exc_info,
]
if cfg.debug:
renderer = structlog.dev.ConsoleRenderer(colors=True)
else:
renderer = structlog.processors.JSONRenderer()
structlog.configure(
processors=shared_processors + [renderer],
wrapper_class=structlog.make_filtering_bound_logger(level),
logger_factory=structlog.PrintLoggerFactory(),
cache_logger_on_first_use=True,
)
def get_logger(name: str | None = None) -> structlog.stdlib.BoundLogger:
"""Return a structlog logger bound to `name`."""
return structlog.get_logger(name) # type: ignore[return-value]