Disable output of root logger

2019-04-24 05:48发布

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

3条回答
Animai°情兽
2楼-- · 2019-04-24 06:21

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)
查看更多
Animai°情兽
3楼-- · 2019-04-24 06:36

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.

查看更多
虎瘦雄心在
4楼-- · 2019-04-24 06:39

So you may start by dropping your basicConfig that already add a StreamHandler to your root syslogger, so you actually have two StreamHandlers:

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

[<logging.StreamHandler object at 0x7f3f57c4d050>, <logging.FileHandler object at 0x7f3f57c091d0>, <logging.StreamHandler object at 0x7f3f57c09250>]

Then you have to do what basicConfig was doing for you:

logging.getLogger().setLevel(logging.INFO)
查看更多
登录 后发表回答