【问题标题】:universal logger name in python logging yaml config filepython日志记录yaml配置文件中的通用记录器名称
【发布时间】:2018-04-16 09:27:54
【问题描述】:

好的,所以情况是我需要使用 yaml 配置文件进行日志记录。(不要问 - 我只需要它 :))。在编写“记录器:”指令时,我想使用一个记录器并能够使用getLogger(__name__) 从我的应用程序中的多个模块中获取它。如果我使用普通的 python 配置文件进行日志记录,我知道该怎么做,但是我找不到对 yaml 文件执行相同操作的方法。 使用 python 2.7 长话短说,这就是我所拥有的(这只是我的问题的一个简化示例,不是实际应用程序的一部分:)):

#this is app.py
import logging.config
import yaml
import os

def init_logging():
    path = 'logging.yaml'
    if os.path.exists(path):
        with open(path, 'r') as f:
            config = yaml.safe_load(f.read())
        logging.config.dictConfig(config['logging'])
    main()


def main():
    logger = logging.getLogger('app')
    logger.debug("done!")


init_logging()

这里是 logging.yaml 配置文件:

logging:
    version: 1
    formatters:
        brief:
            format: '%(message)s'
        default:
            format: '%(asctime)s %(levelname)-8s [%(name)s] %(message)s'
            datefmt: '%Y-%m-%d %H:%M:%S'

    handlers:
        console:
            class: logging.StreamHandler
            level: DEBUG

    loggers:
        app:
            handlers: [console]
            level: DEBUG

所以它就在这里 - 它有效。 '完成!消息显示在控制台中。 但我希望能够在配置中设置的不是一些不同的记录器(这里我称之为“应用程序”),而是一个通用的,就像它在 .py 配置中一样

"loggers": {
    "": {
        "handlers": ["console"],
        "level": "DEBUG",
    },
}

然后我会在不同的模块中使用logging.getLogger(__name__),它会始终使用一个“”记录器并向我显示消息。 那么有没有办法在 yaml 中创建一个通用记录器?像“”:在python日志配置中? 我试过 (), ~, null - 那些不做的工作。 基本上我需要能够使用我想要的任何名称调用记录器并获得一个指定的记录器。 是的 - 我可以在 yaml 中创建一个根指令并使用 logging.getLogger() 调用它

【问题讨论】:

  • 那么您是否尝试过'' 而不是~null
  • 是的 - 也没有运气。
  • 这似乎很奇怪,因为包含 '' 的 YAML 会产生与 Python 中相同的结构。您应该尝试通过转储和检查它们来找出 Python 结构和加载的 YAML 之间的区别。

标签: python python-2.7 logging configuration yaml


【解决方案1】:

好的,所以我找到了答案(感谢@flyx!)。 我比较了原始的 python dict 配置和从 yaml dict config 转换后的配置,发现日志记录会自动将 disable_existing_loggers: False 添加到 python 配置中。之后,我将此行添加到 yaml 并在 loggers 指令中使用了 '' .. 它奏效了! 所以生成的 yaml 配置是这样的:

..............
disable_existing_loggers: False

loggers:
    '':
        handlers: [console, sentry]
        level: DEBUG
        propagate: False

现在它可以工作了。即使我创建了一个像logging.getLogger('something') 这样的记录器并且记录器“某事”不在配置中,那么应用程序也会使用“记录器”。

如果记录器是在文件开头定义的(在配置它之前),@Don Kirkby 的答案将不起作用。但是,如果在配置日志记录之后定义记录器,则它可以正常工作。所以这是我问题中代码的解决方案,但不是问题的答案 - “那么有没有办法在 yaml 中创建通用记录器?就像“”:在 python 日志记录配置中?这就是为什么我没有选择它作为答案。但他的评论是完全合法的:)

【讨论】:

    【解决方案2】:

    诀窍是在其他记录器列表之外使用名为root 的特殊记录器。

    我在Python documentation 中找到了这个:

    root - 这将是根记录器的配置。除了propagate 设置不适用之外,配置的处理将与任何记录器一样。

    这是您问题中的配置更改为使用root 键:

    logging:
        version: 1
        formatters:
            brief:
                format: '%(message)s'
            default:
                format: '%(asctime)s %(levelname)-8s [%(name)s] %(message)s'
                datefmt: '%Y-%m-%d %H:%M:%S'
    
        handlers:
            console:
                class: logging.StreamHandler
                level: DEBUG
    
        root:
            handlers: [console]
            level: WARN
        loggers:
            app:
                level: DEBUG
    

    DEBUG 级别配置app,在WARN 级别配置其他所有内容。

    【讨论】:

      猜你喜欢
      • 2018-10-12
      • 1970-01-01
      • 1970-01-01
      • 2020-01-03
      • 2022-08-18
      • 2018-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多