有没有办法在Python中配置SMTPHandler来做更高级的事情?

问题描述 投票:0回答:4

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

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

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

我浏览了文档,但找不到类似的内容。似乎很简单。 如果 SMTPHandler 不能做到这一点,那么最好且仍然简单的替代方案是什么? 有任何简洁的库吗?

谢谢!

python exception smtp logging
4个回答
9
投票

您只需创建自己的 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)

2
投票

简单灵活的方法是不仅格式化电子邮件内容,还格式化电子邮件主题。这需要子类化

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


0
投票

您可以继承 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

0
投票

首先,我建议使用您自己的记录器,而不是根记录器。 我还想指出, 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 对象中的任何变量并将其包含在电子邮件主题中。

© www.soinside.com 2019 - 2024. All rights reserved.