Python logging to console
Asked Answered
T

3

12

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?

Tertias answered 29/1, 2019 at 14:59 Comment(4)
Check here: #34320021Amontillado
The OP's code already does what the linked question suggests as answerVaginitis
It's related thoughRahal
Yes, I had already checked that before posting. Thanks though.Tertias
S
21

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)
Saviour answered 29/1, 2019 at 15:16 Comment(1)
Definitely better than what I was suggesting. +1Rahal
R
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)
Rahal answered 29/1, 2019 at 15:17 Comment(1)
This is the simplest option for setting up logging to the console.Voroshilov
D
1

If you only need console log and collect logs with any log agents you could also use

print("my log info here")

This works for quick troubleshooting like console.log() in JS.

Dapplegray answered 10/7, 2023 at 5:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.