0

我想从子类调用父类的方法,但是当我运行以下命令时,我没有在日志文件中看到日志记录条目:

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]

实际结果是一个空的日志文件。问题是我应该对源代码进行哪些更改以使日志记录功能完整?将不胜感激任何帮助。

4

1 回答 1

1

您正在配置和重新配置logging模块,每次调用logging.config.dictConfig()时都将disable_existing_loggers参数留给dictConfig()to True。请参阅文档的字典架构详细信息部分

disable_existing_loggers- 是否要禁用任何现有的记录器。此设置反映了 中的同名参数fileConfig()。如果不存在,则此参数默认为 True。incremental如果为 True,则忽略此值。

所以每次你调用dictConfig()任何logging.Logger()实例都被禁用

如果您在使用创建单个对象之前只调用dictConfig() 一次,您的代码就可以工作。但是当您扩展到两个模块时,您的行 imports , executes并创建一个before 控制返回到模块,然后再次运行(您在其中创建的引用在任何地方都未使用)。logging.getLogger(__name__)Logging()from A import *AdictConfig()Logger()BdictConfig()loggerB

您只需要配置一次日志记录,最好从主入口点(使用 Python 运行的脚本)尽早配置,如果您的代码已经创建了Logger()要继续使用的实例,则需要设置incremental为 True (但请理解[那时只会应用您的配置的一个子集),或设置disable_existing_loggersFalse.

请记住,您始终可以更新从.yaml文件加载的字典,因此您可以使用:

config['disable_existing_loggers'] = False

在你传递configlogging.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)
于 2019-01-04T15:24:19.367 回答