Пользовательский регистратор базы данных python с циклическим импортом

Я пытаюсь создать свой собственный обработчик журнала для ведения журнала в моделях базы данных, что расширяет возможности ведения журнала.

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()

и это конфигурация журнала:

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

однако я получаю следующую ошибку, см. stacktrace:

Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    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

Благодаря @istruble указал, что это связано с циклическим импортом настроек, как я могу избежать этого и по-прежнему регистрироваться в моделях базы данных?


person James Lin    schedule 17.09.2012    source источник
comment
Как ты это делаешь? Можете ли вы запустить его с python -m pdb или, возможно, поместить import pdb; pdb.set_trace() в свой settings.py и продолжить, чтобы вы могли получить приглашение pdb в точке ошибки и проверить состояние?   -  person Mu Mind    schedule 17.09.2012
comment
Возможно, циклический импорт settings.py? Прокрутите вверх 6 строк из этого раздела документов docs.djangoproject .com / ru / dev / themes / logging /   -  person istruble    schedule 17.09.2012
comment
@istruble да, это из-за циклического импорта, потому что обработчик журнала использует модель ...   -  person James Lin    schedule 17.09.2012


Ответы (2)


Я только что придумал еще один, более канонический способ его реализации с использованием отложенного импорта, моя первоначальная проблема заключалась в попытке импортировать модель внутри функции 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])
person James Lin    schedule 18.09.2012

У меня есть работа, и я признаю, что это похоже на взлом, который использует инъекцию модели в фактической точке регистрации, как это

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()

и вы регистрируете его в правильной модели, выполнив следующие действия:

import logging
import logger.models.TheModel

logger = logging.getLogger(__name__)
logger.info(123, extra={'model':TheModel})
person James Lin    schedule 17.09.2012