-1

I have been experimenting with Python's logging module for a while. And I have most of the basics pretty much working. However, I hit a wall at the point where I wanted to control the levels for the logger.

Here is a representation of the logging behaviour that I am trying to implement:

if verbosityState == 0:
    # Total silence
elif verbosityState == 1:
    # Display only INFO, ERROR, CRITICAL
elif verbosityState == 2:
    # Display INFO, DEBUG, ERROR, CRITICAL
elif verbosityState > 2:
    # Display INFO, DEBUG, ERROR, CRITICAL, WARNING
else:
   # Total silence

I have found the following solution, here on stackoverflow, and it involves inheriting the FILTER class and creating a custom filter. Unfortunately I was not able to adapt it to my case.

Could you please help me with this?

Thanks.

Community
  • 1
  • 1
mbilyanov
  • 2,315
  • 4
  • 29
  • 49
  • From the documentation you simply import logging and instanciate the Logger class ( which I assume you did) and then use Logger.setLevel(lvl) – gkusner Jun 23 '14 at 16:35
  • @gkusner Thanks. Yeah, but with the default setting you cannot have a non-default behaviour. With level INFO, you get INFO, WARNING, ERROR and CRITICAL. With DEBUG, you get everything. With WARNING you get WARNING, ERROR, CRITICAL. I am trying to add and remove level components. – mbilyanov Jun 23 '14 at 16:42
  • You need to show exactly what you tried - "I was not able to adapt it" doesn't give enough information. – Vinay Sajip Jun 23 '14 at 16:48
  • Well, I tried to adapt the class in the linked solution, just like dank did, but my logic was wrong, and I forgot about the removeFilter method so I was constantly overwriting my filter. – mbilyanov Jun 23 '14 at 17:06

1 Answers1

1

You can use a custom Filter, just like the answer you linked to:

class CustomFilter(logging.Filter):
    def __init__(self, state):
        self.state = state

    def filter(self, record):
        if self.state == 1:
            return record.levelno in [logging.INFO, logging.ERROR, 
                                      logging.CRITICAL]
        elif self.state == 2:
            return record.levelno in [logging.INFO, logging.DEBUG, 
                                      logging.ERROR, logging.CRITICAL]
        elif self.state > 2:
            return record.levelno in [logging.INFO, logging.DEBUG, 
                                      logging.ERROR, logging.CRITICAL, 
                                      logging.WARNING]
        else:
            return False


h1 = logging.StreamHandler(sys.stdout)
logger = logging.getLogger("my.logger")
logger.setLevel(logging.DEBUG)
print("No logging:")
f1 = CustomFilter(0)
h1.addFilter(f1)
logger.addHandler(h1)
logger.info("info")
logger.debug("debug")
logger.error("error")
logger.warning("warning")
logger.critical("critical")
print ("Level 1:")
h1.removeFilter(f1)
f1 = CustomFilter(1)
h1.addFilter(f1)
logger.addHandler(h1)
logger.info("info")
logger.debug("debug")
logger.error("error")
logger.warning("warning")
logger.critical("critical")
print("Level 2:")
h1.removeFilter(f1)
logger.removeHandler(h1)
f1 = CustomFilter(2)
h1.addFilter(f1)
logger.addHandler(h1)
logger.info("info")
logger.debug("debug")
logger.error("error")
logger.warning("warning")
logger.critical("critical")
print("Level 3:")
h1.removeFilter(f1)
logger.removeHandler(h1)
f1 = CustomFilter(3)
h1.addFilter(f1)
logger.addHandler(h1)
logger.info("info")
logger.debug("debug")
logger.error("error")
logger.warning("warning")
logger.critical("critical")

Output:

No logging:
Level 1:
info
error
critical
Level 2:
info
debug
error
critical
Level 3:
info
debug
error
warning
critical
dano
  • 91,354
  • 19
  • 222
  • 219
  • Thanks, this works. I am still not very comfortable with class inheritance and overriding the methods. Also `return record.levelno in []` is a nice solution. Thank you very much. – mbilyanov Jun 23 '14 at 17:08