Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable output of root logger

Tags:

python

logging

I have the following code in a file called 'logger.py'

import logging

format = '%(asctime)s - %(name)-30s - %(levelname)-8s - %(message)s'
logging.basicConfig(level=logging.DEBUG,
                    format=format)

formatter = logging.Formatter(format)

fh = logging.FileHandler('test.log')
fh.setFormatter(formatter)
fh.setLevel(logging.DEBUG)

ch = logging.StreamHandler()
ch.setFormatter(formatter)
ch.setLevel(logging.INFO)

logging.getLogger().addHandler(fh)
logging.getLogger().addHandler(ch)

and in another file

import logging
import logger

logger = logging.getLogger(__name__)
logger.info('Staring Scheduler')

and I am getting the following console output

2014-07-14 22:27:10,915 - __main__                       - INFO     - Staring Scheduler
2014-07-14 22:27:10,915 - __main__                       - INFO     - Staring Scheduler

I am unable to disable the double output. I would like to use the extra streamhandler to customize the log level printed to the console. In the future I would also like to use the RotatingFileHandler instead of the simple file handler.

Does anybody know how to achieve this while keeping the simple logger setup as in the second file? I have search, but no solution seems to do it.

UPDATE 1 (Solved)

File logger.py

import logging

logging.getLogger().setLevel(logging.DEBUG)

formatter = logging.Formatter('%(asctime)s - %(name)-30s - %(levelname)-8s - %(message)s')

fh = logging.FileHandler('test.log')
fh.setFormatter(formatter)
fh.setLevel(logging.DEBUG)

ch = logging.StreamHandler()
ch.setFormatter(formatter)
ch.setLevel(logging.ERROR)

logging.getLogger().addHandler(fh)
logging.getLogger().addHandler(ch)

File test.py

import logging
import logger

logger = logging.getLogger(__name__)
logger.debug('Debug message')
logger.info('Info message')
logger.warning('Warning message')
logger.error('Error message')
logger.critical('Critical message')

Console output:

2014-07-15 09:47:58,171 - __main__                       - ERROR    - Error message
2014-07-15 09:47:58,171 - __main__                       - CRITICAL - Critical message

Test.log content:

2014-07-15 09:47:58,171 - __main__                       - DEBUG    - Debug message
2014-07-15 09:47:58,171 - __main__                       - INFO     - Info message
2014-07-15 09:47:58,171 - __main__                       - WARNING  - Warning message
2014-07-15 09:47:58,171 - __main__                       - ERROR    - Error message
2014-07-15 09:47:58,171 - __main__                       - CRITICAL - Critical message
like image 236
Tammo Heeren Avatar asked Jul 15 '14 05:07

Tammo Heeren


People also ask

What is the root logger Python?

The root of the hierarchy of loggers is called the root logger. That's the logger used by the functions debug() , info() , warning() , error() and critical() , which just call the same-named method of the root logger. The functions and the methods have the same signatures.

What is root level in logging?

The root logger resides at the top of the logger hierarchy. It is exceptional in three ways: it always exists, its level cannot be set to null. it cannot be retrieved by name.

Why is logging better than printing?

One of the advantages of using the logging module to track our codes is the ability to format the messages based on our needs. For example, in my code, I would like to log the date and time with appropriate messages. Here is an example. And here is the output.


2 Answers

The reason you are seeing the double output is because you have set up two StreamHandlers in your first file; logger.py

One explicitly in this line:

ch = logging.StreamHandler()

the other in this line:

logging.basicConfig(level=logging.DEBUG,

According to the docs for logging.basicConfig:

Does basic configuration for the logging system by creating a StreamHandler with a default Formatter and adding it to the root logger.

So you should remove the basicConfig line.

However after you remove it you will need to set the level for the root logger to DEBUG, since you do this in the basicConfig line:

logging.getLogger().setLevel(logging.DEBUG)
like image 144
Jeremy Allen Avatar answered Oct 16 '22 16:10

Jeremy Allen


You're calling logging.basicConfig(), which defaults to a StreamHandler. Instead, you should set the level manually.

>>> import logging

>>> format = '%(asctime)s - %(name)-30s - %(levelname)-8s - %(message)s'
>>> formatter = logging.Formatter(format)
>>> fh = logging.FileHandler('test.log')
>>> fh.setFormatter(formatter)
>>> fh.setLevel(logging.DEBUG)
>>> ch = logging.StreamHandler()
>>> ch.setFormatter(formatter)
>>> ch.setLevel(logging.INFO)
>>> logging.getLogger().addHandler(fh)
>>> logging.getLogger().addHandler(ch)
>>> l = logging.getLogger(__name__)
>>> l.setLevel(logging.INFO)
>>> l.info("HI")
2014-07-15 08:46:50,000 - __main__                       - INFO     - HI

The file contents are:

msvalkon@lunkwill:~$ cat test.log
2014-07-15 08:46:50,000 - __main__                       - INFO     - HI

Also, you're overwriting your logger. In your another file:

import logging
import logger # <-- importing logger.py

logger = logging.getLogger(__name__) # <-- overwriting the logger name, nothing from logger.py is now availabe
logger.info('Staring Scheduler') # This is just a logging object

Your logging configuration is done in this case, because the import will go through your code. In some other cases might not be true. Fix by changing the variable name or change the configuration scheme entirely.

like image 44
msvalkon Avatar answered Oct 16 '22 15:10

msvalkon