1

I'm writing a large hardware simulation library in Python3. For logging, I use the Python3 Logging module.

For controlling debug messages with method-level granularity, I learned "on the street" (ok, here at StackOverflow) to create sub-loggers within each method I wanted to log from:

sub_logger = logging.getChild("new_sublogger_name") sub_logger.setLevel(logging.DEBUG) # Sample debug message sub_logger.debug("This is a debug message...") 

By changing the call to setLevel(), the user is able to enable/disable debugging messages on a per-method basis.

Now the Boss Man don't like this approach. He's advocating a single-point at which all logging messages in the library can be enabled/disabled with the same method-level granularity. (This was to be accomplished by writing our own Python logging library BTW).

Not wanting to re-invent the logging wheel, I proposed to instead continue to use the Python Logging library, but instead use Filters to allow single-point control of logging messages.

Having not used Python Logging Filters very often, is there a consensus on using Filters vs Sublogger.setLevel() for this application? What are the pros/cons of each method?

I'm quite used to setLevel() after using it for a while, but that may be coloring my objectiveness. I DO NOT, however, wish to waste everyone's time writing another Python logging library.

1

1 Answer 1

4

I think the existing logging module does what you want. The trick is to separate the place where you call setLevel() (a configuration operation) from the places where you call getChild() (ongoing logging operations).

import logging logger = logging.getLogger('mod1') def fctn1(): logger.getChild('fctn1').debug('I am chatty') # do stuff (notice, no setLevel) def fctn2(): logger.getChild('fctn2').debug('I am even more chatty') # do stuff (notice, no setLevel) 

Notice there was no setLevel() there, which makes sense. Why call setLevel() every time and since when does a method know what logging level the user wants.

You set your logging levels in a configuration step at the beginning of the program. You can do it with the dictionary based configuration, a python module that does a bunch of setLevel() calls or even something you cook up with ini files or whatever. But basically it boils down to:

def config_logger(): logging.getLogger('abc.def').setLevel(logging.INFO) logging.getLogger('mod1').setLevel(logging.WARN) logging.getLogger('mod1.fctn1').setLeveL(logging.DEBUG) (etc...) 

Now, if you want to get fancy with filters, you can use them to inspect the stack frame and pull the method name out for you. But that gets more complicated.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for that idea. I'll see if I can easily integrate it into my current system. Thanks!
I've played around with this approach and the drawback I see is that I must specifically set the level for each logger in config_logger(). How could I instead say, "Be quiet unless you are specifically enabled in config_logger()?
@JS - log levels are inherited. What you add at the root affects all loggers unless they are overridden. In general, what you set at a.b affects its children (a.b.c, a.b.c.d, etc...). logging.getLogger('').setLevel(logging.FATAL) keeps the chatter down.
BINGO! THAT's the aspect I've been missing! Thank you so very much!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.