Saturday 24 November 2012

Constant logging

In the upcoming 1.0 release of Whyteboard, there is substantial logging across the program. This can help track down bugs when users report crashes from the program's internal error catching dialog. Whyteboard can now submit a log of the user's actions leading up to the crash as well as the stack trace. I needed the program to operate in several view states: it's always in debug mode but the debugging may not always be visible. I had to create a custom log handler to allow me to 'save' every log message in order to attach it to the error email.
from collections import deque
from logging import StreamHandler, DEBUG
from time import gmtime, strftime

class LogRemembererHandler(StreamHandler):
    '''
    A custom log handler that remembers the last x many logs sent to it
    for retrieving log messages (in this case, we want to fetch the logs 
    if the program crashes)
    '''
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(LogRemembererHandler, cls).__new__(cls, *args, **kwargs)
            cls._instance.logs = deque(maxlen=101)            
        return cls._instance
    
    def emit(self, record):
        self.format(record)
        time = strftime("%d/%m/%Y %H:%M:%S", gmtime(record.created))
        self.logs.append(u"%s: %s" % (time, record.message))
        
    def get_logs(self):
        return self.logs
and to use:
        formatter = logging.Formatter('%(levelname)s %(asctime)s %(message)s')
        handler.setFormatter(formatter)
        logger.addHandler(handler)


...


        LogRemembererHandler().get_logs()

No comments:

Post a Comment