Python logging to console

16,567

Solution 1

The problem comes from the call to basicConfig which sets up a log handler for stderr and also accepts a format string, not a formatter. Because you are doing this work yourself later, you don't need to use the basicConfig function. More information can be found in the python documentation.

Removing the call to basicConfig, and adding a self.log.setLevel(self.log_level) will fix the issue you are seeing.

Working code:

import logging                                                                  
import sys                                                                      

class Temp:                                                                     
    def __init__(self, is_verbose=False):                                       
        # configuring log                                                       
        if (is_verbose):                                                        
            self.log_level=logging.DEBUG                                        
        else:                                                                   
            self.log_level=logging.INFO                                         

        log_format = logging.Formatter('[%(asctime)s] [%(levelname)s] - %(message)s')
        self.log = logging.getLogger(__name__)                                  
        self.log.setLevel(self.log_level)                                       

        # writing to stdout                                                     
        handler = logging.StreamHandler(sys.stdout)                             
        handler.setLevel(self.log_level)                                        
        handler.setFormatter(log_format)                                        
        self.log.addHandler(handler)                                            

        # here                                                                  
        self.log.debug("test")                                                  

if __name__ == "__main__":                                                      
    t = Temp(True)

Solution 2

Looking through a similar issue on the Python bug tracker (https://bugs.python.org/issue16368), you can see that the formatter argument is expected to be a string (hence the attempt to invoke find):

log_format = '[%(asctime)s] [%(levelname)s] - %(message)s'
logging.basicConfig(level=self.log_level, format=log_format)
Share:
16,567
GregT
Author by

GregT

Updated on June 26, 2022

Comments

  • GregT
    GregT almost 2 years

    I'm trying to create a log in Python 3.x, that writes out to the console. Here is my code:

    import logging
    import sys
    
    class Temp:
        def __init__(self, is_verbose=False):
            # configuring log
            if (is_verbose):
                self.log_level=logging.DEBUG
            else:
                self.log_level=logging.INFO
    
            log_format = logging.Formatter('[%(asctime)s] [%(levelname)s] - %(message)s')
            logging.basicConfig(level=self.log_level, format=log_format)
            self.log = logging.getLogger(__name__)
    
            # writing to stdout
            handler = logging.StreamHandler(sys.stdout)
            handler.setLevel(self.log_level)
            handler.setFormatter(log_format)
            self.log.addHandler(handler)
    
            # here
            self.log.debug("test")
    
    if __name__ == "__main__":
        t = Temp(True)
    

    If the line after "here" is entered, Python raises an error:

    [2019-01-29 15:54:20,093] [DEBUG] - test
    --- Logging error ---
    Traceback (most recent call last):
      File "C:\Programok\Python 36\lib\logging\__init__.py", line 993, in emit
        msg = self.format(record)
      File "C:\Programok\Python 36\lib\logging\__init__.py", line 839, in format
        return fmt.format(record)
      File "C:\Programok\Python 36\lib\logging\__init__.py", line 577, in format
        if self.usesTime():
      File "C:\Programok\Python 36\lib\logging\__init__.py", line 545, in usesTime
        return self._style.usesTime()
      File "C:\Programok\Python 36\lib\logging\__init__.py", line 388, in usesTime
        return self._fmt.find(self.asctime_search) >= 0
    AttributeError: 'Formatter' object has no attribute 'find'
    ...
    

    I also had some other places in my code that prints to the log, but nothing is written to stdout, even if the line after "here" is removed.

    What might be the problem?

  • Mad Physicist
    Mad Physicist about 5 years
    Definitely better than what I was suggesting. +1