从Python日志记录的YAML配置文件中评估语句

从Python日志记录的YAML配置文件中评估语句

本文介绍了从Python日志记录的YAML配置文件中评估语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下Python logging YAML配置文件片段:

Consider the following snippet of a Python logging YAML config file:

version: 1
formatters:
  simple:
    format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
  logfile:
    class: logging.handlers.TimedRotatingFileHandler
    level: DEBUG
    filename: some_fancy_import_name.generate_filename_called_error
    backupCount: 5
    formatter: simple

我想通过以下方式加载此YAML配置文件:

I would like to load this YAML config file this way:

with open('logging.yaml', 'r') as fd:
    config = yaml.safe_load(fd.read())
logging.config.dictConfig(config)

特别注意handler应该向其写入日志的filename.在普通的Python代码中,我希望some_fancy_import_name.generate_filename_called_errorlog生成字符串'error.log'.总而言之,我想说这个日志处理程序应该写入当前目录中的文件'error.log'.

Take special notice of the filename to which the handler should write logs. In normal Python code, I would expect some_fancy_import_name.generate_filename_called_errorlog to generate the string 'error.log'. All in all, I would like to say that this logging handler should write to the file 'error.log' in the current directory.

然而,事实证明并非如此.当我查看当前目录时,看到一个名为'some_fancy_import_name.generate_filename_called_errorlog'的文件.

However, as it turns out, this is not the case. When I look at the current directory, I see a file named 'some_fancy_import_name.generate_filename_called_errorlog'.

我希望以编程方式确定filename.我已经成功尝试使用这种方式使用常规Python脚本配置日志记录:

I would like filename to be programmatically determined. I have successfully tried configuring logging using normal Python scripting this way:

# fancy import name
from os import environ as env

# Programmatically determine filename path
log_location = env.get('OPENSHIFT_LOG_DIR', '.')
log_filename = os.path.join(log_location, 'error')
handler = logging.handlers.TimedRotatingFileHandler(log_filename)

查看如何从环境变量中推断出log_filename路径.

See how the log_filename path was inferred from environment variables.

我想将其转换为YAML配置文件.有可能吗?

I would like to translate this to a YAML config file. Is it possible?

也许我可能需要翻阅yaml.safe_load(fd.read())产生的dict并做一些eval()东西?

Perhaps I might need to dig through the dict produced by yaml.safe_load(fd.read()) and do some eval() stuff?

推荐答案

您可以添加自定义构造函数,并使用特殊标记标记该值,以便您的构造函数在加载时被执行:

You can add a custom constructor and mark the value with a special tag, so your constructor gets executed when loading it:

import yaml

def eval_constructor(loader, node):
  return eval(loader.construct_scalar(node))

yaml.add_constructor(u'!eval', eval_constructor)

some_value = '123'

config = yaml.load("""
version: 1
formatters:
  simple:
    format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
  logfile:
    class: logging.handlers.TimedRotatingFileHandler
    level: DEBUG
    filename: !eval some_value
    backupCount: 5
    formatter: simple
""")

print config['handlers']['logfile']['filename']

这将打印123,因为值some_value具有标签!eval,因此已加载eval_constructor.

This prints 123, since the value some_value has the tag !eval, and therefore is loaded with eval_constructor.

请注意eval配置数据的安全隐患.可以通过将任意Python代码写入YAML文件来执行!

Be aware of the security implications of evaling configuration data. Arbitrary Python code can be executed by writing it into the YAML file!

这篇关于从Python日志记录的YAML配置文件中评估语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-28 21:15