[英]How to specify in YAML to always create log file in the project's folder using dictConfig?
In my Python program I have the following code: 在我的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)
...
and this is my logging.yml configuration file: 这是我的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
The problem is that the bot.log file is created where the program is launched. 问题是在程序启动的地方创建了bot.log文件。 I want it to always be created in the project's folder, ie in the same folder as my Python program.
我希望它始终在项目的文件夹中创建,即与我的Python程序在同一文件夹中。
For an example, launching the program with ./bot.py
would create the log file in the same folder. 例如,使用
./bot.py
启动程序将在同一文件夹中创建日志文件。 But launching it with python3 path/bot.py
would create the log file a level above the Python program in the file hierarchy. 但是使用
python3 path/bot.py
启动它会在文件层次结构中创建一个高于Python程序的日志文件。
How should I write the filename in the config file to solve this? 我应该如何在配置文件中写入文件名来解决这个问题? Or do I need to write a custom handler?
或者我需要编写自定义处理程序? If so, how?
如果是这样,怎么样? Or is this not possible to solve using dictConfig?
或者使用dictConfig无法解决这个问题?
There are a number of ways you can achieve what you want. 有很多方法可以达到你想要的效果。 For example, one way is to make a custom initialiser for your handler:
例如,一种方法是为您的处理程序创建自定义初始化程序:
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()
Note that I moved the logging.yml
to be adjacent to the script. 请注意,我将
logging.yml
移动到脚本旁边。 The logmaker
is the custom initialiser. logmaker
是自定义初始化程序。 Specify it in the YAML as follows: 在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
If you run the Python script, you should find that the bot.log
is created adjacent to the script and YAML file. 如果您运行Python脚本,您会发现
bot.log
是在脚本和YAML文件旁边创建的。 The same message is printed to the console and bot.log
: 相同的消息将打印到控制台和
bot.log
:
2013-04-16 11:08:11,178 DEBUG cloaked_chatter Hello, world!
NB The script could be a little tidier, but it illustrates my point. NB脚本可能有点整洁,但它说明了我的观点。
Update: As per the documentation , the use of ()
as a key in dictionary indicates that the value is a callable which is essentially a custom constructor for the handler. 更新:根据文档 ,使用
()
作为字典中的键表示该值是可调用的,它本质上是处理程序的自定义构造函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.