2017-02-23 68 views
0

我試圖在日誌中使用str.format樣式模板。似乎無法讓它正常工作。使用`str.format`模板日誌消息

>>> import logging 
>>> logging.basicConfig(filename='/tmp/example', format='{asctime} - {levelname} - {message}', style='{', level=logging.INFO) 
>>> logger = logging.getLogger(__name__) 
>>> logger.warning('blah') 
>>> logger.warning('{foo:03d}', {'foo': 42}) 

實際輸出:

2017-02-23 16:11:45,695 - WARNING - blah 
2017-02-23 16:12:11,432 - WARNING - {foo:03d} 

預期輸出:

2017-02-23 16:11:45,695 - WARNING - blah 
2017-02-23 16:12:11,432 - WARNING - 042 

什麼我在此設置丟失?

我不想看到在記錄字符串之前對字符串進行格式化的變通辦法,或者使用舊式%模板的Python 2 solutions

回答

3

顯然style參數僅適用於有關消息(如時間戳,嚴重性等)的信息,而不適用於實際消息。

logger.warning文檔字符串:

warning(msg, *args, **kwargs) method of logging.Logger instance 
    Log 'msg % args' with severity 'WARNING'. 

看來,msg使用舊式格式格式化始終,所以記錄器的style參數甚至沒有考慮。

logging HOWTO包含一個位的更多信息:

...使用str.format()string.Template語法,你不能直接進行通話記錄,因爲內部日誌包使用 % -formatting合併格式字符串和可變參數。 在保持向後兼容性的情況下, 不會改變這一點,因爲現有代碼中的所有日誌記錄調用將使用%-格式字符串爲 。

0

「我不感興趣看到在字符串被記錄之前對字符串進行格式化的解決方法」爲什麼不呢?舊樣式在記錄之前對其進行格式化......您可以將該行在logger.warning調用中執行格式設置,並且它在功能上沒有任何變化。如果{foo:42}僅僅是一個更大的字典的成員,你可以做這樣的事情:

for key,val in warningsDictionary.iteritems(): 
    logger.warning('{'+key+':'+format(val,'03')+'}') 

這是否足夠取決於您實際正在嘗試做的。

+0

如果我們在調用記錄器之前格式化字符串,然後日誌聚合的東西不能正常工作 – wim

+0

你能更具體嗎?它如何不正常工作? – amoose136

+0

考慮諸如'logger.warning('thing%(thing_id)03d',{'thing_id':42})''的問題'的消息。這會在輸出中產生一個日誌消息,例如'042的問題'。然而,像'sentry'這樣的日誌聚合服務會將'001'事件,'042事件','069事件'作爲同一警告的不同表現集中在一起。如果您自己爲日誌記錄創建模板,而不是讓日誌記錄器處理日誌記錄,那麼您將失去所有功能,並且可以獲得數百萬個不同的警報(應該只有1次警報,並有數百萬次命中)。 – wim