1

I use the following code in my __init__ class:

# Create a custom logger
self.logger = logging.getLogger(__name__)

# Create handlers
self.handler_cmdline = logging.StreamHandler()
self.handler_file = logging.FileHandler(self.logfile)
self.handler_cmdline.setLevel(logging.DEBUG)
self.handler_file.setLevel(logging.INFO)

# Create formatters and add it to handlers
log_format = logging.Formatter(fmt='%(asctime)s - %(name)s - %(<levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
self.handler_cmdline.setFormatter(log_format)
self.handler_file.setFormatter(log_format)

# Add handlers to the logger
self.logger.addHandler(self.handler_cmdline)
self.logger.addHandler(self.handler_file)

self.logger.debug('Initialisation Complete')
self.logger.info('Initialisation Complete')
self.logger.warning('Initialisation Complete')
self.logger.critical('Initialisation Complete')

The debug and the warning don't work somehow. Everything from warning and above works.

What's wrong here?

vvvvv
  • 25,404
  • 19
  • 49
  • 81
smyril
  • 111
  • 10

1 Answers1

1
import logging

class example():
       def __init__(self):
              self.logger = logging.getLogger(__name__)
              self.logfile = 'example.log'

              # Create handlers
              self.handler_cmdline = logging.StreamHandler()
              self.handler_file = logging.FileHandler(self.logfile)
              self.handler_cmdline.setLevel(logging.DEBUG)
              self.handler_file.setLevel(logging.INFO)


              # Create formatters and add it to handlers
              log_format = logging.Formatter(fmt='%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
              self.handler_cmdline.setFormatter(log_format)
              self.handler_file.setFormatter(log_format)

              # Add handlers to the logger
              self.logger.addHandler(self.handler_cmdline)
              self.logger.addHandler(self.handler_file)
              self.logger.setLevel(logging.DEBUG)
              # print(self.logger.level)

              self.logger.debug('Initialisation Complete')
              self.logger.info('Initialisation Complete')
              self.logger.warning('Initialisation Complete')
              self.logger.critical('Initialisation Complete')

example()

Small snippet to test the fix with your code, the issue is that your logger does not have a level set. Because of which default level is used which causes the INFO and DEBUG levelled logs to be ignored. You can try printing the self.logger.level to see what level it is currently set to.

In your case, you did not have logging level set for your self.logger.

Just adding the self.logger.setLevel(logging.DEBUG) fixes the issue. And you can see this output in the console -

2022-12-12 17:44:23 - __main__ - DEBUG - Initialisation Complete
2022-12-12 17:44:23 - __main__ - INFO - Initialisation Complete
2022-12-12 17:44:23 - __main__ - WARNING - Initialisation Complete
2022-12-12 17:44:23 - __main__ - CRITICAL - Initialisation Complete

while in the file, the debug log would not be there, because of the logging level of the file handler being INFO.

The level of the logger should be minimum of the level of the log handlers of that logger, else those logs would not be logged.(e.g. in this case, if you set the logger level to INFO, the debug log will not be printed in stdout either, even though the log handler has its level set to DEBUG.

Jay
  • 2,431
  • 1
  • 10
  • 21
  • do you mean that I set levels for each handler but not for the logger itself? because it works now that I added `self.logger.setLevel(logging.DEBUG)` – smyril Dec 12 '22 at 12:28
  • 1
    Yeah, and in the NOTSET level(corresponding to 0 when printed) the logger doesn't print anything below WARNING. – Jay Dec 12 '22 at 12:30
  • Thank you very much! follow up question: why does it work like it did without your fix if i add `self.logger.setLevel(logging.NONSET)` (instead of DEBUG)? – smyril Dec 12 '22 at 12:33
  • 1
    Check this out - https://stackoverflow.com/questions/21494468/about-notset-in-python-logging – Jay Dec 12 '22 at 12:34
  • 1
    When something is logged at a specific level(say DEBUG for example), first logger's level is checked, if the logger level is set to be higher than the logged level, then for each log handler(if the level is set then it is checked), if log handler level is also lower than logged level then log is logged. Without setting the logger level in your case, the first check itself(logger level) was failing hence log handler level wont' be checked even if it is higher than the logged level. – Jay Dec 12 '22 at 12:36