Reputation: 2104
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
Upvotes: 14
Views: 21398
Reputation: 6644
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)
Upvotes: 14
Reputation: 12077
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.
Upvotes: 2
Reputation: 11636
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)
Upvotes: 1