我正在开发一个项目,我们有一个加载多个插件的核心应用程序。 每个插件都有自己的配置文件,核心应用程序也有一个。
我们正在使用python标准库中的优秀日志记录模块。 日志记录模块包括从.ini文件加载日志记录配置的功能。 但是,如果加载另一个配置文件,则会丢弃其他文件,并且仅使用新配置。
我想要做的是将我的日志配置拆分为多个文件,以便应用程序可以加载自己的配置文件,然后加载每个插件将其日志配置合并到主要配置文件中。
注意:fileConfig有一个名为disable_existing_loggers的选项,可以设置为False。但是,这只会使现有的记录器保持活动状态,但它仍然会清除处理程序的内部映射(这意味着插件的配置不能使用应用程序配置文件中定义的处理程序)。
我可以手动合并文件以生成我自己的配置,但我宁愿避免这种情况。
感谢。
为了更清楚,我想做这样的事情:
# application.ini
[loggers]
keys=root,app
[handlers]
keys=rootHandler,appHandler
[formatters]
keys=myformatter
[logger_root]
# stuff
[handler_rootHandler]
# stuff
[formatter_myformatter]
# stuff
...
# plugin.ini
[loggers]
keys=pluginLogger # no root logger
[handlers]
keys=pluginHandler # no root handler
# no formatters section
[logger_pluginLogger]
# stuff
formatter=myformatter # using the formatter from application.ini
答案 0 :(得分:1)
我找不到办法去做我想做的事情,所以我最后还是上了一堂课去做。
这是一个方便的github gist。
答案 1 :(得分:1)
我通常使用 logging.config.dictConfig 和 pyYaml 包执行此操作。该程序包允许您将配置文件的内容作为 dict 对象加载。
唯一需要的是一个小助手类来处理配置覆盖/附加组件:
import yaml
class Configuration(dict):
def __init__(self,
config_file_path=None,
overwrites=None):
with open(config_file_path) as config_file:
config = yaml.load(config_file)
super(Configuration, self).__init__(config)
if overwrites is not None:
for overwrite_key, value in overwrites.items():
self.apply_overwrite(self, overwrite_key, value)
def apply_overwrite(self, node, key, value):
if isinstance(value, dict):
for item in value:
self.apply_overwrite(node[key], item, value[item])
else:
node[key] = value
例如,如果您的主要配置是:
logger:
version: 1
disable_existing_loggers: False
formatters:
simple:
format: '%(levelname)s: Module: %(name)s Msg: %(message)s'
handlers:
file:
level: DEBUG
class: logging.handlers.RotatingFileHandler
maxBytes: 10000000
backupCount: 50
formatter: simple
filename: '/tmp/log1.log'
root:
handlers: [file]
level: DEBUG
,你的覆盖是:
logger:
handlers:
file:
filename: '/tmp/log2.log'
你可以像这样得到你的覆盖记录器:
from configuration import Configuration
from logging.config import dictConfig
import logging
if __name__ == '__main__':
config = Configuration('standard.yml', overwrites=Configuration('overwrite.yml'))
dictConfig(config['logger'])
logger = logging.getLogger(__name__)
logger.info('I logged it')