我正在使用标准 SMTPHandler 记录器来捕获 Python 异常。 有没有办法将例外名称放入邮件主题中?这比静态主题好得多,因为Gmail(不仅是Gmail)可以根据主题对对话进行分组,因此它可以根据错误类型。
例如,如果发生 50 个完全相同的错误 + 1 个不同的错误,我会在收件箱中看到两个对话,而不是 1 个由 51 封电子邮件组成的组,在其中我可以很容易地忽略单个不同的错误。
另外,有没有办法防止发送相同的错误? 例如。以某种方式定义我自己的函数来决定是否发送电子邮件。该函数将在参数中获取一些基本信息,以便它可以做出决定(例如缓存并查看是否已经发送了此类问题)。
我浏览了文档,但找不到类似的内容。似乎很简单。 如果 SMTPHandler 不能做到这一点,那么最好且仍然简单的替代方案是什么? 有任何简洁的库吗?
谢谢!
您只需创建自己的 SMTPHandler 子类。
对于您的第一个请求:您只需重写
getSubject(record)
方法。至于主题里可以放什么,从logging导入Formatter后看help(Formatter)
。
对于您的第二个请求:您必须重写
emit(record)
方法。检查记录并自行决定是否发送。如果是这样,那么只需调用 super(SMTPHandler,self).emit(record)
方法即可。
class MySMTPHandler(SMTPHandler):
def getSubject(self, record):
return "My Error Format from the record dict"
def emit(self, record):
#check for record in self.already_send or something
if sendit:
super(MySMTPHandler,self).emit(record)
简单灵活的方法是不仅格式化电子邮件内容,还格式化电子邮件主题。这需要子类化
logging.handlers.SMTPHandler
。
这样如果您配置的主题中有任何变量引用,它将按需扩展。这是包含测试代码的实现:
import logging, logging.handlers
class TitledSMTPHandler(logging.handlers.SMTPHandler):
def getSubject(self, record):
formatter = logging.Formatter(fmt=self.subject)
return formatter.format(record)
# below is to test
logging.getLogger().addHandler(TitledSMTPHandler(
('your.smtp.server',587),
'[email protected]', '[email protected]',
'%(asctime)s Error: %(message)s',
('SMTP login', 'SMTP password'), ()
))
logging.error("TestError")
将 SMTP 配置替换为您的配置,运行代码,您应该会收到一封电子邮件,其中主题中包含错误消息(也在电子邮件正文中)。
如果您在日志配置文件中定义处理程序,请记住转义参数引用。例如
%(asctime)s
应该变成 %%(asctime)s
,以防止 configparser 过早插值 - 然而 %%
转义在 python 3.1 及之前并没有被支持。
拜托,如果您一次只问一个问题,您将为其他 Google 员工提供很大帮助。您应该开始两个主题,一个称为“有没有办法将异常名称放入邮件主题?”另一个“有没有办法防止发送相同的错误?”
我只会回答你的第一个问题,以便专注于一个主题。也许您认为这两个问题可能相互依赖,因此必须一起提出,但它们只是同时出现在您的脑海中。我认为建议你改变问题的标题来强调一个问题还是可行的,而不是说“高级的东西”。
如果问题是一个开放主题和/或无法很好定义(例如“我想要高级的东西,其他人都使用什么?”),我还建议访问 comp.lang.python
您可以继承 SMTPHandler 类并增强或替换其功能,例如
class A(object):
def __init__(self):
self.email = "[email protected]"
def send_error(self, error):
send_mail(self.email, error)
class B(A):
def __init__(self):
A.__init__(self)
def send_error(self, error):
if not error.sent:
A.send_mail(self, error)
else:
#do nothing
pass
首先,我建议使用您自己的记录器,而不是根记录器。 我还想指出, getSubject() 返回一个字符串对象,因此您可以根据需要构造它:
import logging.handlers
import logging
import platform
import os
class TitledSMTPHandler(logging.handlers.SMTPHandler):
def getSubject(self, record):
return f"{record.levelname} [{platform.node()}]: {os.path.basename(__file__)}"
# below is to test
log = logging.getLogger(__name__)
log.addHandler(TitledSMTPHandler(
('your.smtp.server', 587),
'[email protected]',
'[email protected]',
'subject',
('SMTP login', 'SMTP password'),
()
))
log.warning("message")
您可以使用 record 对象中的任何变量并将其包含在电子邮件主题中。