| from __future__ import annotations | |
| import logging | |
| import logging.config | |
| from app.core.config import get_settings | |
| _LOG_FORMAT = "%(asctime)s %(levelname)-8s %(name)s :: %(message)s" | |
| _DATE_FORMAT = "%Y-%m-%d %H:%M:%S" | |
| def setup_logging() -> None: | |
| """Configure root logger with a single stdout handler. Idempotent.""" | |
| settings = get_settings() | |
| logging.config.dictConfig( | |
| { | |
| "version": 1, | |
| "disable_existing_loggers": False, | |
| "formatters": { | |
| "default": { | |
| "format": _LOG_FORMAT, | |
| "datefmt": _DATE_FORMAT, | |
| }, | |
| }, | |
| "handlers": { | |
| "console": { | |
| "class": "logging.StreamHandler", | |
| "stream": "ext://sys.stdout", | |
| "formatter": "default", | |
| "level": settings.log_level, | |
| }, | |
| }, | |
| "loggers": { | |
| "uvicorn.access": {"level": "WARNING", "propagate": True}, | |
| "aiogram.event": {"level": "INFO", "propagate": True}, | |
| "sqlalchemy.engine": {"level": "WARNING", "propagate": True}, | |
| }, | |
| "root": { | |
| "handlers": ["console"], | |
| "level": settings.log_level, | |
| }, | |
| } | |
| ) | |