如何在 Python 中捕获日志库本身抛出的错误
How to catch errors thrown by logging library itself in Python
我不小心使用 Python3 以错误的方式调用了 logging.info(),库本身向控制台抛出错误,但 FileHandler 未能捕获此类错误。那么有没有一种方法可以捕获所有的错误,无论它们在哪里被抛出。
错误消息如下所示:
--- Logging error ---
...
TypeError: not all arguments converted during string formatting
Call stack:
File "<ipython-input-12-5ba547bc4aeb>", line 1, in <module>
logging.info(1,1)
Message: 1
Arguments: (1,)
复制以下代码可以重现我的问题。日志文件可以捕捉到logging.info()和ZeroDivisionError的错误,但是未能捕捉到日志库抛出的错误信息。
import logging
logger_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s: %(message)s')
logger_handler = logging.FileHandler('/Users/your_name/Desktop/logging.log')
logger_handler.setLevel(logging.DEBUG)
logger_handler.setFormatter(logger_formatter)
root_logger = logging.getLogger()
root_logger.setLevel(logging.DEBUG)
root_logger.addHandler(logger_handler)
try:
logging.info('test')
logging.info(1,1)
1/0
except:
logging.exception("")
日志文件输出:
2021-03-10 18:07:32,315 - root - INFO: test
2021-03-10 18:07:32,324 - root - ERROR:
Traceback (most recent call last):
File "<ipython-input-1-6a4f609a80ca>", line 17, in <module>
1/0
ZeroDivisionError: division by zero
记录在记录过程中可能发生的所有错误是不可能的,因为错误可能会破坏记录,如果这会触发记录调用,则会导致无限循环。但是,您可以通过覆盖处理程序的 handleError
来实现自定义错误处理,如果您感觉特别勇敢,请尝试在该错误处理程序中编写日志。根据您的代码,它看起来像这样:
import logging
class MyFileHandler(logging.FileHandler):
def handleError(self, record):
logging.error('There was an error when writing a log. Msg was: '+str(record.msg))
logger_handler = MyFileHandler('custom.log')
logger_handler.setLevel(logging.DEBUG)
root_logger = logging.getLogger()
root_logger.setLevel(logging.DEBUG)
root_logger.addHandler(logger_handler)
try:
logging.info('test')
logging.info(1,1)
1/0
except:
logging.exception("")
当然,如果你更愿意有一个冒泡的异常,而不是你可以从 handleError
.
提出
我不小心使用 Python3 以错误的方式调用了 logging.info(),库本身向控制台抛出错误,但 FileHandler 未能捕获此类错误。那么有没有一种方法可以捕获所有的错误,无论它们在哪里被抛出。
错误消息如下所示:
--- Logging error ---
...
TypeError: not all arguments converted during string formatting
Call stack:
File "<ipython-input-12-5ba547bc4aeb>", line 1, in <module>
logging.info(1,1)
Message: 1
Arguments: (1,)
复制以下代码可以重现我的问题。日志文件可以捕捉到logging.info()和ZeroDivisionError的错误,但是未能捕捉到日志库抛出的错误信息。
import logging
logger_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s: %(message)s')
logger_handler = logging.FileHandler('/Users/your_name/Desktop/logging.log')
logger_handler.setLevel(logging.DEBUG)
logger_handler.setFormatter(logger_formatter)
root_logger = logging.getLogger()
root_logger.setLevel(logging.DEBUG)
root_logger.addHandler(logger_handler)
try:
logging.info('test')
logging.info(1,1)
1/0
except:
logging.exception("")
日志文件输出:
2021-03-10 18:07:32,315 - root - INFO: test
2021-03-10 18:07:32,324 - root - ERROR:
Traceback (most recent call last):
File "<ipython-input-1-6a4f609a80ca>", line 17, in <module>
1/0
ZeroDivisionError: division by zero
记录在记录过程中可能发生的所有错误是不可能的,因为错误可能会破坏记录,如果这会触发记录调用,则会导致无限循环。但是,您可以通过覆盖处理程序的 handleError
来实现自定义错误处理,如果您感觉特别勇敢,请尝试在该错误处理程序中编写日志。根据您的代码,它看起来像这样:
import logging
class MyFileHandler(logging.FileHandler):
def handleError(self, record):
logging.error('There was an error when writing a log. Msg was: '+str(record.msg))
logger_handler = MyFileHandler('custom.log')
logger_handler.setLevel(logging.DEBUG)
root_logger = logging.getLogger()
root_logger.setLevel(logging.DEBUG)
root_logger.addHandler(logger_handler)
try:
logging.info('test')
logging.info(1,1)
1/0
except:
logging.exception("")
当然,如果你更愿意有一个冒泡的异常,而不是你可以从 handleError
.