【问题标题】:How to specify in YAML to always create log file in the project's folder using dictConfig?如何在 YAML 中指定始终使用 dictConfig 在项目文件夹中创建日志文件?
【发布时间】:2013-03-28 22:49:26
【问题描述】:

在我的 Python 程序中,我有以下代码:

def main():
    # The file's path
    path = os.path.dirname(os.path.realpath(__file__))
    ...
    # Config file relative to this file
    loggingConf = open('{0}/configs/logging.yml'.format(path), 'r')
    logging.config.dictConfig(yaml.load(loggingConf))
    loggingConf.close()
    logger = logging.getLogger(LOGGER)
    ...

这是我的 logging.yml 配置文件:

version: 1
formatters:
  default:
    format: '%(asctime)s %(levelname)s %(name)s %(message)s'
handlers:
  console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: default
    stream: ext://sys.stdout
  file:
    class : logging.FileHandler
    formatter: default
    filename: bot.log
loggers:
  cloaked_chatter:
    level: DEBUG
    handlers: [console, file]
    propagate: no

问题是 bot.log 文件是在程序启动的地方创建的。我希望它始终在项目的文件夹中创建,即在与我的 Python 程序相同的文件夹中。

例如,使用./bot.py 启动程序会在同一文件夹中创建日志文件。但是使用python3 path/bot.py 启动它会在文件层次结构中创建比 Python 程序高一级的日志文件。

我应该如何在配置文件中写入文件名来解决这个问题?还是我需要编写一个自定义处理程序?如果是这样,怎么做?还是用dictConfig无法解决?

【问题讨论】:

  • 我根据您的评论更新了我的答案。

标签: python logging python-3.x yaml configuration-files


【解决方案1】:

您可以通过多种方式实现您的目标。例如,一种方法是为您的处理程序制作自定义初始化程序:

import os
import yaml

def logmaker():
    path = os.path.dirname(os.path.realpath(__file__))
    path = os.path.join(path, 'bot.log')
    return logging.FileHandler(path)

def main():
    # The file's path
    path = os.path.dirname(os.path.realpath(__file__))

    # Config file relative to this file
    loggingConf = open('{0}/logging.yml'.format(path), 'r')
    logging.config.dictConfig(yaml.load(loggingConf))
    loggingConf.close()
    logger = logging.getLogger('cloaked_chatter')
    logger.debug('Hello, world!')

if __name__ == '__main__':
    main()

请注意,我将logging.yml 移动到与脚本相邻的位置。 logmaker 是自定义初始化程序。在 YAML 中指定如下:

version: 1
formatters:
  default:
    format: '%(asctime)s %(levelname)s %(name)s %(message)s'
handlers:
  console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: default
    stream: ext://sys.stdout
  file:
    () : __main__.logmaker
    formatter: default
loggers:
  cloaked_chatter:
    level: DEBUG
    handlers: [console, file]
    propagate: no

如果您运行 Python 脚本,您应该会发现 bot.log 是在脚本和 YAML 文件旁边创建的。同样的消息打印到控制台和bot.log:

2013-04-16 11:08:11,178 DEBUG cloaked_chatter Hello, world!

注意脚本可能会更简洁一些,但它说明了我的观点。

更新:根据the documentation,使用() 作为字典中的键表示该值是可调用的,它本质上是处理程序的自定义构造函数。

【讨论】:

  • YAML代码中__main__.logmaker前面的():是什么意思?
  • 它是要调用以获取此数据的“模块”的名称,对我来说,我必须调用我的公共模块来实例化记录器@DanielJonsson
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-10-04
  • 2022-09-27
  • 1970-01-01
  • 1970-01-01
  • 2013-12-29
  • 2021-01-13
  • 2019-03-17
相关资源
最近更新 更多