Python logging, how to filter a specific logger
Asked Answered
P

2

5

It seems a very simple question, but I can't find any good example for me.

I want to filter a logger which has a specific name.

For example

import logging

logging.root.setLevel(logging.DEBUG)
logging.root.addHandler(logging.StreamHandler())
logging.root.addFilter(logging.Filter(name="a"))

a = logging.getLogger("a")
b = logging.getLogger("b")

a.info("aaaaa")
b.info("bbbbb")

I expected that root logger will filters message from b because I understood that logging.Filter only pass the name or childs of the name.

But as you expect it just passes all of the messages.

What is the point I misunderstand?

Phosphorism answered 18/3, 2015 at 15:53 Comment(0)
P
9

As logging documentation states:

events which have been generated by descendant loggers will not be filtered by a logger’s filter setting, unless the filter has also been applied to those descendant logger

If you just want to turn off messages from a sub-logger, you can just set its level:

logging.getLogger("a").setLevel(logging.CRITICAL + 1)
Publia answered 18/3, 2015 at 16:5 Comment(2)
I can't understand unless part, so how do i do to use filter ? could you give me a simple example ?Phosphorism
Set a filter on the handler instead.Stutsman
C
3

I've just been learning this same issue. If you look at flow chart at https://docs.python.org/2.7/howto/logging.html#logging-advanced-tutorial (or read the sentence in the docs, above) you can see that filters on LOGGERS are only applied at initial log event, but NOT when the record is propagated to parent loggers. Because of this, it seems like filters should almost always be applied to handlers and not to loggers.

In your original example, adding your name filter to the stream hander would work as expected.

I expected something like this to work:

class RestFilter(logging.Filter):
    def filter(self,record):
        return '/rest' not in record.msg

# Add the filter to the root logger
logging.getLogger().setFilter(RestFilter())

I thought adding a filter to the root would filter all the records before the record was passed to all the handlers attached to root. But this only filters records that ENTER at the root. I'm curious if any commenters could suggest a rationale for this design.

Casque answered 16/12, 2015 at 20:29 Comment(1)
It helps me. BTW, if you want a filter working for all records logged from one certain logger and its children, you could add a new handler on that logger and apply the filter on the handler.Rachaba

© 2022 - 2024 — McMap. All rights reserved.