2011-03-31 93 views
10

我的想法是讓情境日誌方案在下面的例子中顯示:Python的縮進上下文級別記錄前綴長度

[ DEBUG] Parsing dialogs files 
[ DEBUG] ... [DialogGroup_001] 
[ DEBUG] ...... Indexing dialog xml file [c:\001_dlg.xml] 
[ DEBUG] ......... dialog [LobbyA] 
[ DEBUG] ............ speech nodes [3] 
[ DEBUG] ............... [LobbyA_01] 
[ DEBUG] ............... [LobbyA_02] 
[ DEBUG] ............... [LobbyA_03] 
[ DEBUG] ............ sms nodes [0] 
[ DEBUG] ......... dialog [LobbyB] 
[ DEBUG] ............ speech nodes [3] 
[ DEBUG] ............... [LobbyB_01] 
[ DEBUG] ............... [LobbyB_02] 
[ DEBUG] ............... [LobbyB_03] 
[ DEBUG] ............ sms nodes [0] 
[ DEBUG] ... [DialogGroup_002] 
[ DEBUG] ...... Indexing dialog xml file [c:\002_dlg.xml] 
[ DEBUG] ......... dialog [HighGroundsA] 
[ DEBUG] ............ speech nodes [3] 
[ DEBUG] ............... [HighGroundsA_01] 
[ DEBUG] ............... [HighGroundsA_02] 
[ DEBUG] ............... [HighGroundsA_03] 
[ DEBUG] ............ sms nodes [0] 

在這一點上,我使用的是自定義的一個Python的日誌記錄模塊,手登錄-written前綴時,例如:

(...) 

log.debug('') 
log.debug('Parsing dialogs files') 
for dlg in defDlgList: 
    log.debug('... [{0}]'.format(dlg)) 

(...) 

它的工作非常好,但有一些細微的問題,例如:從內部功能登錄時 - 他們可能會從不同範圍和前綴長度可以用於改變稱爲每次通話。

我正在尋找一種優雅而不可見的方式,爲每個日誌自動建立一個'...'前綴的長度。我寧願避免將前綴長度作爲參數傳遞給每個FUNC或使用顯式調用設置lenght,例如:

(...) 

logWrapper.debug('') 
logWrapper.debug('Parsing dialogs files') 
for dlg in defDlgList: 
    logWrapper.nextLogLevelBegin() 
    logWrapper.debug('[{0}]'.format(dlg)) 
    logWrapper.nextLogLevelEnd() 

(...) 

是否有一種方式來獲得從Python的解析器當前的縮進級別或構建敏感範圍包裝類記錄?

回答

11

也許你可以使用inspect.getouterframes找到縮進級別:

import inspect 
import logging 

logger=logging.getLogger(__name__) 

def debug(msg): 
    frame,filename,line_number,function_name,lines,index=inspect.getouterframes(
     inspect.currentframe())[1] 
    line=lines[0] 
    indentation_level=line.find(line.lstrip()) 
    logger.debug('{i} [{m}]'.format(
     i='.'*indentation_level, 
     m=msg    
     )) 

def foo():  
    debug('Hi Mom') 
    for i in range(1): 
     debug("Now we're cookin") 

if __name__=='__main__': 
    logging.basicConfig(level=logging.DEBUG) 
    foo() 

收益率

DEBUG:__main__:.... [Hi Mom] 
DEBUG:__main__:........ [Now we're cookin] 
+0

這是我需要知道的! :D:D:D:D 非常感謝! – Helbreder 2011-03-31 13:30:07

8

通過搜索文檔,我真的沒有辦法獲得當前的縮進級別。你能做的最好的,就是讓當前函數嵌套級別,像這樣:

len(traceback.extract_stack()); 

例子:

import traceback; 

def test(): 
    print len(traceback.extract_stack()); 

print len(traceback.extract_stack()); # prints 1 
test(); # prints 2 
+0

這個很有用,謝謝!我將把這個與選擇答案的解決方案結合起來,使嵌套函數的日誌正確。 – Helbreder 2011-03-31 13:47:06

3

將以前的答案與How do I add custom field to Python log format string?結合起來可以實現相同的結果,而無需提供自定義的debug()方法(因爲需要爲每個級別的info(),error()等完成相同的結果。

import logging 
import traceback 
class CustomAdapter(logging.LoggerAdapter): 
    @staticmethod 
    def indent(): 
     indentation_level = len(traceback.extract_stack()) 
     return indentation_level-4 # Remove logging infrastructure frames 

    def process(self, msg, kwargs): 
     return '{i}{m}'.format(i='\t'*self.indent(), m=msg), kwargs 

logger = CustomAdapter(logger, {}) 
logger.debug('A debug message') 
logger.error('An error message') 
logger.info('An info message')