loggingPythonexception的最佳方法

我打印我的exception到一个日志文件目前使用:

try: # coode in here except Exception, e: logging.error(e) 

我可以打印关于exception的更多信息和生成它的代码,而不仅仅是exceptionstring? 像行号或栈跟踪会很好。

logger.exception做到这一点。

例如:

 import logging try: 1/0 except Exception as e: logging.exception("message") 

输出:

 ERROR:root:message Traceback (most recent call last): File "<stdin>", line 2, in <module> ZeroDivisionError: integer division or modulo by zero 

@Paulo Check notes“,请注意,在Python 3中,必须在except部分内部调用logging.exception方法,如果在任意位置调用此方法,您可能会遇到一个奇怪的例外情况,文档会提醒您。

关于logging.exception一个好消息, SiggyF的答案没有显示,你可以传入一个任意的消息,并且日志仍然会显示所有exception细节的完整回溯:

 import logging try: 1/0 except Exception: logging.exception("Deliberate divide by zero traceback") 

使用sys.stderr打印错误的默认(最近版本)logging行为,它看起来像这样:

 >>> import logging >>> try: ... 1/0 ... except Exception: ... logging.exception("Deliberate divide by zero traceback") ... ERROR:root:Deliberate divide by zero traceback Traceback (most recent call last): File "<stdin>", line 2, in <module> ZeroDivisionError: integer division or modulo by zero 

使用exc_info选项可能会更好,允许您select错误级别(如果使用exception ,它将始终显示error ):

 try: # do something here except Exception as e: logging.error(e, exc_info=True) 

引用

如果您的应用程序以其他方式进行logging而不使用logging模块呢?

现在,可以在这里使用traceback

 import traceback def log_traceback(ex, ex_traceback=None): if ex_traceback is None: ex_traceback = ex.__traceback__ tb_lines = [ line.rstrip('\n') for line in traceback.format_exception(ex.__class__, ex, ex_traceback)] exception_logger.log(tb_lines) 
  • Python 2中使用它:

     try: # your function call is here except Exception as ex: _, _, ex_traceback = sys.exc_info() log_traceback(ex, ex_traceback) 
  • Python 3中使用它:

     try: x = get_number() except Exception as ex: log_traceback(ex) 

如果您使用普通日志 – 所有的日志logging应符合此规则: one record = one line 。 遵循这个规则,你可以使用grep和其他工具来处理你的日志文件。

但是回溯信息是多线的。 所以我的答案是在这个线程上面提到的zangw的一个扩展版本的解决scheme。 问题是,回溯行可能有\n里面,所以我们需要做一些额外的工作来摆脱这个行结束:

 import logging logger = logging.getLogger('your_logger_here') def log_app_error(e: BaseException, level=logging.ERROR) -> None: e_traceback = traceback.format_exception(e.__class__, e, e.__traceback__) traceback_lines = [] for line in [line.rstrip('\n') for line in e_traceback]: traceback_lines.extend(line.splitlines()) logger.log(level, traceback_lines.__str__()) 

之后(当你将分析你的日志),你可以从你的日志文件复制/粘贴所需的回溯线,并做到这一点:

 ex_traceback = ['line 1', 'line 2', ...] for line in ex_traceback: print(line) 

利润!

这个答案build立在上面的优秀。

在大多数应用程序中,您不会直接调用logging.exception(e)。 很可能你已经为你的应用程序或模块定义了特定的自定义logging器,如下所示:

 # Set the name of the app or module my_logger = logging.getLogger('NEM Sequencer') # Set the log level my_logger.setLevel(logging.INFO) # Let's say we want to be fancy and log to a graylog2 log server graylog_handler = graypy.GELFHandler('some_server_ip', 12201) graylog_handler.setLevel(logging.INFO) my_logger.addHandler(graylog_handler) 

在这种情况下,只需使用logging器来调用exception(e)就像这样:

 try: 1/0 except Exception, e: my_logger.exception(e) 

如果你可以处理额外的依赖关系然后使用twisted.log,你不必显式地logging错误,并且它将整个追踪和时间返回到文件或stream。

一个干净的方法是使用format_exc() ,然后parsing输出以获得相关部分:

 from traceback import format_exc try: 1/0 except Exception: print 'the relevant part is: '+format_exc().split('\n')[-2] 

问候