通过缩进或前缀长度显示日志上下文级别
我的想法是做一个上下文日志记录的方案,下面是一个示例:
[ 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的日志模块,并且自己手动添加前缀来记录日志,比如:
(...)
log.debug('')
log.debug('Parsing dialogs files')
for dlg in defDlgList:
log.debug('... [{0}]'.format(dlg))
(...)
这样做效果还不错,但有一些细微的问题,比如:在函数内部记录日志时,这些函数可能会在不同的地方被调用,每次调用时前缀的长度可能会不一样。
我想找一种优雅且不显眼的方法,能够自动为每条日志确定'...'前缀的长度。我希望避免将前缀长度作为参数传递给每个函数,或者通过明确的调用来设置长度,比如:
(...)
logWrapper.debug('')
logWrapper.debug('Parsing dialogs files')
for dlg in defDlgList:
logWrapper.nextLogLevelBegin()
logWrapper.debug('[{0}]'.format(dlg))
logWrapper.nextLogLevelEnd()
(...)
有没有办法从Python的解析器获取当前的缩进级别,或者构建一个对日志记录敏感的包装类?
3 个回答
10
把之前的回答和这个问题的内容结合起来:我怎么在Python日志格式字符串中添加自定义字段?,可以实现同样的效果,而不需要单独提供一个自定义的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(logging.getLogger(__name__), {})
logger.debug('A debug message')
logger.error('An error message')
logger.info('An info message')
11
在查阅文档时,我发现没有直接的方法可以获取当前的缩进级别。你能做的最好就是获取当前函数的嵌套级别,方法如下:
len(traceback.extract_stack());
举个例子:
import traceback;
def test():
print len(traceback.extract_stack());
print len(traceback.extract_stack()); # prints 1
test(); # prints 2
20
也许你可以使用 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]