In any modern programming language, the logging facilities are provided with common features. Similarly, Python's logging module is very rich in features and flexibilities. We can use the different types of log handlers with the logging module, such as the console or the file logging handler. One way in which you can maximize your logging benefits is by e-mailing the log messages to the user just as the log is being produced. Python's logging module provides a type of handler called BufferingHandler,
which is capable of buffering the log data.
An example of extending BufferingHandler
has been displayed later. A child class called BufferingSMTPHandler
is defined by BufferingHandler
. In this example, an instance of the logger object is created by using the logging module. Then, an instance of BufferingSMTPHandler
is tied to this logger object. The logging level is set to DEBUG so that it can log any message. A sample list of four words has been used for creating the four log entries. Each log entry should resemble the following:
<Timestamp> INFO First line of log This accumulated log message will be emailed to a local user as set on top of the script.
Now, let us take a look at the full code. The following is an example of sending an e-mail with the help of the logging module:
import logging.handlers import getpass MAILHOST = 'localhost' FROM = 'you@yourdomain' TO = ['%s@localhost' %getpass.getuser()] SUBJECT = 'Test Logging email from Python logging module (buffering)' class BufferingSMTPHandler(logging.handlers.BufferingHandler): def __init__(self, mailhost, fromaddr, toaddrs, subject, capacity): logging.handlers.BufferingHandler.__init__(self, capacity) self.mailhost = mailhost self.mailport = None self.fromaddr = fromaddr self.toaddrs = toaddrs self.subject = subject self.setFormatter(logging.Formatter("%(asctime)s %(levelname)-5s %(message)s")) def flush(self): if len(self.buffer) > 0: try: import smtplib port = self.mailport if not port: port = smtplib.SMTP_PORT smtp = smtplib.SMTP(self.mailhost, port) msg = "From: %s To: %s Subject: %s " % (self.fromaddr, ",".join(self.toaddrs), self.subject) for record in self.buffer: s = self.format(record) print(s) msg = msg + s + " " smtp.sendmail(self.fromaddr, self.toaddrs, msg) smtp.quit() except: self.handleError(None) # no particular record self.buffer = [] def test(): logger = logging.getLogger("") logger.setLevel(logging.DEBUG) logger.addHandler(BufferingSMTPHandler(MAILHOST, FROM, TO, SUBJECT, 10)) for data in ['First', 'Second', 'Third', 'Fourth']: logger.info("%s line of log", data) logging.shutdown() if __name__ == "__main__": test()
As you can see, our BufferingSMTPHandler
method only overrides one method, that is, flush()
. On the constructor, __init__()
, the basic variable is setup as well as the logging format by using the setFormatter()
method. In the flush()
method, we have created an instance of an SMTP()
object. The SMTP message header has been created by using the data available. The log message has been appended to the e-mail message, and the sendmail()
method has been called to send the e-mail message. The code in the flush()
method is wrapped inside a try-except
block.
The output of the script discussed will be similar to the following:
$ python3 logger_mail_send.py 2014-10-25 13:15:07,124 INFO First line of log 2014-10-25 13:15:07,127 INFO Second line of log 2014-10-25 13:15:07,127 INFO Third line of log 2014-10-25 13:15:07,129 INFO Fourth line of log
Now, when you check the e-mail message with the e-mail command (native to Linux/UNIX machines), you can expect that the e-mail would have been received by the local user, as shown in the following:
$ mail Mail version 8.1.2 01/15/2001. Type ? for help. "/var/mail/faruq": 1 message 1 new >N 1 you@yourdomain Sat Oct 25 13:15 20/786 Test Logging email from Python logging module (buffering)
You can view the content of the message by typing the message ID on the command prompt with &
, as shown in the following output:
& 1 Message 1: From you@yourdomain Sat Oct 25 13:15:08 2014 Envelope-to: faruq@localhost Delivery-date: Sat, 25 Oct 2014 13:15:08 +0100 Date: Sat, 25 Oct 2014 13:15:07 +0100 From: you@yourdomain To: faruq@localhost Subject: Test Logging email from Python logging module (buffering) 2014-10-25 13:15:07,124 INFO First line of log 2014-10-25 13:15:07,127 INFO Second line of log 2014-10-25 13:15:07,127 INFO Third line of log 2014-10-25 13:15:07,129 INFO Fourth line of log
Finally, you can quit the mail program by typing the shortcut q
on the command prompt, as shown here:
& q Saved 1 message in /home/faruq/mbox