Log exception with traceback

后端 未结 11 1143
失恋的感觉
失恋的感觉 2020-12-02 04:25

How can I log my Python errors?

try:
    do_something()
except:
    # How can I log my exception here, complete with its traceback?
相关标签:
11条回答
  • 2020-12-02 04:57

    Uncaught exception messages go to STDERR, so instead of implementing your logging in Python itself you could send STDERR to a file using whatever shell you're using to run your Python script. In a Bash script, you can do this with output redirection, as described in the BASH guide.

    Examples

    Append errors to file, other output to the terminal:

    ./test.py 2>> mylog.log
    

    Overwrite file with interleaved STDOUT and STDERR output:

    ./test.py &> mylog.log
    
    0 讨论(0)
  • 2020-12-02 04:58

    Use logging.exception from within the except: handler/block to log the current exception along with the trace information, prepended with a message.

    import logging
    LOG_FILENAME = '/tmp/logging_example.out'
    logging.basicConfig(filename=LOG_FILENAME, level=logging.DEBUG)
    
    logging.debug('This message should go to the log file')
    
    try:
        run_my_stuff()
    except:
        logging.exception('Got exception on main handler')
        raise
    

    Now looking at the log file, /tmp/logging_example.out:

    DEBUG:root:This message should go to the log file
    ERROR:root:Got exception on main handler
    Traceback (most recent call last):
      File "/tmp/teste.py", line 9, in <module>
        run_my_stuff()
    NameError: name 'run_my_stuff' is not defined
    
    0 讨论(0)
  • 2020-12-02 04:58

    You can log all uncaught exceptions on the main thread by assigning a handler to sys.excepthook, perhaps using the exc_info parameter of Python's logging functions:

    import sys
    import logging
    
    logging.basicConfig(filename='/tmp/foobar.log')
    
    def exception_hook(exc_type, exc_value, exc_traceback):
        logging.error(
            "Uncaught exception",
            exc_info=(exc_type, exc_value, exc_traceback)
        )
    
    sys.excepthook = exception_hook
    
    raise Exception('Boom')
    

    If your program uses threads, however, then note that threads created using threading.Thread will not trigger sys.excepthook when an uncaught exception occurs inside them, as noted in Issue 1230540 on Python's issue tracker. Some hacks have been suggested there to work around this limitation, like monkey-patching Thread.__init__ to overwrite self.run with an alternative run method that wraps the original in a try block and calls sys.excepthook from inside the except block. Alternatively, you could just manually wrap the entry point for each of your threads in try/except yourself.

    0 讨论(0)
  • 2020-12-02 05:01

    maybe not as stylish, but easier:

    #!/bin/bash
    log="/var/log/yourlog"
    /path/to/your/script.py 2>&1 | (while read; do echo "$REPLY" >> $log; done)
    
    0 讨论(0)
  • 2020-12-02 05:04

    You can get the traceback using a logger, at any level (DEBUG, INFO, ...). Note that using logging.exception, the level is ERROR.

    # test_app.py
    import sys
    import logging
    
    logging.basicConfig(level="DEBUG")
    
    def do_something():
        raise ValueError(":(")
    
    try:
        do_something()
    except Exception:
        logging.debug("Something went wrong", exc_info=sys.exc_info())
    
    DEBUG:root:Something went wrong
    Traceback (most recent call last):
      File "test_app.py", line 10, in <module>
        do_something()
      File "test_app.py", line 7, in do_something
        raise ValueError(":(")
    ValueError: :(
    

    EDIT:

    This works too (using python 3.6)

    logging.debug("Something went wrong", exc_info=True)
    
    0 讨论(0)
提交回复
热议问题