0

I have following code in my colab notebook:

# Cell 1
import logging


# Cell 2
class MyClass:
  def __init__(self):
    self.configureLogger()
    self.fileLogger.info('info log to file')
    self.consoleLogger.debug('debug log to console')    

  def configureLogger(self):
    # https://stackoverflow.com/a/56144390/6357916
    # logging.basicConfig(level=logging.NOTSET)
    self.fileLogger = logging.getLogger('fileLogger2')
    if not self.fileLogger.hasHandlers():
        self.fileLogger.setLevel(logging.INFO)
        formatter1 = logging.Formatter("%(asctime)s,%(message)s")
        file_handler = logging.FileHandler('log.txt')
        file_handler.setLevel(logging.INFO)
        file_handler.setFormatter(formatter1)
        self.fileLogger.addHandler(file_handler)

    self.consoleLogger = logging.getLogger('consoleLogger2')
    if not self.consoleLogger.hasHandlers():
        self.consoleLogger.setLevel(logging.DEBUG)
        formatter2 = logging.Formatter("%(message)s")
        console_handler = logging.StreamHandler()
        console_handler.setFormatter(formatter2)
        self.consoleLogger.addHandler(console_handler)

c = MyClass()

There MyClass has a method called configureLogger() which configures two loggers:

  1. fileLogger: logs to file
  2. consoleLogger: logs t console

MyClass.__init__() call this method and uses both of these loggers to log single message each. But nothing gets logged to console. Nor does log.txt file gets created.

I am expecting it to log debug log to console to console and info log to file to file. This is how it is behaving on my local machine, but fails on colab

What I am missing here?

Update

After commenting both line containing if ..., it is now printing

2023-04-07 20:10:20,860,info log to file

to file and

INFO:fileLogger2:info log to file
debug log to console
DEBUG:consoleLogger2:debug log to console

to console.

It means those if conditions are false causing no file handler are getting added and that is why nothing was getting logged. But those if conditions should be true initially right (as logger should not have any handler to start with)?

MsA
  • 2,599
  • 3
  • 22
  • 47

1 Answers1

0

The logger names fileLogger2 and consoleLogger2 are both children of the root logger, which has the default level set to WARNING. This means that the messages with lower log levels (like INFO and DEBUG) will not propagate to the root logger and won't be logged. You can set the propagate attribute of your loggers to False, which would prevent the messages from being passed to the parent loggers allowing you to see the log messages as expected:

def configureLogger(self):
    self.fileLogger = logging.getLogger('fileLogger2')
    if not self.fileLogger.hasHandlers():
        self.fileLogger.setLevel(logging.INFO)
        self.fileLogger.propagate = False  # Add this line
        formatter1 = logging.Formatter("%(asctime)s,%(message)s")
        file_handler = logging.FileHandler('log.txt')
        file_handler.setLevel(logging.INFO)
        file_handler.setFormatter(formatter1)
        self.fileLogger.addHandler(file_handler)

    self.consoleLogger = logging.getLogger('consoleLogger2')
    if not self.consoleLogger.hasHandlers():
        self.consoleLogger.setLevel(logging.DEBUG)
        self.consoleLogger.propagate = False  # Add this line
        formatter2 = logging.Formatter("%(message)s")
        console_handler = logging.StreamHandler()
        console_handler.setFormatter(formatter2)
        self.consoleLogger.addHandler(console_handler)

https://docs.python.org/3/library/logging.html#logging.Logger.propagate


EDIT: Alternatively, you can remove existing handlers by adding logging.root.handlers.clear() to your configureLogger() method. Also, because we remove any existing handlers we do not need to care any propagation (as there is nothing to propagate to), so remove self.consoleLogger.propagate = False line I suggested previously:

def configureLogger(self):
    logging.root.handlers.clear()  # Add this line

    ...
    self.consoleLogger.propagate = False  # Remove this (x2)
    ...
Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141
  • Tried, it does not work. [Here](https://colab.research.google.com/drive/1FiFLyd8_GEDRscmryco37zEX_tBcQf2n?usp=sharing) is the updated notebook. Also setting root loggers level to `DEBUG` doesnt work as expected. – MsA Apr 07 '23 at 20:28
  • 1
    Can you please try adding `logging.root.handlers.clear()` at the beginning of `configureLogger()`? – Marcin Orlowski Apr 07 '23 at 21:24
  • Utter thank you!!! It worked perfectly. Also `propgate=False` was not required. Updated the notebook linked in the comment. I got the reason: `hasHandlers()` checks if there is any handler on parent logger too. So, no handler was getting added to any of `consoleLogger` and `fileLogger`. Now am not guessing why original code work on my local machine but not on colab!!! Any guesses? Did it work on your local machine? – MsA Apr 08 '23 at 17:59
  • yes, your code did nothing due to `if` condition being `False` because of existing handlers. Once we removed them, your code kicked in. I edited the answer to reflect that. If that solved your problem, please mark answer accepted. – Marcin Orlowski Apr 08 '23 at 20:17
  • 1
    Also a note to colab users. If you are writing logs to google drive, it may take several minutes for a log file to actually get updated. In my case, it did get reflected after at least 5 minutes. Till that time I was brain storming and constantly changing code to fix why log file might not be getting created. And suddenly after 5 minutes, log file got created with all logs for several different runs corresponding to my code changes! – MsA Apr 11 '23 at 14:48