Вызовите метод родительского класса из дочернего класса, но не видите в файле журнала

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

python.exe B.py

Если я позвоню printA() метод в A.py код, то я вижу запись в журнале.

Следующий фрагмент кода Python A.py файл:

#!/usr/bin/env python
import logging
import logging.config
import yaml

with open('logging.yaml', 'r') as f:
    config = yaml.safe_load(f.read())
    logging.config.dictConfig(config)
logger = logging.getLogger(__name__)

class A:
    def __init__(self, name, value):
        self.name = name
        self.value = value

    def printA(self):
        logger.info('Name: {}'.format(self.name))
        logger.info('Value: {}'.format(self.value))

B.py файл:

#!/usr/bin/env python
from A import *
import logging
import logging.config
import yaml


with open('logging.yaml', 'r') as f:
    config = yaml.safe_load(f.read())
    logging.config.dictConfig(config)
logger = logging.getLogger(__name__)

class B(A):
    def __init__(self, name, value):
        super(B, self).__init__(name, value + 1)      

b = B('Name', 1)
b.printA()

logging.yaml файл:

version: 1
formatters:
  simple:
    format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
  console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: simple
    stream: ext://sys.stdout
  debug_file_handler:
    class: logging.handlers.RotatingFileHandler
    level: DEBUG
    formatter: simple
    filename: debug.log
    maxBytes: 10485760 # 10MB
    backupCount: 20
    encoding: utf8
root:
  level: DEBUG
  handlers: [console, debug_file_handler]

Фактический результат - пустой файл журнала. Вопрос в том, что я должен изменить в своем исходном коде, чтобы завершить функцию регистрации? Буду благодарен за любую помощь.

1 ответ

Решение

Вы настраиваете и переконфигурируете logging модуль, и каждый раз, когда вы звоните logging.config.dictConfig() Вы покидаете disable_existing_loggers параметр для dictConfig() в True, См. Раздел " Сведения о схеме словаря " документации:

disable_existing_loggers - должны ли какие-либо существующие регистраторы быть отключены. Этот параметр отражает параметр с тем же именем в fileConfig(), Если этот параметр отсутствует, по умолчанию этот параметр равен True. Это значение игнорируется, если incremental правда.

Поэтому каждый раз, когда вы звоните dictConfig() любой logging.Logger() экземпляры отключены.

Ваш код работает, если вы звоните только dictConfig() один раз, прежде чем использовать logging.getLogger(__name__) создать свой сингл Logging() объект. Но когда вы расширили до двух модулей, ваш from A import * импорт линии A выполняет dictConfig() и создает Logger() до того, как контроль вернется к B модуль, который затем снова запускается dictConfig() (logger ссылка, которую вы создаете в B в противном случае нигде не используется).

Вам необходимо настроить ведение журнала только один раз, желательно как можно раньше с главной точки входа (сценария, который вы запускаете с Python), и если ваш код уже создан Logger() экземпляры, которые вы хотите продолжать использовать, вам нужно либо установить incremental в True (но понимайте [что тогда будет применяться только подмножество вашей конфигурации), или установите disable_existing_loggers в False,

Помните, что вы всегда можете обновить словарь, который вы загружаете из .yaml файл, так что вы можете просто использовать:

config['disable_existing_loggers'] = False

прежде чем пройти config в logging.config.dictConfig(),

Я бы использовал if __name__ == '__main__': сторож, чтобы убедиться, что вы настраиваете протоколирование только в этой точке. Не запускайте код верхнего уровня в модуле, который изменяет глобальную конфигурацию без такой защиты:

if __name__ == '__main__':
    # this module is used as a script, configure logging
    with open('logging.yaml', 'r') as f:
        config = yaml.safe_load(f.read())
    # do not disable any logger objects already created before this point
    config['disable_existing_loggers'] = False
    logging.config.dictConfig(config)
Другие вопросы по тегам