I think you are struck by the somewhat confusing distribution of the log hierarchy. Everything written in "elasticsearch.trace", which goes through the log level of this registrar, will first be distributed to the "elasticsearch" logger, and then to the root ("") logger. Please note that after the message passes LogLevel to the "elasticsearch.trace" logger, the parent logging levels ("elasticsearch" and root) are not checked, but all messages will be sent to the handler. (The handlers themselves have registration levels that apply.)
Consider the following example to illustrate a problem and a possible solution:
import logging
Output:
msg1 DEBUG:foo:msg1 msg2
You see that "msg1" is logged by both the "foo" log and its parent, the root logger (like "DEBUG: foo: msg1"). Then, when propagation is disabled ll.propagate = False to "msg2", the root registrar no longer registers it. Now, if you comment out the first line ( logging.info("DUMMY...") , the behavior will change so that the root logger line is not shown. This is because the logging module level functions above info() , debug() , etc. Configure the root log with the handler when the handler is not yet defined, which is why you see different behavior in your example when you change the root handler by doing logger = logging.getLogger() .
I canβt see in my code that you will do anything in the root logger, but, as you can see, crazy logging.info() or the like, in the program code or the library code can cause a handler to be added.
So, to answer your question, I would set logger.propagate = False for lumberjacks, where it makes sense to you and where you want to distribute, make sure the log level handlers themselves are the way you want them.
Here is an attempt:
es_logger = logging.getLogger('elasticsearch') es_logger.propagate = False es_logger.setLevel(logging.INFO) es_logger_handler=logging.handlers.RotatingFileHandler('top-camps-base.log', maxBytes=0.5*10**9, backupCount=3) es_logger.addHandler(es_logger_handler) es_tracer = logging.getLogger('elasticsearch.trace') es_tracer.propagate = False es_tracer.setLevel(logging.DEBUG) es_tracer_handler=logging.handlers.RotatingFileHandler('top-camps-full.log', maxBytes=0.5*10**9, backupCount=3) es_tracer.addHandler(es_tracer_handler) logger = logging.getLogger('mainLog') logger.propagate = False logger.setLevel(logging.DEBUG) # create file handler fileHandler = logging.handlers.RotatingFileHandler('top-camps.log', maxBytes=10**6, backupCount=3) fileHandler.setLevel(logging.INFO) # create console handler consoleHandler = logging.StreamHandler() consoleHandler.setLevel(logging.INFO) # create formatter and add it to the handlers formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') consoleHandler.setFormatter(formatter) fileHandler.setFormatter(formatter) # add the handlers to logger logger.addHandler(consoleHandler) logger.addHandler(fileHandler)
Anton
source share