26 Stimmen

Wie kann ich aktuelle Zeile und Stack-Info mit Python protokollieren?

Ich habe eine Protokollierungsfunktion wie folgt.

logging.basicConfig(
    filename = fileName,
    format = "%(levelname) -10s %(asctime)s %(message)s",
    level = logging.DEBUG
)

def printinfo(string):
    if DEBUG:
        logging.info(string)

def printerror(string):
    if DEBUG:
        logging.error(string)
    print string

Ich muss die Zeilennummer und die Stapelinformationen anmelden. Zum Beispiel:

1: def hello():
2:    goodbye()
3:
4: def goodbye():
5:    printinfo()

---> Line 5: goodbye()/hello()

Wie kann ich das mit Python erreichen?

GELÖST

def printinfo(string):
    if DEBUG:
        frame = inspect.currentframe()
        stack_trace = traceback.format_stack(frame)
        logging.debug(stack_trace[:-1])
    if LOG:
        logging.info(string)

gibt mir diese Informationen, die genau das sind, was ich brauche.

DEBUG      2011-02-23 10:09:13,500 [
  '  File "/abc.py", line 553, in <module>\n    runUnitTest(COVERAGE, PROFILE)\n', 
  '  File "/abc.py", line 411, in runUnitTest\n    printinfo(string)\n']

20voto

Duncan Punkte 85702

Der Name der aktuellen Funktion, das Modul und die Zeilennummer können Sie einfach ändern, indem Sie die Formatzeichenfolge so ändern, dass sie diese enthält.

logging.basicConfig(
    filename = fileName,
    format = "%(levelname) -10s %(asctime)s %(module)s:%(lineno)s %(funcName)s %(message)s",
    level = logging.DEBUG
)

Die meisten Leute wollen den Stack nur, wenn sie eine Ausnahme protokollieren, und das Protokollierungsmodul macht das automatisch, wenn Sie logging.exception() . Wenn Sie wirklich Stack-Informationen zu anderen Zeitpunkten benötigen, müssen Sie das Traceback-Modul verwenden, um die zusätzlichen Informationen zu extrahieren, die Sie benötigen.

19voto

Dunes Punkte 34391
import inspect
import traceback

def method():
   frame = inspect.currentframe()
   stack_trace = traceback.format_stack(frame)
   print ''.join(stack_trace)

Verwenden Sie stack_trace[:-1], um zu vermeiden, dass Methoden-/Druckinformationen in den Stacktrace aufgenommen werden.

18voto

ncoghlan Punkte 37564

Ab Python 3.2 kann dies vereinfacht werden, indem man die stack_info=True Flagge zum Anrufe protokollieren . Für frühere Versionen müssen Sie jedoch eine der oben genannten Antworten verwenden.

6voto

bsimmons Punkte 167

Späte Antwort, aber gut.

Eine andere Lösung ist, dass Sie Ihren eigenen Formatierer mit einem Filter erstellen können, wie in den Dokumenten beschrieben ici . Dies ist eine wirklich großartige Funktion, da Sie nun nicht mehr eine Hilfsfunktion verwenden müssen (und die Hilfsfunktion überall dort einfügen müssen, wo Sie den Stack-Trace haben wollen). Stattdessen implementiert eine benutzerdefinierte formatierte es direkt in die Protokolle selbst.

import logging
class ContextFilter(logging.Filter):
    def __init__(self, trim_amount)
        self.trim_amount = trim_amount
    def filter(self, record):
        import traceback
        record.stack = ''.join(
            str(row) for row in traceback.format_stack()[:-self.trim_amount]
        )
        return True

# Now you can create the logger and apply the filter.
logger = logging.getLogger(__name__)
logger.addFilter(ContextFilter(5))

# And then you can directly implement a stack trace in the formatter.    
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s \n %(stack)s')

Hinweis: Im obigen Code werden die letzten 5 Stapelrahmen abgeschnitten. Dies ist nur der Einfachheit halber und damit wir keine Stackframes aus dem Python-Logging-Paket selbst anzeigen. (Es muss möglicherweise auch für verschiedene Versionen des Logging-Pakets angepasst werden)

3voto

Daniel Roseman Punkte 565786

Verwenden Sie die Traceback Modul.

logging.error(traceback.format_exc())

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X