changes
This commit is contained in:
@@ -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)
|
||||
Reference in New Issue
Block a user