Re: Making a logging handler that produces context.

Discussion in 'Python' started by Peter Otten, Jan 14, 2013.

  1. Peter Otten

    Peter Otten Guest

    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)
     
    Peter Otten, Jan 14, 2013
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. VS_NET_DEV
    Replies:
    2
    Views:
    3,807
    jenny
    May 25, 2004
  2. =?Utf-8?B?U3VuU21pbGU=?=
    Replies:
    0
    Views:
    709
    =?Utf-8?B?U3VuU21pbGU=?=
    Jan 10, 2006
  3. Gal Aviel
    Replies:
    1
    Views:
    462
    Gerard Flanagan
    Mar 4, 2008
  4. Antoon Pardon
    Replies:
    0
    Views:
    136
    Antoon Pardon
    Jan 14, 2013
  5. Antoon Pardon
    Replies:
    0
    Views:
    135
    Antoon Pardon
    Jan 14, 2013
Loading...

Share This Page