Logger de base de datos de Python personalizado, con importación circular

Estoy tratando de crear mi propio controlador de registro para iniciar sesión en modelos de db, lo que amplía el registro.

import logging from logging import Handler from logger.models import SearchLog class DBHandler(Handler,object): model = None def __init__(self, model): super(DBHandler, self).__init__() mod = __import__(model) components = name.split('.') for comp in components[1:]: mod = getattr(mod, comp) self.model = mod def emit(self,record): log_entry = self.model(level=record.levelname, message=record.msg) log_entry.save() 

y esta es la configuración de registro:

 'db_search_log':{ 'level': 'INFO', 'class': 'db_logger.handlers.DBHandler', 'model': 'db_logger.models.SearchLog', 'formatter': 'verbose', } 

Sin embargo, estoy recibiendo el error de seguimiento, ver stacktrace:

 Traceback (most recent call last): File "manage.py", line 10, in  execute_from_command_line(sys.argv) File "/home/james/virtualenv/hydrogen/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 443, in execute_from_command_line utility.execute() File "/home/james/virtualenv/hydrogen/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 382, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/home/james/virtualenv/hydrogen/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 252, in fetch_command app_name = get_commands()[subcommand] File "/home/james/virtualenv/hydrogen/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 101, in get_commands apps = settings.INSTALLED_APPS File "/home/james/virtualenv/hydrogen/local/lib/python2.7/site-packages/django/utils/functional.py", line 184, in inner self._setup() File "/home/james/virtualenv/hydrogen/local/lib/python2.7/site-packages/django/conf/__init__.py", line 42, in _setup self._wrapped = Settings(settings_module) File "/home/james/virtualenv/hydrogen/local/lib/python2.7/site-packages/django/conf/__init__.py", line 135, in __init__ logging_config_func(self.LOGGING) File "/usr/lib/python2.7/logging/config.py", line 777, in dictConfig dictConfigClass(config).configure() File "/usr/lib/python2.7/logging/config.py", line 575, in configure '%r: %s' % (name, e)) ValueError: Unable to configure handler 'db_search_log': Unable to configure handler 'db_search_log': 'module' object has no attribute 'handlers' 

 db_logger/ __init__.py __init__.pyc handlers.py handlers.pyc log_handlers.pyc models.py models.pyc router.py router.pyc tests.py views.py 

Gracias a @istruble señaló que eso se debe a las importaciones circulares de configuraciones, ¿cómo puedo evitarlo y seguir logueando los modelos de base de datos?

Se me ocurrió otra forma realmente más canónica de implementarlo utilizando importaciones retrasadas, mi problema original era intentar importar el modelo dentro de la función init :

 from logging import Handler class DBHandler(Handler,object): model_name = None def __init__(self, model=""): super(DBHandler,self).__init__() self.model_name = model def emit(self,record): # instantiate the model try: model = self.get_model(self.model_name) except: from logger.models import GeneralLog as model log_entry = model(level=record.levelname, message=self.format(record)) log_entry.save() def get_model(self, name): names = name.split('.') mod = __import__('.'.join(names[:-1]), fromlist=names[-1:]) return getattr(mod, names[-1]) 

Tengo una solución y admito que parece un truco, que utiliza la inyección del modelo en un punto de registro real como este.

 from logging import Handler class DBHandler(Handler,object): def __init__(self): super(DBHandler, self).__init__() def emit(self,record): model = record.model log_entry = model(level=record.levelname, message=record.msg) log_entry.save() 

y lo registra en el modelo correcto haciendo esto:

 import logging import logger.models.TheModel logger = logging.getLogger(__name__) logger.info(123, extra={'model':TheModel})