2015-02-06 86 views
1

在我的應用程序中,我使用logging.captureWarnings(True)來確保在正常的應用程序日誌中有任何DeprecationWarning登錄。如何更改與logging.captureWarnings()關聯的記錄器?

這種運作良好,但會導致像日誌:

WARNING [py.warnings] c:\some\path... 

看來from the documentation說:

如果捕獲爲True,由警告模塊發出的警告將被 重定向到日誌系統。具體來說,警告將使用warnings.formatwarning()格式化爲 ,並且生成的字符串 已記錄到一個名爲'py.warnings'的記錄器,其嚴重程度爲WARNING。

所以這是所有的預期。但是我想更改與此類警告相關的記錄器(使用我的應用程序提供的記錄器,以便在查看來自DeprecationWarning的日誌時可以知道)。

有沒有辦法改變關聯的記錄器?

回答

1

我只是做了一些調查,發現以達到一個完美的方式:

源代碼尋找logging.captureWarnings()

def captureWarnings(capture): 
    """ 
    If capture is true, redirect all warnings to the logging package. 
    If capture is False, ensure that warnings are not redirected to logging 
    but to their original destinations. 
    """ 
    global _warnings_showwarning 
    if capture: 
     if _warnings_showwarning is None: 
      _warnings_showwarning = warnings.showwarning 
      warnings.showwarning = _showwarning 
    else: 
     if _warnings_showwarning is not None: 
      warnings.showwarning = _warnings_showwarning 
      _warnings_showwarning = None 

似乎可以只改變warnings.showwarning指向另一個調用這將做任何你想要的記錄工作(或其他任何事情)。

預期的原型warnings.showwarning似乎是:

def _show_warning(message, category, filename, lineno, file=None, line=None): 
    """Hook to write a warning to a file; replace if you like.""" 
    if file is None: 
     file = sys.stderr 
    try: 
     file.write(formatwarning(message, category, filename, lineno, line)) 
    except IOError: 
     pass # the file (probably stderr) is invalid - this warning gets lost. 

看來logging.captureWarnings()實際上是設置調用到logging._showwarning

def _showwarning(message, category, filename, lineno, file=None, line=None): 
    """ 
    Implementation of showwarnings which redirects to logging, which will first 
    check to see if the file parameter is None. If a file is specified, it will 
    delegate to the original warnings implementation of showwarning. Otherwise, 
    it will call warnings.formatwarning and will log the resulting string to a 
    warnings logger named "py.warnings" with level logging.WARNING. 
    """ 
    if file is not None: 
     if _warnings_showwarning is not None: 
      _warnings_showwarning(message, category, filename, lineno, file, line) 
    else: 
     s = warnings.formatwarning(message, category, filename, lineno, line) 
     logger = getLogger("py.warnings") 
     if not logger.handlers: 
      logger.addHandler(NullHandler()) 
     logger.warning("%s", s) 
相關問題