2014-12-02 1 views
1

파이썬의 로거 smtphandler를 사용하여 오류 및 기타 등등의 이메일을 보내고 싶습니다. 또한받은 편지함에 동일한 버그에 대한 수천 개의 이메일이 넘치고 싶지 않습니다.스로틀 파이썬 smtphandler 이메일

보내는 이메일의 양을 줄이는 방법이 있습니까? 이상적으로 동일한 예외가 계속 발생하면 보내는 이메일의 양을 줄입니다.

답변

1

SMTPHandler에 내 래퍼를 만들었습니다. 첫 번째 초안은 완벽하지 않습니다. 핸들러의 여러 인스턴스는 별도로 중복을 제한합니다. self.logged를 redis로 저장하여 공유 리소스로 만들 수있었습니다.

설정할 필요가있는 유일한 추가 매개 변수는 분 (ints) 목록 인 간격입니다. [0 10 30]이 간격으로 전달된다고 가정하십시오. 지금 이메일을 보내라고 말할 것입니다. 10 분이 경과 할 때까지 이후의 중복은 무시됩니다. 그런 다음 속행은 30 분이 지나야 무시 될 것입니다. 그 후에는 이메일을 보내지 않을 것입니다.

dupe 로그로 간주되는 것을 변경하려면 _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 개가 있습니다.