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} \033[0;35m!!!请去邮箱检查,可能在垃圾邮件中\033[0m')
self._msg_map[record.msg] = time.time()
except Exception:
self.handleError(record)
else:
pass
print(f'[log_manager.py] 邮件发送太频繁,此次不发送这个邮件内容: {record.msg} ')

python日志,一个改版SMTPHandler的更多相关文章

  1. python日志按天分割,保存近一个月日志,日志自动清理

    python日志按天分割,保存近一个月日志 import os import logging import re from logging.handlers import TimedRotatingF ...

  2. python日志模块logging学习

    介绍 Python本身带有logging模块,其默认支持直接输出到控制台(屏幕),或者通过配置输出到文件中.同时支持TCP.HTTP.GET/POST.SMTP.Socket等协议,将日志信息发送到网 ...

  3. Python日志输出——logging模块

    Python日志输出——logging模块 标签: loggingpythonimportmodulelog4j 2012-03-06 00:18 31605人阅读 评论(8) 收藏 举报 分类: P ...

  4. python日志模块logging

    python日志模块logging   1. 基础用法 python提供了一个标准的日志接口,就是logging模块.日志级别有DEBUG.INFO.WARNING.ERROR.CRITICAL五种( ...

  5. 浅析python日志重复输出问题

    浅析python日志重复输出问题 问题起源: ​ 在学习了python的函数式编程后,又接触到了logging这样一个强大的日志模块.为了减少重复代码,应该不少同学和我一样便迫不及待的写了一个自己的日 ...

  6. python 日志打印之logging使用介绍

    python 日志打印之logging使用介绍 by:授客QQ:1033553122 测试环境: Python版本:Python 2.7   简单的将日志打印到屏幕 import logging lo ...

  7. 用Python编写一个简单的Http Server

    用Python编写一个简单的Http Server Python内置了支持HTTP协议的模块,我们可以用来开发单机版功能较少的Web服务器.Python支持该功能的实现模块是BaseFTTPServe ...

  8. Python 日志输出中添加上下文信息

    Python日志输出中添加上下文信息 除了传递给日志记录函数的参数(如msg)外,有时候我们还想在日志输出中包含一些额外的上下文信息.比如,在一个网络应用中,可能希望在日志中记录客户端的特定信息,如: ...

  9. python日志模块笔记

    前言 在应用中记录日志是程序开发的重要一环,也是调试的重要工具.但却很容易让人忽略.之前用flask写的一个服务就因为没有处理好日志的问题导致线上的错误难以察觉,修复错误的定位也很困难.最近恰好有时间 ...

随机推荐

  1. android:Button控件

    Button 是程序用于和用户进行交互的一个重要控件,相信你对这个控件已经是非常熟悉 了,因为我们在上一章用了太多次 Button.它可配置的属性和 TextView 是差不多的,我们 可以在 act ...

  2. 使用JCOOKIES创建http cookie

    jCookies,一个功能强大的操作http cookie的jquery插件,他能够让你存储任何数据类型如:字符串,数组,对象等.它通过JavaScript存储Cookies,然后通过服务器端代码如: ...

  3. 序列化与反序列化的单例模式实现和readResolve()【转】

    如: public class SingleTest implements Serializable{private static final long serialVersionUID = -860 ...

  4. wcstombs_s 宽字节转多字节

    // crt_wcstombs_s.c // This example converts a wide character // string to a multibyte character str ...

  5. PC高级语言与施耐德、罗克韦尔、台达等PLC的Modbus通讯源代码(ModbusTCP.DLL/ModbusRTU.DLL)

    1.0  通讯组件概述 该类通讯组件适用于基于PC高级语言的工业自动化控制系统,用于PC与可编程控制器(PLC).智能仪表等进行数据通讯.组件采用动态链接库文件(*.DLL)的形式,在PC系统的项目工 ...

  6. vim 正则替换功能

    最近使用vim的正则替换功能,非常强大 一个文件: ,, ,, ,, ,, ,, ,, ,, ,, ,, ,, 现在需要删除逗号前面的内容,那么在vim敲入命令: :%s/.*,//g 得到的结果是: ...

  7. VS2017不能打开stdio.h等文件

    从另一台机器上复制过来的项目,由于两台机器的库目录不一致,导致了stdio.h等很多文件都打不开: 解决的办法是从新设置包含目录.选择项目-->%项目名称%属性-->VC++目录,设置包含 ...

  8. Python中结巴分词使用手记

    手记实用系列文章: 1 结巴分词和自然语言处理HanLP处理手记 2 Python中文语料批量预处理手记 3 自然语言处理手记 4 Python中调用自然语言处理工具HanLP手记 5 Python中 ...

  9. html元素不可见的三种方式

    html中使元素不可见有三种方法: 使用hidden属性 使用style中的display=none 使用style中的visibility=false 显然,使元素不可见有两类方式: 元素彻底不可见 ...

  10. Benchmark Web App 性能瓶颈分析与性能测试工具的使用方法总结

    主要分为以下几个要素的指标: Disk IO . CPU . mem . Net . MySQL Web性能测试工具: 客户端 服务器端: 服务器性能测试工具: 服务器性能瓶颈分析工具: ab, si ...