import logging
from datetime import datetime, timezone
from pythonjsonlogger import json
[docs]
def logger(level, json_logging=True):
"""Create a logger with JSON or standard formatting.
:param level: Logging level (e.g., logging.INFO, logging.DEBUG)
:type level: int
:param json_logging: Whether to use JSON formatting for logs
:type json_logging: bool
:return: AppLogger class
:rtype: class
"""
# Suppress verbose logging from third-party libraries
logging.getLogger("urllib3").setLevel(logging.WARNING)
logging.getLogger("pika").setLevel(logging.ERROR)
if json_logging:
log_handler = logging.StreamHandler()
log_handler.setLevel(level)
formatter = CustomJsonFormatter("%(timestamp)s %(level)s %(name)s %(message)s")
log_handler.setFormatter(formatter)
logging.basicConfig(handlers=[log_handler], level=level, force=True)
else:
logging.basicConfig(level=level)
class AppLogger:
"""Application logger class with metadata support.
Provides debug, info, warning, and error logging methods with
optional metadata support for structured logging.
"""
def __init__(self, name):
"""Initialize the application logger.
:param name: Name of the logger instance
:type name: str
"""
self.local_logger = logging.getLogger(name)
@staticmethod
def prepare_meta(meta=None):
"""Prepare metadata for logging.
:param meta: Metadata dictionary or None
:type meta: dict or None
:return: Formatted metadata or None
:rtype: dict or None
"""
return None if meta is None else {"attributes": meta}
@staticmethod
def setup_logger_level(lib, log_level):
"""Set the logging level for a specific library.
:param lib: Library name
:type lib: str
:param log_level: Logging level to set
:type log_level: int
"""
logging.getLogger(lib).setLevel(log_level)
def debug(self, message, meta=None):
"""Log a debug message.
:param message: Message to log
:type message: str
:param meta: Optional metadata to include
:type meta: dict or None
"""
self.local_logger.debug(message, extra=AppLogger.prepare_meta(meta))
def info(self, message, meta=None):
"""Log an info message.
:param message: Message to log
:type message: str
:param meta: Optional metadata to include
:type meta: dict or None
"""
self.local_logger.info(message, extra=AppLogger.prepare_meta(meta))
def warning(self, message, meta=None):
"""Log a warning message.
:param message: Message to log
:type message: str
:param meta: Optional metadata to include
:type meta: dict or None
"""
self.local_logger.warning(message, extra=AppLogger.prepare_meta(meta))
def error(self, message, meta=None):
"""Log an error message with exception info.
:param message: Message to log
:type message: str
:param meta: Optional metadata to include
:type meta: dict or None
"""
# noinspection PyTypeChecker
self.local_logger.error(
message, exc_info=1, extra=AppLogger.prepare_meta(meta)
)
return AppLogger