Example of Modifying the Logging Module


NOTE: This is just an example of what you can do with the logging module. For zope, just initializing this code somewhere in the system (i.e. __init__.py) will make it apply to every call to logging.*

 

'''

LOGGING CONFIG

We want to have a little bit of logging customization here

such that all bad errors get emailed to someone

'''

import logging

import logging.handlers

from logging.handlers import MemoryHandler

logging.basicConfig(level=logging.DEBUG,

                    format='%(asctime)s %(levelname)s @%(pathname)s/%(filename)s %(module)s %(lineno)d  : %(message)s ',

                    filename='/var/log/mysite.log',

                    filemode='a')

 

# who gets stuck reading these

SYSTEM_WHORE = ['support@mysite.com']

# who are all these emails from?

BIG_WHINER = 'errors@mysite.com'

# the mail server that will be sending all this mail

TOOL_OF_DELIVERER_OF_BAD_NEWS = '10.0.x.xxx'

def patchLogger():

    bufferHandler = MyLoggingHandler(capacity=25, flushLevel=logging.CRITICAL)

    logger = logging.getLogger()

 

    # check to see if this logger has this handler

    # since we don't want to accidentally have multiple smtp handlers

    # and get multiple copies of the same meassages

    alreadyPatched = False

    for currentHandler in logger.handlers:

        if isinstance(currentHandler, MyLoggingHandler):

            alreadyPatched = True

            break

 

    if not alreadyPatched:

        logger.addHandler(bufferHandler)

 

# batch up email requests and send as one

class MyLoggingHandler(MemoryHandler):

    def __init__(self, **kwargs):

        MemoryHandler.__init__(self, **kwargs)

        self.setFormatter(logging.Formatter('%(asctime)s %(levelname)s @%(pathname)s/%(filename)s %(module)s %(lineno)d  : %(message)s'))

        mailHandler = logging.handlers.SMTPHandler( TOOL_OF_DELIVERER_OF_BAD_NEWS,

                                            BIG_WHINER,

                                            SYSTEM_WHORE,

                                            'ERROR logged in the network: Please Investigate')

        self.setTarget(mailHandler)

        self.addFilter(LevelFilter(logging.ERROR))           

 

    def flush(self):

        '''

        Make one message to send instead of gagilliogns

        '''

        sendMe = ""

        for record in self.buffer:

            sendMe += "\n-----------------------------------\n"

            sendMe += self.format(record)

            sendMe += "\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"

 

        self.buffer = []

        if sendMe: # there are utilities thtat could potentially send empty error messages

            newRecord = logging.LogRecord('root', logging.ERROR, '', '', sendMe, None, None)

            if self.target:

                self.target.handle(newRecord)

 

class LevelFilter(logging.Filter):

    def __init__(self, level):

        self.level = level

    def filter(self, record):

        return self.level == record.levelno