from logging.handlers import BufferingHandler class LogHandler(BufferingHandler): def __init__(self, matcher): # BufferingHandler takes a "capacity" argument # so as to know when to flush. As we're overriding # shouldFlush anyway, we can set a capacity of zero. # You can call flush() manually to clear out the # buffer. super(LogHandler, self).__init__(0) self.matcher = matcher def shouldFlush(self, **kwargs): return False def emit(self, record): self.buffer.append(record.__dict__) def matches(self, **kwargs): """ Look for a saved dict whose keys/values match the supplied arguments. """ result = False for d in self.buffer: if self.matcher.matches(d, **kwargs): result = True break return result class Matcher(object): _partial_matches = ('msg', 'message') def matches(self, d, **kwargs): """ Try to match a single dict with the supplied arguments. Keys whose values are strings and which are in self._partial_matches will be checked for partial (i.e. substring) matches. You can extend this scheme to (for example) do regular expression matching, etc. """ result = True for k in kwargs: v = kwargs[k] dv = d.get(k) if not self.match_value(k, dv, v): result = False break return result def match_value(self, k, dv, v): """ Try to match a single stored value (dv) with a supplied value (v). """ if type(v) != type(dv): result = False elif type(dv) is not str or k not in self._partial_matches: result = (v == dv) else: result = dv.find(v) >= 0 return result