2016-06-18 100 views
4

我添加了兩個具有不同格式化的處理程序到我的記錄器。第一個需要繼承日誌記錄.Formatter自定義格式。第二個處理程序默認的格式化程序就足夠了。繼承logging.Formatter更改默認行爲logging.Formatter

比方說,第一個格式化程序只是從消息中刪除換行符。下面的腳本說明了什麼似乎是奇怪的現象:

import logging 

logger = logging.getLogger(__name__) 

class CustomFormatter(logging.Formatter): 
    def __init__(self, *args, **kwargs): 
     super().__init__(*args, **kwargs) 
    def format(self, record): 
     record.msg = record.msg.strip().replace('\n', ' ') 
     return super().format(record) 

h1 = logging.StreamHandler() 
formatter1 = CustomFormatter(fmt=None, datefmt=None) 
h1.setFormatter(formatter1) 
logger.addHandler(h1) 

h2 = logging.StreamHandler() 
formatter2 = logging.Formatter(fmt=None, datefmt=None) 
h2.setFormatter(formatter2) 
logger.addHandler(h2) 

logger.warning('string with\nmultiple lines') 

此輸出以下:

string with multiple lines 
string with multiple lines 

我預計這個代替:

string with multiple lines 
string with 
multiple lines 

第二格式不應該執行的行爲CustomFormatter,但它的確如此。當我將處理程序添加到記錄器的順序顛倒時,這不會發生。

除非我誤解了子類,否則不應通過重寫子類中的方法來改變基類的行爲。當我重寫logging.Formatter以外的類的方法時,這似乎不成問題。

這是記錄模塊中的錯誤,還是我在這裏丟失了一些東西?

+0

有趣的是,我沒有'logger.handlers [1] .formatter = None'和記錄器仍然愉快地印刷兩行。但是'logger.handlers [1] = None'按預期破壞了事情。 – tdelaney

回答

2

這條線是你往下掉:

record.msg = record.msg.strip().replace('\n', ' ') 

您重新分配洗滌的字符串,這是通過使用連接到記錄器所有剩餘的處理/格式化記錄。複製該記錄和它的工作原理:

import logging 
from copy import copy 

logger = logging.getLogger(__name__) 

class CustomFormatter(logging.Formatter): 
    def __init__(self, *args, **kwargs): 
     super().__init__(*args, **kwargs) 
    def format(self, record): 
     record = copy(record) 
     record.msg = record.msg.strip().replace('\n', ' ') 
     return super().format(record) 

h1 = logging.StreamHandler() 
formatter1 = CustomFormatter(fmt=None, datefmt=None) 
h1.setFormatter(formatter1) 
logger.addHandler(h1) 

h2 = logging.StreamHandler() 
formatter2 = logging.Formatter(fmt=None, datefmt=None) 
h2.setFormatter(formatter2) 
logger.addHandler(h2) 

logger.warning('string with\nmultiple lines') 

輸出

string with multiple lines 
string with 
multiple lines 
+0

這很有道理 - 謝謝指出我的失誤! –