Search code examples
pythonloggingtracebackpython-logging

Can I make Python output exceptions in one line / via logging?


I am using AWS and use AWS cloudwatch to view logs. While things should not break on AWS, they could. I just had such a case. Then I searched for Traceback and just got the lines

Traceback (most recent call last):

without the actual traceback. I have a working structured logging setup (see other question) and I would like to get tracebacks in a similar way.

So instead of:

Traceback (most recent call last):
  File "/home/math/Desktop/test.py", line 32, in <module>
    adf
NameError: name 'adf' is not defined

something like

{"message": "Traceback (most recent call last):\n      File \"/home/math/Desktop/test.py\", line 32, in <module>\n        adf\n    NameError: name 'adf' is not defined", "lineno": 35, "pathname": "/home/math/Desktop/test.py"}

or even better also with the string in a JSON format.

The only way to achieve this I can think of is a giant try-except block. Pokemon-style. Is there a better solution?


Solution

  • You can use sys.excepthook. It is invoked whenever an exception occurs in your script.

    import logging
    import sys
    import traceback
    
    def exception_logging(exctype, value, tb):
        """
        Log exception by using the root logger.
    
        Parameters
        ----------
        exctype : type
        value : NameError
        tb : traceback
        """
        write_val = {'exception_type': str(exctype),
                     'message': str(traceback.format_tb(tb, 10))}
        logging.exception(str(write_val))
    

    Then in your script you have to override the value of sys.excepthook.

    sys.excepthook = exception_logging
    

    Now whenever an exception occurs it will be logged with your logger handler.

    Note: Don't forget to setup logger before running this