【问题标题】:Throttle Python smtphandler emails限制 Python smtphandler 电子邮件
【发布时间】:2015-01-30 03:44:29
【问题描述】:

我想使用 Python 的记录器 smtphandler 发送电子邮件以查找错误等。我也不想让我的收件箱因为同一个错误而充斥着数千封电子邮件。

有没有办法限制发送的电子邮件数量?理想情况下,如果它不断捕获相同的异常,则减少发送的电子邮件数量。

【问题讨论】:

    标签: python logging smtp postfix-mta


    【解决方案1】:

    我最终为 SMTPHandler 制作了自己的包装器。初稿并不完美。处理程序的多个实例将分别限制欺骗。可以将self.logged存储在redis中,使其成为共享资源。

    唯一需要设置的额外参数是间隔,它是分钟列表(整数)。假设 [0 10 30] 被传递给区间。它会说现在发送电子邮件。随后的欺骗将被忽略,直到 10 分钟过去。然后后续的欺骗将被忽略,直到 30 分钟之后。之后它不会发送任何电子邮件。

    如果您想更改被视为重复日志的内容,请根据您的要求修改 _record_type。

    import logging.handlers
    import datetime
    
    
    class SMTPHandler(logging.handlers.SMTPHandler):
        """
        Custom SMTPHandler for the logger.
    
        You specify the intervals to which emails will be sent.  At most the number
        of emails that will be sent will be equal to the number of intervals set.
        """
    
        def __init__(self, mailhost, fromaddr, toaddrs, subject, intervals,
                     credentials=None, secure=None, timeout=5.0):
            super(SMTPHandler, self).__init__(mailhost, fromaddr, toaddrs, subject,
                                              credentials, secure, timeout)
            self.logged = {}
            self.init_date = datetime.datetime.now()
            self.intervals = self._make_intervals(intervals)
    
        def _make_intervals(self, intervals):
            return [datetime.timedelta(minutes=i) for i in intervals]
    
        def _record_type(self, record):
            """Make key from LogRecord"""
            type = record.levelname + record.pathname
            if record.exc_info:
                type = type + str(record.exc_info[0])
            return type
    
        def update(self, record):
            """Check if a similar log has been emitted, if so how many times and has specified interval passed"""
            record_type = self._record_type(record)
            last = self.logged.get(record_type)
            # log if hasn't been logged at all
            if last is None:
                self.logged[record_type] = (1, datetime.datetime.now())
                return True
            # log if last log was more than a specified interval before
            else:
                count, last_date = last
                if count <= len(self.intervals):
                    if (last_date - self.init_date) > self.intervals[count]:
                        self.logged[record_type] = (count+1, datetime.datetime.now())
                        return True
                    else:
                        return False
                else:
                    return False
    
        def emit(self, record):
            emittable = self.update(record)
            if emittable is True:
                super(SMTPHandler, self).emit(record)
    

    【讨论】:

      【解决方案2】:

      您可以查看mailinglogger 包,它看起来像您需要的。 This part of documentation 解释了设置限制以防止洪水泛滥。即使没有设置任何东西,它也有合理的默认每小时 10 封电子邮件:)

      【讨论】:

        猜你喜欢
        • 2021-06-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-23
        相关资源
        最近更新 更多