如何解决记录 handleError() 不拦截异常
我创建了一个自定义 Python 日志处理程序,在其中覆盖了 handleError() 方法。为了测试它,我删除了包含日志文件的目录以强制记录错误。我期待下次尝试使用记录器记录某些内容时会触发对 handleError() 的调用。然而,这并没有发生。异常直接传递给我的方法进行日志记录。
最小可重复示例:
import logging
import os
import shutil
from logging.handlers import WatchedFileHandler
from pathlib import Path
class MySpecialWatchedFileHandler(WatchedFileHandler):
def handleError(self,record):
print("******************** HANDLING AN ERROR!!!! *********************")
super().handleError(record)
print("************** Start ************")
test_logger = logging.getLogger(__name__)
test_logger.handlers = []
log_directory = "/tmp/test_logdir"
Path(log_directory).mkdir(parents=True,exist_ok=True)
handler = MySpecialWatchedFileHandler(os.path.join(log_directory,"test_logfile.log"),delay=False)
test_logger.addHandler(handler)
test_logger.setLevel(logging.INFO)
# Force a failure by deleting the logging directory,so that it does not auto-recover.
shutil.rmtree(log_directory,ignore_errors=False)
test_logger.info("This is a test")
print("************** End ************")
结果输出:
/home/joe/percipient/mirage-backend-django/venv/bin/python /home/joe/.config/JetBrains/PyCharm2020.3/scratches/scratch.py
************** Start ************
Traceback (most recent call last):
File "/home/joe/.config/JetBrains/PyCharm2020.3/scratches/scratch.py",line 25,in <module>
test_logger.info("This is a test")
File "/usr/lib/python3.6/logging/__init__.py",line 1308,in info
self._log(INFO,msg,args,**kwargs)
File "/usr/lib/python3.6/logging/__init__.py",line 1444,in _log
self.handle(record)
File "/usr/lib/python3.6/logging/__init__.py",line 1454,in handle
self.callHandlers(record)
File "/usr/lib/python3.6/logging/__init__.py",line 1516,in callHandlers
hdlr.handle(record)
File "/usr/lib/python3.6/logging/__init__.py",line 865,in handle
self.emit(record)
File "/usr/lib/python3.6/logging/handlers.py",line 481,in emit
self.reopenIfNeeded()
File "/usr/lib/python3.6/logging/handlers.py",line 471,in reopenIfNeeded
self.stream = self._open()
File "/usr/lib/python3.6/logging/__init__.py",line 1061,in _open
return open(self.baseFilename,self.mode,encoding=self.encoding)
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/test_logdir/test_logfile.log'
Process finished with exit code 1
请注意,永远不会打印 ******************** HANDLING AN ERROR!!!! *********************
。
为什么我的处理程序没有捕获该异常?
不确定是否重要,但我已经尝试将 logging.raiseExceptions
设置为 True
和 False
,并将延迟设置为 True
和 {{ 1}} 在处理程序中,两个选项的行为都是相同的。
解决方法
这是python中的一个“错误”。基本上 WatchedFileHandler 上的 reopenIfNeeded()
方法没有被包装到捕获所有其他日志错误的 try/except 块中。根据目标的不同,有两种可能的更改可以使这项工作发挥作用:
1.) 只删除日志文件,而不是包含它的目录。 WatchedFileHandler 将能够检测到这一点并通过重新创建文件来恢复
2.) 使用常规的 FileHandler
而不是 WatchedFileHandler。不会尝试重新创建丢失的文件,handleError
将按预期处理错误
这是我最终解决它的方法。在我的自定义处理程序中,我覆盖了emit() 方法,在调用超类的emit() 方法周围使用我自己的try/except,以便它现在在打开日志时捕获异常并将其路由到我的handleError()方法。
class MySpecialWatchedFileHandler(WatchedFileHandler):
def handleError(self,record):
print("****** HANDLING AN ERROR!!!! *****")
#
# Do what I need to do to handle the error here
#
def emit(self,record):
try:
super().emit(record)
except Exception:
record.exc_info = sys.exc_info()
self.handleError(record)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。