zoukankan      html  css  js  c++  java
  • python日志,一个改版SMTPHandler

    1、官方logging包的SMTPHandler不支持ssl的邮箱,修改成兼容ssl以支持大部分国内邮箱。

    2、增加一个频率控制的参数,比如要设置一个报警邮件,异常时候通知我们,但假设1分钟内异常几千次,那是不需要发几千次相同日志的,handler自带频率限制,使用的时候一秒钟调用运行logger.waning('某某报警')几万次都没问题,直接自动忽略相同内容的报警信息,不会发送邮件。

     3、发邮件时候另开线程,发邮件是需要一段时间的,运气不好时候发邮件需要两三秒,把主线程阻塞两三秒了,另开线程不会有阻塞。

    修改成如下:

    class CompatibleSMTPSSLHandler(handlers.SMTPHandler):
        """
        官方的SMTPHandler不支持SMTP_SSL的邮箱,这个可以两个都支持,并且支持邮件发送频率限制
        """
    
        def __init__(self, mailhost, fromaddr, toaddrs: tuple, subject,
                     credentials=None, secure=None, timeout=5.0, is_use_ssl=True, mail_time_interval=0):
            """
    
            :param mailhost:
            :param fromaddr:
            :param toaddrs:
            :param subject:
            :param credentials:
            :param secure:
            :param timeout:
            :param is_use_ssl:
            :param mail_time_interval: 发邮件的时间间隔,可以控制日志邮件的发送频率,为0不进行频率限制控制,如果为60,代表1分钟内最多发送一次邮件
            """
            super().__init__(mailhost, fromaddr, toaddrs, subject,
                             credentials, secure, timeout)
            self._is_use_ssl = is_use_ssl
            self._time_interval = mail_time_interval
            self._msg_map = dict()  # 是一个内容为键时间为值得映射
    
        def emit(self, record: logging.LogRecord):
            """
            Emit a record.
    
            Format the record and send it to the specified addressees.
            """
            from threading import Thread
            if sys.getsizeof(self._msg_map) > 10 * 1000 * 1000:
                self._msg_map.clear()
            Thread(target=self.__emit, args=(record,)).start()
    
        def __emit(self, record):
            if record.msg not in self._msg_map or time.time() - self._msg_map[record.msg] > self._time_interval:
                try:
                    import smtplib
                    from email.message import EmailMessage
                    import email.utils
                    t_start = time.time()
                    port = self.mailport
                    if not port:
                        port = smtplib.SMTP_PORT
                    smtp = smtplib.SMTP_SSL(self.mailhost, port, timeout=self.timeout) if self._is_use_ssl else smtplib.SMTP(self.mailhost, port, timeout=self.timeout)
                    msg = EmailMessage()
                    msg['From'] = self.fromaddr
                    msg['To'] = ','.join(self.toaddrs)
                    msg['Subject'] = self.getSubject(record)
                    msg['Date'] = email.utils.localtime()
                    msg.set_content(self.format(record))
                    if self.username:
                        if self.secure is not None:
                            smtp.ehlo()
                            smtp.starttls(*self.secure)
                            smtp.ehlo()
                        smtp.login(self.username, self.password)
                    smtp.send_message(msg)
                    smtp.quit()
                    print(f'[log_manager.py]  发送邮件给 {self.toaddrs} 成功,用时{round(time.time() - t_start,2)} ,发送的内容是--> {record.msg}                    33[0;35m!!!请去邮箱检查,可能在垃圾邮件中33[0m')
                    self._msg_map[record.msg] = time.time()
                except Exception:
                    self.handleError(record)
            else:
                pass
                print(f'[log_manager.py]  邮件发送太频繁,此次不发送这个邮件内容: {record.msg}    ')
  • 相关阅读:
    Java异常处理
    冒泡排序法
    21个项目-MNIST机器学习入门
    Hadoop集群搭建中ssh免密登录
    利用奇异值分解简化数据
    数据集中空值替换成对应特征的平均值
    PCA降维处理
    使用FP-growth算法高效发现频繁项集
    原生js---ajax---post方法传数据
    原生js---ajax---get方法传数据
  • 原文地址:https://www.cnblogs.com/ydf0509/p/9752210.html
Copyright © 2011-2022 走看看