This commit is contained in:
HotSwapp
2025-08-18 20:20:04 -05:00
parent 89b2bc0aa2
commit bac8cc4bd5
114 changed files with 30258 additions and 1341 deletions

View File

@@ -17,6 +17,8 @@ class StructuredLogger:
def __init__(self, name: str, level: str = "INFO"):
self.logger = logging.getLogger(name)
self.logger.setLevel(getattr(logging, level.upper()))
# Support bound context similar to loguru's bind
self._bound_context: Dict[str, Any] = {}
if not self.logger.handlers:
self._setup_handlers()
@@ -68,13 +70,24 @@ class StructuredLogger:
def _log(self, level: int, message: str, **kwargs):
"""Internal method to log with structured data."""
context: Dict[str, Any] = {}
if self._bound_context:
context.update(self._bound_context)
if kwargs:
structured_message = f"{message} | Context: {json.dumps(kwargs, default=str)}"
context.update(kwargs)
if context:
structured_message = f"{message} | Context: {json.dumps(context, default=str)}"
else:
structured_message = message
self.logger.log(level, structured_message)
def bind(self, **kwargs):
"""Bind default context fields (compatibility with loguru-style usage)."""
if kwargs:
self._bound_context.update(kwargs)
return self
class ImportLogger(StructuredLogger):
"""Specialized logger for import operations."""
@@ -261,8 +274,25 @@ def log_function_call(logger: StructuredLogger = None, level: str = "DEBUG"):
return decorator
# Local logger cache and factory to avoid circular imports with app.core.logging
_loggers: dict[str, StructuredLogger] = {}
def get_logger(name: str) -> StructuredLogger:
"""Return a cached StructuredLogger instance.
This implementation is self-contained to avoid importing app.core.logging,
which would create a circular import (core -> utils -> core).
"""
logger = _loggers.get(name)
if logger is None:
logger = StructuredLogger(name, getattr(settings, 'log_level', 'INFO'))
_loggers[name] = logger
return logger
# Pre-configured logger instances
app_logger = StructuredLogger("application")
app_logger = get_logger("application")
import_logger = ImportLogger()
security_logger = SecurityLogger()
database_logger = DatabaseLogger()
@@ -270,16 +300,16 @@ database_logger = DatabaseLogger()
# Convenience functions
def log_info(message: str, **kwargs):
"""Quick info logging."""
app_logger.info(message, **kwargs)
get_logger("application").info(message, **kwargs)
def log_warning(message: str, **kwargs):
"""Quick warning logging."""
app_logger.warning(message, **kwargs)
get_logger("application").warning(message, **kwargs)
def log_error(message: str, **kwargs):
"""Quick error logging."""
app_logger.error(message, **kwargs)
get_logger("application").error(message, **kwargs)
def log_debug(message: str, **kwargs):
"""Quick debug logging."""
app_logger.debug(message, **kwargs)
get_logger("application").debug(message, **kwargs)