How To/python/

Using GMail SMTP server with logging module

What's wrong?

You cannot use gmail account for sending emails with logging module. It is because google requires TLS connection and logging module doesn't support it.

Solution

To use gmail you have to extend logging.handlers.SMTPHandler class and override SMTPHandler.emit() method. Here is source code. There really should be option to add user comments on pythons documentation pages!

import logging
import logging.handlers
 
class TlsSMTPHandler(logging.handlers.SMTPHandler):
    def emit(self, record):
        """
        Emit a record.
 
        Format the record and send it to the specified addressees.
        """
        try:
            import smtplib
            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
            smtp = smtplib.SMTP(self.mailhost, 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)
            if self.username:
                smtp.ehlo() # for tls add this line
                smtp.starttls() # for tls add this line
                smtp.ehlo() # for tls add this line
                smtp.login(self.username, self.password)
            smtp.sendmail(self.fromaddr, self.toaddrs, msg)
            smtp.quit()
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.handleError(record)
 
logger = logging.getLogger()
 
gm = TlsSMTPHandler(("smtp.gmail.com", 587), 'bugs@my_company.com', ['admin@my_company.com'], 'Error found!', ('my_company_account@gmail.com', 'top_secret_gmail_password'))
gm.setLevel(logging.ERROR)
 
logger.addHandler(gm)
 
try:
    1/0
except:
    logger.exception('FFFFFFFFFFFFFFFFFFFFFFFUUUUUUUUUUUUUUUUUUUUUU-')

Email output:

FFFFFFFFFFFFFFFFFFFFFFFUUUUUUUUUUUUUUUUUUUUUU-
Traceback (most recent call last):
  File "c:\users\mynth\temp\le_fu.py", line 50, in <module>
    1/0
ZeroDivisionError: integer division or modulo by zero