問題:
直接配置logging發(fā)送smtp協(xié)議465端口發(fā)送郵件會(huì)出現(xiàn)页眯,如下錯(cuò)誤,如圖:
20190624165933.png
其實(shí)原因就是厢呵,發(fā)送郵件時(shí)直接調(diào)用smtplib中的SMTP方法窝撵,該方法是沒有封裝支持TLS協(xié)議,所以會(huì)出現(xiàn)超時(shí)連接錯(cuò)誤襟铭。
解決方法:
重寫發(fā)送郵件的emit方法
修改前:
def emit(self, record):
"""
Emit a record.
Format the record and send it to the specified addressees.
"""
try:
import smtplib
from email.message import EmailMessage
import email.utils
port = self.mailport
if not port:
port = smtplib.SMTP_PORT
smtp = 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()
except Exception:
self.handleError(record)
修改后:
def emit(self, record):
"""
Overwrite the logging.handlers.SMTPHandler.emit function with SMTP_SSL.
Emit a record.
Format the record and send it to the specified addressees.
"""
try:
import smtplib
from email.utils import formatdate
port = self.mailport
if not port:
port = smtplib.SMTP_PORT
smtp = smtplib.SMTP_SSL(self.mailhost, port, timeout=5)
msg = self.format(record)
msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\nDate: %s\r\n\r\n%s" % (
self.fromaddr, ", ".join(self.toaddrs), self.getSubject(record), formatdate(), msg)
if self.username:
smtp.ehlo()
smtp.login(self.username, self.password)
smtp.sendmail(self.fromaddr, self.toaddrs, msg)
smtp.quit()
except (KeyboardInterrupt, SystemExit):
raise
except:
self.handleError(record)
修改完之后碌奉,直接把原來的方法覆蓋就好了,代碼如下:
handlers.SMTPHandler.emit = emit # 需要導(dǎo)入from logging import handlers模塊
最后問題就解決啦寒砖,可以直接發(fā)送TLS協(xié)議的郵件赐劣。
注:這里是參考了stack overflow的文章https://stackoverflow.com/questions/30770981/logging-handlers-smtphandler-raises-smtplib-smtpauthenticationerror/34003015#34003015