Используйте 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