Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python logging module having a formatter causes AttributeError

I am writing a terminal application, which, after passing in -v option, gets, unsurprisingly, verbose. I want to have the output available in the terminal, for easy testing (it gets redirected to a log file when running as cron anyways).

However, python logging module doesn't allow me to write out the messages with corresponding levels when using a formatter. (Formatter is copied directly from Python Logging Cookbok)

This behavior is not limited to Python3 only. Python2.7 raises the same exception under the given conditions.


one.py

from sys import stdout
import logging

if __name__ == '__main__':

    level = 20

    log = logging.getLogger()
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    handler = logging.StreamHandler(stdout).setFormatter(formatter)
    log.addHandler(handler)
    log.setLevel(level)

    log.info("Blah")

one.py output

Traceback (most recent call last):
  File "/home/tlevi/PycharmProjects/untitled/main.py", line 14, in <module>
    log.info("Blah")
  File "/usr/lib/python3.4/logging/__init__.py", line 1279, in info
    self._log(INFO, msg, args, **kwargs)
  File "/usr/lib/python3.4/logging/__init__.py", line 1414, in _log
    self.handle(record)
  File "/usr/lib/python3.4/logging/__init__.py", line 1424, in handle
    self.callHandlers(record)
  File "/usr/lib/python3.4/logging/__init__.py", line 1485, in callHandlers
    if record.levelno >= hdlr.level:
AttributeError: 'NoneType' object has no attribute 'level'

two.py (works like a charm)

from sys import stdout
import logging

if __name__ == '__main__':

    level = 20

    log = logging.getLogger()
    handler = logging.StreamHandler(stdout)
    log.addHandler(handler)
    log.setLevel(level)

    log.info("Blah")

two.py output

Blah
like image 325
sjaustirni Avatar asked Dec 16 '15 18:12

sjaustirni


People also ask

What is Formatter logging?

The formatter returns formatted output to the handler, which writes the output to the output device. The formatter is responsible for rendering the event for output. This formatter uses the resource bundle that is specified in the event to look up the message in the appropriate language.

Is logging python thread safe?

Although logging module is thread-safe, it's not process-safe. If you want multiple processes to write to the same log file, then you have to manually take care of the access to your file.

What is Qualname in python logging?

The qualname entry is the hierarchical channel name of the logger, that is to say the name used by the application to get the logger.

How do you initialize a logger in Python?

Configuring Logging Creating loggers, handlers, and formatters explicitly using Python code that calls the configuration methods listed above. Creating a logging config file and reading it using the fileConfig() function. Creating a dictionary of configuration information and passing it to the dictConfig() function.


1 Answers

Instead of

handler = logging.StreamHandler(stdout).setFormatter(formatter)

Try:

handler = logging.StreamHandler(stdout)
handler.setFormatter(formatter)

What is happening is that in the first case you are assigning the return of setFormatter() to the handler variable, but setFormatter() does not return the handler (i.e. it returns None)

like image 172
Sebastian Avatar answered Oct 12 '22 10:10

Sebastian