Python: создать собственный обработчик ведения журнала и настроить существующий файл конфигурации для перенаправления журналов в виджет «Вывод» - PullRequest
1 голос
/ 11 февраля 2020

Примечание: это мой самый первый пост. Сначала я попытался найти ответ, извиняюсь за то, что не нашел, если он уже существует. Если я сделаю что-то не так с этим постом, сообщите мне, научите меня, помогите мне улучшить.

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

[loggers]
keys=root, main , [...list of loggers...]

[handlers]
keys=consoleHandler, fileHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_main]
level=DEBUG
handlers=consoleHandler, fileHandler
qualname=main
propagate=0

[...all loggers...]

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=simpleFormatter
args=('logconfig.log',)

[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=
class=logging.Formatter

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

logging.config.fileConfig('logging.conf')
logger = logging.getLogger('main')

Это работает очень хорошо при запуске только сценария.

Теперь мне нужно запустить свой сценарий в записной книжке Jupyter с помощью команды % run magi c, которая также отлично работает. Но оттуда я хочу перенаправить любой вывод из журнала в виджет «Вывод». Итак, в предыдущей ячейке от запуска сценария я (пытаюсь) объявить пользовательский обработчик:

class OutputWidgetHandler(logging.StreamHandler):
    """ Custom logging handler sending logs to an output widget """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        layout = {
            'width': '80%',
            'height': '160px',
            'border': '1px solid black'
        }
        self.out = widgets.Output(layout=layout)
        display(self.out)

    def emit(self, record):
        """ Overload of logging.Handler method """
        formatted_record = self.format(record)
        new_output = {
            'name': 'stdout',
            'output_type': 'stream',
            'text': formatted_record+'\n'
        }
        self.out.outputs = (new_output, ) + self.out.outputs

, который я связываю с моим файлом конфигурации с помощью:

logging.handlers.OutputWidgetHandler = OutputWidgetHandler
logging.config.fileConfig('logging.conf')

И я обновите конфигурацию соответствующим образом:

[handlers]
keys= OutputWidgetHandler, consoleHandler, fileHandler

[logger_main]
level=DEBUG
handlers= OutputWidgetHandler, fileHandler
qualname=main
propagate=0

[...]

[handler_OutputWidgetHandler]
class=handlers.OutputWidgetHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

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

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

Спасибо за помощь, если у вас есть какие-либо подсказки, любая идея приветствуется и может решить эту проблему. Приветствия.

...