2016-09-20 89 views
1

我工作的一个项目,我们有一个加载多个插件核心应用程序。 每个插件都有自己的配置文件,核心应用程序也有一个。记录 - 合并多个配置文件

我们正在使用从Python的标准库中的优秀日志模块。 日志记录模块包含从.ini文件加载日志记录配置的功能。 但是,如果加载另一个配置文件,则其他文件将被丢弃,并且只会使用新配置。

我想这样做是为了我的日志配置分割成多个文件,从而使应用程序可以加载自己的配置文件,然后加载每个插件的合并他们的日志配置到主之一。

注:fileConfig有一个叫做可设置为False disable_existing_loggers的选项。但是,这只会保留现有的记录器存活,但它仍然清除处理程序的内部映射(这意味着插件的配置不能使用应用程序配置文件中定义的处理程序)。

我可以手动合并文件来产生我自己的配置,但我宁愿避免这种情况。

感谢。


使其更清晰,我愿意做这样的事情:

# 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 

回答

1

我无法找到一个方法来做到我想要的东西,所以我最终轧制类做到这一点。

这是作为一个方便github gist

1

我通常使用logging.config.dictConfigpyYaml包进行此操作。该软件包允许您将配置文件的内容加载为字典对象。

唯一需要增加的是一个小的辅助类来处理配置覆盖/加载项:

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')