2016-09-20 100 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')