from __future__ import annotations import logging import os import sys from pathlib import Path from django.conf import settings from loguru import logger _CONFIGURED = False def _is_truthy(value: str | None) -> bool: if value is None: return False return value.lower() in {"1", "true", "yes", "on"} def _get_stdout_level() -> str: env_level = os.environ.get("LOGURU_STDOUT_LEVEL") if env_level: return env_level debug_flag = os.environ.get("DEBUG") if debug_flag is None: try: debug_flag = "1" if getattr(settings, "DEBUG", False) else "0" except Exception: debug_flag = "0" return "DEBUG" if _is_truthy(debug_flag) else "INFO" def _get_log_file_path() -> Path: override = os.environ.get("LOGURU_FILE") if override: return Path(override) try: logging_config = getattr(settings, "LOGGING", None) or {} handler = (logging_config.get("handlers") or {}).get("file") or {} filename = handler.get("filename") if filename: path = Path(filename) if path.is_absolute(): return path return Path(getattr(settings, "BASE_DIR", Path.cwd())) / path except Exception: pass try: return Path(getattr(settings, "BASE_DIR", Path.cwd())) / "logs" / "app.log" except Exception: return Path.cwd() / "logs" / "app.log" def get_log_file_path() -> Path: return _get_log_file_path() def configure_loguru() -> Path: global _CONFIGURED if _CONFIGURED: return _get_log_file_path() log_file_path = get_log_file_path() log_file_path.parent.mkdir(parents=True, exist_ok=True) stdout_level = _get_stdout_level() log_format = "[{time:DD/MMM/YYYY HH:mm:ss}] {level} [{name}:{line}] {message}" logger.remove() logger.add( sys.stdout, level=stdout_level, enqueue=True, backtrace=False, diagnose=False, format=log_format, ) logger.add( str(log_file_path), level="DEBUG", enqueue=True, backtrace=True, diagnose=False, format=log_format + "\n{exception}", rotation="10 MB", retention="10 days", ) logging.root.setLevel(logging.DEBUG) _CONFIGURED = True logger.debug("Loguru logging configured with stdout and file sinks (stdout={})", stdout_level) return log_file_path