2014-12-02 74 views
1

我想使用Python的記錄器smtphandler發送錯誤和whatnot電子郵件。我也不想讓我的收件箱裏充斥着數以千計的電子郵件,以解決相同的問題。Throttle Python smtphandler電子郵件

有沒有辦法來限制發送的電子郵件數量?理想情況下,如果它始終捕獲相同的異常,請減少發送的電子郵件數量。

回答

1

我最終制作了自己的SMTPHandler包裝器。初稿如此不完美。處理程序的多個實例將分別限制dupe。可以在redis中存儲self.logged以使其成爲共享資源。

需要設置的唯一額外參數是時間間隔,它是分鐘(整數)的列表。假設[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) 
0

你可以看看mailinglogger包,它看起來像你所需要的。 This part of documentation解釋設置限制以防止洪水。即使沒有設置任何東西,它每小時有合理的默認10封電子郵件:)