2011-07-27 46 views
9

用Python(通過日誌記錄模塊)臨時更改日誌消息格式的最簡單方法是什麼?如何在Python中臨時更改記錄消息的格式?

目標是擁有一些標準的消息格式,同時能夠臨時添加有關正在讀取的某個文件(如其名稱)的信息;當文件不再被讀取時,消息格式應該恢復爲默認值。產生這些消息的程序是而不是意識到正在讀取什麼文件,所以如果它的消息自動包含相關的文件名(如果錯誤消息是:「ERROR ,同時讀取文件 ***: ...「而不是」錯誤:...「)。

+0

我更新了我的答案。 –

回答

7

這是一個簡單的解決方案,可以從Vinay Sajip自己的HOWTO推導出來;它基本上更新日誌記錄格式化與setFormatter()

import logging 

logger = logging.getLogger() # Logger 
logger_handler = logging.StreamHandler() # Handler for the logger 
logger.addHandler(logger_handler) 

# First, generic formatter: 
logger_handler.setFormatter(logging.Formatter('%(message)s')) 
logger.error('error message') # Test 

# New formatter for the handler: 
logger_handler.setFormatter(logging.Formatter('PROCESSING FILE xxx - %(message)s')) 
logger.error('error message') # Test 

此正確地產生:

error message 
PROCESSING FILE xxx - error message 

(其中xxx可以動態地設置到正在處理的文件,如在問題問)。

+0

不知道爲什麼這被認爲是解決方案。處理程序確定日誌目標,格式化程序確定日誌格式;這兩個可以被認爲是正交的。如果我想臨時更改特定記錄器的日誌格式(例如記錄器'package1.module2')以添加一些特定於模塊的上下文信息,我希望爲記錄器的所有處理程序執行此操作。枚舉所有其他記錄器可能使用的處理程序,臨時更改格式,然後將其更改回來以免打破其他記錄器,這不是一個解決方案。 – dtheodor

+0

這確實是在這種更極端的情況下必須要做的事情,在這種情況下,人們幾乎無法控制處理程序在記錄器中的分佈情況。這是一個具體而不幸的案例。現在,這樣做仍然可以按照這個答案完成,所以對我來說看起來很好(免責聲明:我都問過這個問題並提供了這個答案)。有趣的是在上面的評論中針對案例大綱提出具體問題,並附上相應的具體答案;這屬於另一個StackOverflow條目。 – EOL

6

有幾種方法。除了already documented onesextra參數記錄調用,LoggerAdapter,Filter)之外,另一種方法是指定一個自定義格式類,其實例可以隨時瞭解正在處理的文件。例如:

class FileProcessingFormatter(logging.Formatter): 
    def __init__(self, fmt, datefmt=None, current_file=None): 
     super(FileProcessingFormatter, self).__init__(fmt, datefmt) 
     self.orig_fmt = fmt 
     self.current_file = current_file 

    def format(self, record): 
     if self.current_file is None: 
      self._fmt = self.orig_fmt.replace('__FILE_PLACEHOLDER__', '') 
     else: 
      self._fmt = self.orig_fmt.replace('__FILE_PLACEHOLDER__', 
          ' while processing %r' % self.current_file) 
     return super(FileProcessingFormatter, self).format(record) 

實例化格式化......

f = FileProcessingFormatter('%(levelname)s__FILE_PLACEHOLDER__ %(message)s') 
for h in relevant_handlers: 
    h.setFormatter(f) 

進程文件...

f.current_file = fn 
process_file(fn) 
f.current_file = None 

這是非常簡單的 - 例如,而不是在線程環境,如果使用文件處理由不同的線程同時完成。

更新:儘管根記錄器的處理程序可通過logging.getLogger().handlers訪問,但這是可能更改的實現細節。由於您的要求不是那麼基本,您可以使用dictConfig()來配置您的日誌記錄(可通過針對舊版Python的logutils項目進行配置)。

+0

謝謝。一個只能通過'logging.basicConfig()'定義的處理程序能獲得'relevant_handlers'嗎?如果不是,那麼如何定義'related_handlers'? – EOL

+0

感謝您的更新。我需要閱讀Logging HOWTO,也許更多 - 在我可以實現任何具體解決方案之前... – EOL

相關問題