I installed a local SMTP server and used logging.handlers.SMTPHandler
to log an exception using this code:
import logging
import logging.handlers
import time
gm = logging.handlers.SMTPHandler(("localhost", 25), '[email protected]', ['[email protected]'], 'Hello Exception!',)
gm.setLevel(logging.ERROR)
logger.addHandler(gm)
t0 = time.clock()
try:
1/0
except:
logger.exception('testest')
print time.clock()-t0
It took more than 1sec to complete, blocking the python script for this whole time. How come? How can I make it not block the script?
It inherits the output functionality from StreamHandler . Returns a new instance of the FileHandler class. The specified file is opened and used as the stream for logging. If mode is not specified, 'a' is used.
FileHandler sends logging output to a disk file. RotatingFileHandler supports sending logging to a rotation of disk log files.
Here's the implementation I'm using, which I based on this Gmail adapted SMTPHandler.
I took the part that sends to SMTP and placed it in a different thread.
import logging.handlers
import smtplib
from threading import Thread
def smtp_at_your_own_leasure(mailhost, port, username, password, fromaddr, toaddrs, msg):
smtp = smtplib.SMTP(mailhost, port)
if username:
smtp.ehlo() # for tls add this line
smtp.starttls() # for tls add this line
smtp.ehlo() # for tls add this line
smtp.login(username, password)
smtp.sendmail(fromaddr, toaddrs, msg)
smtp.quit()
class ThreadedTlsSMTPHandler(logging.handlers.SMTPHandler):
def emit(self, record):
try:
import string # for tls add this line
try:
from email.utils import formatdate
except ImportError:
formatdate = self.date_time
port = self.mailport
if not port:
port = smtplib.SMTP_PORT
msg = self.format(record)
msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\nDate: %s\r\n\r\n%s" % (
self.fromaddr,
string.join(self.toaddrs, ","),
self.getSubject(record),
formatdate(), msg)
thread = Thread(target=smtp_at_your_own_leasure, args=(self.mailhost, port, self.username, self.password, self.fromaddr, self.toaddrs, msg))
thread.start()
except (KeyboardInterrupt, SystemExit):
raise
except:
self.handleError(record)
Usage example:
logger = logging.getLogger()
gm = ThreadedTlsSMTPHandler(("smtp.gmail.com", 587), 'bugs@my_company.com', ['admin@my_company.com'], 'Error found!', ('[email protected]', 'top_secret_gmail_password'))
gm.setLevel(logging.ERROR)
logger.addHandler(gm)
try:
1/0
except:
logger.exception('FFFFFFFFFFFFFFFFFFFFFFFUUUUUUUUUUUUUUUUUUUUUU-')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With