Reputation: 165
This question has been asked a few times under different circumstances, and none of them are general enough for me to understand what is actually going on.
The idea is that I want the functionality of the BasicConfig() set up, and the rotating file handling of RotatingFileHandler... But I can't seem to get it. When I try to add custom handlers, it no longer logs sub_modules. I actually get the error No handlers could be found for logger "sub_log1"
Here is a simplified, fully functional version of it:
The logging_test.py
(the "main"):
import logging
from logging.handlers import RotatingFileHandler
import sub_log1
import sub_log2
LOG_LVL = logging.INFO
LOG_FILENAME = 'test.log'
LOG_FORMAT = "[%(levelname)s] %(name)s %(asctime)s %(message)s"
logger = logging.getLogger(__name__)
logging.basicConfig(filename=LOG_FILENAME, format=LOG_FORMAT, level=LOG_LVL)
def main():
logger.debug('testing debug')
logger.info('testing info')
logger.warning('testing warning')
logger.error('testing error')
sub_log1.logging_test1()
sub_log2.logging_test2()
logger.critical('DONE.')
if __name__ == '__main__':
main()
The sub_log1.py
file:
import logging
logger = logging.getLogger(__name__)
def logging_test1():
logger.debug('testing debug')
logger.info('testing info')
logger.warning('testing warning')
logger.error('testing error')
The sub_log2.py
file:
import logging
logger = logging.getLogger(__name__)
def logging_test2():
logger.debug('testing debug')
logger.info('testing info')
logger.warning('testing warning')
logger.error('testing error')
In this configuration, the output of the 'test.log' file has the expected output:
[INFO] __main__ 2016-12-16 19:06:01,531 testing info
[WARNING] __main__ 2016-12-16 19:06:01,531 testing warning
[ERROR] __main__ 2016-12-16 19:06:01,532 testing error
[INFO] sub_log1 2016-12-16 19:06:01,532 testing info
[WARNING] sub_log1 2016-12-16 19:06:01,533 testing warning
[ERROR] sub_log1 2016-12-16 19:06:01,533 testing error
[INFO] sub_log2 2016-12-16 19:06:01,533 testing info
[WARNING] sub_log2 2016-12-16 19:06:01,533 testing warning
[ERROR] sub_log2 2016-12-16 19:06:01,533 testing error
[CRITICAL] __main__ 2016-12-16 19:06:01,534 DONE.
However, if I swap the logging section in logging_test.py
from this:
logger = logging.getLogger(__name__)
logging.basicConfig(filename=LOG_FILENAME, format=LOG_FORMAT, level=LOG_LVL)
to this:
# # Set up a specific logger with our desired output level
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# # Add the log message handler to the logger
handler = logging.handlers.RotatingFileHandler(
LOG_FILENAME, maxBytes=1 * 1024 * 1024, backupCount=5)
# # Set the handler's level
handler.setLevel(LOG_LVL)
# # Add a formatter
formatter = logging.Formatter(LOG_FORMAT)
handler.setFormatter(formatter)
# # add the handler to the logger
logger.addHandler(handler)
I no longer get logging from the sub_logging modules. The output of test.log
now looks like this:
[INFO] __main__ 2016-12-16 19:20:32,485 testing info
[WARNING] __main__ 2016-12-16 19:20:32,485 testing warning
[ERROR] __main__ 2016-12-16 19:20:32,485 testing error
[CRITICAL] __main__ 2016-12-16 19:20:32,485 DONE.
The first example works, but it just fills up the set file with logging statement until that file gets too big to handle.
But when I add a handler that is RotatingFileHandler, now it cannot accept logging output from imported modules. It still logs from the logging_test.py logger, but I lose so much information without accepting logging output from the imports. The only solution I can think of, is to have some sort of secondary script that checks the size of the 'test.log' file, and removes the bloated file if it gets too big... but this just seems like way too much effort for something a standard module should do with ease. Do I need to add handlers to each of the imports? Please advise?
Upvotes: 2
Views: 7617
Reputation: 24788
In the first example, you configure logging globally with
logging.basicConfig(...)
In the second example, you only configure logging for the logger specific to your main module. Thus the loggers in sub_log1
and sub_log2
remain unconfigured.
You can access the global (or root) logger by calling logging.getLogger()
without arguments:
rootLogger = logging.getLogger()
rootLogger.setLevel(...)
rootLogger.addHandler(...)
...
Upvotes: 4