Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python日志记录配置文件中使用程序变量_Python_Python 2.7_Logging - Fatal编程技术网

在python日志记录配置文件中使用程序变量

在python日志记录配置文件中使用程序变量,python,python-2.7,logging,Python,Python 2.7,Logging,我尝试使用以下方法启用python日志记录: #!/usr/bin/env python # -*- coding: utf-8 -*- import logging import logging.config import os test_filename = 'my_log_file.txt' try: logging.config.fileConfig('loggingpy.conf', disable_existing_loggers=False) except Exceptio

我尝试使用以下方法启用python日志记录:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import logging.config
import os
test_filename = 'my_log_file.txt'
try:
    logging.config.fileConfig('loggingpy.conf', disable_existing_loggers=False)
except Exception as e:
    # try to set up a default logger
    logging.error("No loggingpy.conf to parse", exc_info=e)
    logging.basicConfig(level=logging.WARNING, format="%(asctime)-15s %(message)s")
test1_log = logging.getLogger("test1")
test1_log.critical("test1_log crit")
test1_log.error("test1_log error")
test1_log.warning("test1_log warning")
test1_log.info("test1_log info")
test1_log.debug("test1_log debug")
[loggers]
keys=root

[handlers]
keys=handRoot

[formatters]
keys=formRoot

[logger_root]
level=INFO
handlers=handRoot

[handler_handRoot]
class=FileHandler
level=INFO
formatter=formRoot
args=(test_filename,)

[formatter_formRoot]
format=%(asctime)s:%(name)s:%(process)d:%(lineno)d %(levelname)s %(message)s
datefmt=
class=logging.Formatter
我想使用loggingpy.conf文件控制日志记录,如下所示:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import logging.config
import os
test_filename = 'my_log_file.txt'
try:
    logging.config.fileConfig('loggingpy.conf', disable_existing_loggers=False)
except Exception as e:
    # try to set up a default logger
    logging.error("No loggingpy.conf to parse", exc_info=e)
    logging.basicConfig(level=logging.WARNING, format="%(asctime)-15s %(message)s")
test1_log = logging.getLogger("test1")
test1_log.critical("test1_log crit")
test1_log.error("test1_log error")
test1_log.warning("test1_log warning")
test1_log.info("test1_log info")
test1_log.debug("test1_log debug")
[loggers]
keys=root

[handlers]
keys=handRoot

[formatters]
keys=formRoot

[logger_root]
level=INFO
handlers=handRoot

[handler_handRoot]
class=FileHandler
level=INFO
formatter=formRoot
args=(test_filename,)

[formatter_formRoot]
format=%(asctime)s:%(name)s:%(process)d:%(lineno)d %(levelname)s %(message)s
datefmt=
class=logging.Formatter
在这里,我试图将日志发送到本地“test_filename”命名的文件。当我运行此程序时,我得到:

ERROR:root:No loggingpy.conf to parse
Traceback (most recent call last):
  File "logging_test.py", line 8, in <module>
    logging.config.fileConfig('loggingpy.conf', disable_existing_loggers=False)
  File "/usr/lib/python2.7/logging/config.py", line 85, in fileConfig
    handlers = _install_handlers(cp, formatters)
  File "/usr/lib/python2.7/logging/config.py", line 162, in _install_handlers
    args = eval(args, vars(logging))
  File "<string>", line 1, in <module>
NameError: name 'test_filename' is not defined
CRITICAL:test1:test1_log crit
ERROR:test1:test1_log error
WARNING:test1:test1_log warning
错误:root:没有要解析的loggingpy.conf
回溯(最近一次呼叫最后一次):
文件“logging_test.py”,第8行,在
logging.config.fileConfig('loggingpy.conf',disable_existing_loggers=False)
文件“/usr/lib/python2.7/logging/config.py”,第85行,在fileConfig中
处理程序=\u安装\u处理程序(cp、格式化程序)
文件“/usr/lib/python2.7/logging/config.py”,第162行,在安装处理程序中
args=eval(args,vars(日志))
文件“”,第1行,在
NameError:未定义名称“test\u filename”
临界值:test1:test1\u日志临界值
错误:test1:test1\u日志错误
警告:test1:test1\u日志警告

读取时,似乎配置中的“args”值是在日志包命名空间的上下文中求值的,而不是在调用fileConfig时的上下文中求值的。有没有什么好办法可以让日志通过配置文件以这种方式运行,这样我就可以配置一个动态日志文件名(通常类似于“InputFile.log”),但仍然可以灵活地使用日志配置文件来更改它?

这是一个非常粗糙的方法,所以我不推荐使用它。但是,如果出于某种原因不想添加到日志名称空间,可以通过命令行参数传递日志文件名,然后使用sys.argv[1]访问它(sys.argv[0]是脚本名)


您可以将文件名放在日志命名空间中:

logging.test_filename = 'my_log_file.txt'
那么您现有的loggingpy.conf文件应该可以工作了


您应该能够在您的模块中使用任何您喜欢的东西(在合理范围内-我不会尝试logging.config='something')污染日志名称空间,这应该使它可以被配置文件引用。

即使这是一个老问题,我认为这仍然具有相关性。上述解决方案的替代方案是使用
logging.config.dictConfig(…)
并操作字典

MWE:

log_config.yml

version: 1
disable_existing_loggers: false
formatters:
  default:
    format: "%(asctime)s:%(name)s:%(process)d:%(lineno)d %(levelname)s %(message)s"
handlers:
  console:
    class: logging.StreamHandler
    formatter: default
    stream: ext://sys.stdout
    level: DEBUG
  file:
    class: logging.FileHandler
    formatter: default
    filename: "{path}/service.log"
    level: DEBUG
root:
  level: DEBUG
  handlers:
  - file
  - console
示例.py

import logging.config
import sys
import yaml

log_output_path = sys.argv[1]

log_config = yaml.load(open("log_config.yml"))
log_config["handlers"]["file"]["filename"] = log_config["handlers"]["file"]["filename"].format(path = log_output_path)
logging.config.dictConfig(log_config)

logging.debug("test")
可执行文件如下:

python example.py.

结果:

  • 当前工作目录中的service.log文件包含一行日志消息
  • 控制台输出一行日志消息
两者都是这样表述的:

2016-06-06 20:56:56450:root:12232:11调试测试

使用eval在
logging.config.py
\u install\u handlers
解析args语句。因此,您可以将代码添加到
args

[handler_handRoot]
class=FileHandler
level=INFO
formatter=formRoot
args=(os.getenv("LOG_FILE","default_value"),)

现在,您只需要填充环境变量。

这很好,因为它指出日志名称空间(如sys.*和os.*)中有某些内容可用,但本地名称空间不可用。这很简单,效果很好。使用下面Sean的答案,您甚至可以执行args=(os.path.join('.',test_filename),)来帮助将文件放在需要的位置。谢谢我误读了这个问题,因此删除了我(大错特错)的评论。太棒了!这么简单。当使用dictConfig而不是fileConfig时,这个选项可以工作吗?我喜欢这个。这是干净的,不会损坏名称空间。如果我没有弄错的话,这要求密钥(handlers/file/filename)存在。如果没有,则会出现异常失败。您脚本的每个用户都应该知道,如果他们重命名文件处理程序或希望完全删除它,此脚本将失败。您是对的,如果在所有位置都没有正确反映更改,则脚本将失败。这就是为什么我把它命名为MWE。它不打算在产品中复制和使用,但应显示给定问题的可能解决方案。