Используйте fileConfig для настройки пользовательских обработчиков в Python

Я использую файл конфигурации для настройки моего регистратора в приложении Python. Это файл:

[loggers]
keys=root

[logger_root]
level=INFO
handlers=console

[handlers]
keys=console,file_rotating

[handler_console]
class=StreamHandler
level=WARNING
formatter=console
args=(sys.stderr,)

[handler_file_rotating]
class=TimeRotatingFileHandler
level=DEBUG
formatter=file
args=('../logs/twicker.log', 'd', 1, 5)

[formatters]
keys=console,file

[formatter_console]
format=%(levelname)s - %(message)s

[formatter_file]
format=%(asctime)s - %(levelname)s - %(module)s - %(message)s

Моя проблема с TimeRotatingFileHandler. Каждый раз, когда я запускаю приложение, я получаю следующую ошибку:

ImportError: нет модуля с именем "TimeRotatingFileHandler"

Что я делаю не так? Я попытался также изменить строку класса на class=handlers.TimeRotatingFileHandler но в этом случае я получаю следующую ошибку:

ImportError: нет модуля с именем "обработчики"

3 ответа

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

[handler_file_rotating]
class=logging.handlers.TimeRotatingFileHandler
level=DEBUG
formatter=file
args=('../logs/twicker.log', 'd', 1, 5)

Вы можете попробовать

class= оценивается в пространстве имен logging модуль, и по умолчанию это не имеет привязки к handlers, Так что вы могли бы сделать

import logging, logging.handlers
logging.handlers = logging.handlers

перед звонком fileConfig(), а потом class=handlers.TimedRotatingHandler должно сработать.

Чтобы немного расширить это, если вы решите создать собственный обработчик, все, что вам нужно сделать, это определить этот обработчик в верхней части вашего кода, а затем определить его как объект в logging.handlers.

Пример:

class MyCustomRotatingClass(logging.handlers.RotatingFileHandler):
   """custom handler that queues messages
      to be uploaded in batches to the portal
      in a background thread
   """
   def __init__(self, basedir, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0):
       logging.handlers.RotatingFileHandler.__init__(self, 'TestSavvyExecute.log','a',250000,40,'utf-8',0)
       self.maxBytes = maxBytes

   def emit(self, record):
       try:
           if logging.handlers.RotatingFileHandler.shouldRollover(self, record):
               logging.handlers.RotatingFileHandler.doRollover(self)

           #ASCII characters use 1 byte each
           if len(record.msg) > self.maxBytes:
               oldMsg = record.msg

               record.msg = record.msg[0:self.maxBytes]
               logging.FileHandler.emit(self, record)

               record.msg = oldMsg[self.maxBytes + 1:]
               self.emit(record)
           else:
              logging.FileHandler.emit(self, record)
       except (KeyboardInterrupt, SystemExit):
           raise
       except:
           logging.handlers.RotatingFileHandler.handleError(self, record)          

logging.handlers.MyCustomRotatingClass = MyCustomRotatingClass
logging.config.fileConfig('translator.log.config')

Теперь вы можете легко ссылаться на него в вашем конфигурационном файле.

[handler_rollinglog]
class=handlers.MyCustomRotatingClass
Другие вопросы по тегам