有没有办法在Python中配置SMTPHandler来做更多高级的东西?

时间:2012-02-10 22:57:52

标签: python exception-handling smtp logging

我正在使用标准的SMTPHandler记录器来捕获我的Python异常。 有没有办法将异常名称放入邮件主题?这比静态主题要好得多,因为Gmail(而不仅仅是Gmail)可以根据主题对对话进行分组等等可以根据错误的类型对其进行分组。

例如,如果50个完全相同的错误发生+ 1个不同,我会在收件箱中看到两个对话而不是一个包含51封电子邮件的组,我可以很容易地忽略单个不同的对话。

另外,有没有办法防止发送相同的错误? E. g。以某种方式定义我自己的功能决定是否要发送电子邮件。该函数将在params中获取一些基本信息,以便它可以决定(例如缓存并查看是否已发送此类问题)。

我浏览了文档,但我无法找到类似的内容。这似乎很简单。 如果SMTPHandler无法做到这一点,那么最好还是简单的替代方案是什么?任何整洁的库?

谢谢!

3 个答案:

答案 0 :(得分:7)

您只需要创建自己的SMTPHandler子类。

第一次请求:您只需要覆盖getSubject(record)方法。至于您可以在主题中添加什么,请在从日志记录中导入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)

答案 1 :(得分:1)

简单灵活的方式是不仅格式化电子邮件内容,还格式化电子邮件主题。这需要子类化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@from.address', 'email@to.address', 
        '%(asctime)s Error: %(message)s', 
        ('SMTP login', 'SMTP password'), ()
    ))

    logging.error("TestError")

将SMTP配置替换为您的配置,运行代码,您应该收到一封错误消息在主题中的电子邮件(也在电子邮件正文中)。

如果在日志记录配置文件中定义处理程序,请记住转义参数引用。例如%(asctime)s应该变为%%(asctime)s,以防止configparser的过早插值 - 但%%转义在python 3.1之前和之前都没有。{/ p>


如果您一次提出一个问题,请帮助其他Google员工。您应该开始两个主题,一个叫做“有没有办法将异常名称放入邮件主题?”而另一个“有没有办法防止发送相同的错误?”

我只会回答您的第一个问题,以便专注于一个主题。也许你认为这两个问题可能是相互依赖的,因此必须一起询问,而它们只是一起出现在你的脑海中。我认为建议您更改问题的标题以强调一个问题,而不是说“高级内容”,这仍然是可行的。

我还建议访问comp.lang.python,如果问题是一个开放主题和/或无法明确定义(例如“我想要高级内容,其他人使用什么?”)

答案 2 :(得分:0)

您可以继承SMTPHandler类并增强或替换其功能,例如

class A(object):
    def __init__(self):
        self.email = "jjj@jjj.com"

    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