Antoon Pardon wrote: > I have some in house code for which I am considering replacing the > logging code with something that uses the logging module.
> However there is one thing the in-house log code does, that seems > difficult to do with the logging module, provide some context. The > in-house handlers give the possibilty to specify the number of lines of > context the hander can provide. > So the following code: > Logger(fl = stderr, level = warning, context = 2) > > log(INFO, "line 1") > log(INFO, "line 2") > log(INFO, "line 3") > log(INFO, "line 4") > log(WARNING, "line 5") > > Will sent something like the following lines to stderr: > > INFO: line 3 > INFO: line 4 > WARNING: line 5 > > I tried the code below, but that produced the same > as the ordinary StreamHandler. > > class ContextStreamHandler (StreamHandler): > > def __init__(self, stream=None, context = 5): > self.recqueue = deque([], context) > StreamHandler.__init__(self, stream) > #__init__ > > def handle(self, record): > print("CONTEXT HANDLER") > rv = self.filter(record) > if rv: > self.acquire() > try: > for rec in self.recqueue: > self.emit(rec) > self.recqueue.clear() > self.emit(record) > finally: > self.release > else: > self.recqueue.append(record) > return rv > #handle > #ContextStreamHandler It turns out the logic of the above is correct. The problem is that the handler has to see the INFO-level records while the filter() method has to reject them. The following configuration seems to achieve that: import logging from collections import deque class ContextStreamHandler(logging.StreamHandler): def __init__(self, stream=None, context=5): self.record_queue = deque([], context + 1) logging.StreamHandler.__init__(self, stream) def handle(self, record): rv = self.filter(record) self.record_queue.append(record) if rv: self.acquire() try: for record in self.record_queue: self.emit(record) self.record_queue.clear() finally: self.release() return rv class LevelFilter(logging.Filter): def __init__(self, level, name=""): logging.Filter.__init__(self, name) self._filter_level = level def filter(self, record): return record.levelno >= self._filter_level if __name__ == "__main__": root = logging.getLogger() root.setLevel(logging.INFO) handler = ContextStreamHandler(context=2) handler.addFilter(LevelFilter(logging.WARN)) root.addHandler(handler) for i in range(20): if i % 5: root.info("message #%d" % i) else: root.warn("MESSAGE #%d" % i) -- http://mail.python.org/mailman/listinfo/python-list