从子 class 调用父 class 的方法但未在日志文件中看到

Call a parent class's method from child class but don't see in the log file

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

python.exe B.py

如果我在 A.py 代码中调用 printA() 方法,那么我会看到日志条目。

下面的一段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]

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

您正在配置和重新配置 logging 模块,每次调用 logging.config.dictConfig() 时都会将 disable_existing_loggers 参数留给 dictConfig()True.参见文档的Dictionary Schema Details section

disable_existing_loggers - whether any existing loggers are to be disabled. This setting mirrors the parameter of the same name in fileConfig(). If absent, this parameter defaults to True. This value is ignored if incremental is True.

因此,每次您调用 dictConfig() 时,任何 logging.Logger() 个实例都会被 禁用

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

您只需要配置日志记录 一次,最好从主入口点(您 运行 和 Python 的脚本)尽早配置,如果您的代码已经创建了 Logger() 个您想继续使用的实例,您要么需要将 incremental 设置为 True(但请理解 [只有 subset of your configuration 会被应用),或将 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)