2011-03-31 1 views
10

mon idée est de faire système d'enregistrement de contexte comme le montre l'exemple ci-dessous:indentation Python niveau de contexte log longueur du préfixe

[ 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] 

A ce moment, je suis sur un module d'enregistrement de Python avec la coutume, la main préfixes -écrit lors de la connexion, par exemple:

(...) 

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

(...) 

Cela fonctionne très bien, mais il y a quelques problèmes subtils, par exemple: lors de la connexion de fonctions à l'intérieur - ils peuvent être appelés à partir de différents champs d'application et la longueur du préfixe peut varier pour chaque appel.

Je cherche une manière élégante et invisible pour établir une longueur d'un préfixe '...' automatiquement pour chaque notation. Je préfère éviter de passer la longueur du préfixe comme paramètre à chaque func ou le réglage de la longueur à l'aide des appels explicites, par exemple:

(...) 

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

(...) 

Y at-il un moyen d'obtenir le niveau de retrait actuel de l'analyseur de Python ou construire un champ sensible classe wrapper pour la journalisation?

Répondre

11

Peut-être que vous pouvez utiliser inspect.getouterframes pour trouver le niveau de retrait:

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() 

donne

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

C'est ce que j'avais besoin de savoir! : D: D: D: D Merci beaucoup! – Helbreder

8

En parcourant les documents, je ne vois pas vraiment comment obtenir le niveau d'indentation actuel. Le mieux que vous pouvez faire, est d'obtenir le niveau d'imbrication de la fonction actuelle, comme ceci:

len(traceback.extract_stack()); 

Exemple:

import traceback; 

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

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

Ceci est utile, merci! Je vais combiner cela avec des solutions de la réponse choisie pour que les fonctions imbriquées soient correctes. – Helbreder

3

La combinaison des réponses précédentes avec How do I add custom field to Python log format string? peut aboutir au même résultat sans avoir besoin de fournir une méthode de débogage() personnalisée (puisque la même chose devrait être faite pour chaque niveau info(), error(), etc.).

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')