8

I'm working on a small python project that has the following structure -

project -- logs -- project __init.py__ classA.py classB.py utils.py -- main.py 

I've set up the logging configuration in __init.py__ under project as follows:

import logging from logging import StreamHandler from logging.handlers import RotatingFileHandler # Create the Logger logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) # Create the Handler for logging data to a file logger_handler = RotatingFileHandler('logs\\mylog.log', maxBytes=1024, backupCount=5) logger_handler.setLevel(logging.INFO) #Create the Handler for logging data to console. console_handler = StreamHandler() console_handler.setLevel(logging.INFO) # Create a Formatter for formatting the log messages logger_formatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s') # Add the Formatter to the Handler logger_handler.setFormatter(logger_formatter) console_handler.setFormatter(logger_formatter) # Add the Handler to the Logger logger.addHandler(logger_handler) logger.addHandler(console_handler) 

Setting up things this way seems to set up the root logger at the package level, and not at the entire project level. As a result, logged statements inside main.py don't appear in the log file, whereas all log statements in the two classes classA and classB as well as utils.py are routed to the console and the log file as expected.

How do I set up the logging so that I'm able to configure it once and use it across the project? I tried moving the logging configuration statements to main.py, but it didn't seem to work.

def setupLogging(): # Create the Logger logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) ..etc.. def main(): setupLogging() if __name__ == "__main__": main() 

1 Answer 1

11

It is correct to configure logging only once for the whole project, as you first tried, not each package separately.

What you did wrong is you configured the logger for the current module only:

logger = logging.getLogger(__name__) 

Instead of that, you want to configure the root logger:

root_logger = logging.getLogger() root_logger.setLevel(logging.INFO) # ... root_logger.addHandler(logger_handler) root_logger.addHandler(console_handler) 

The configuration done for the root logger applies to every logger which does not explicitly override it.

Then you should use the specific logger when actually logging:

logger = logging.getLogger(__name__) logger.warning("I am warning you about %s", something) 
Sign up to request clarification or add additional context in comments.

8 Comments

Hi, thanks for the advise. It worked! I have a follow-up question though. Setting up the root logger this way seems to have set up the level for other modules imported and I'm now getting messages from third-party imported modules in the log file as well. How do I log messages only from the modules that I have written?
You can set the level for each of them (right here where you are doing this), e.g. logging.getLogger("product").setLevel(logging.INFO) or logging.getLogger("numpy").setLevel(logging.DEBUG). It may be easier to use logging configuration file, though (docs.python.org/2/library/…)
Im also having difficulty of configuring the logger. When I rename the root_logger ie root_logger = logging.getLogger('some-name'), other loggers in other modules don't work anymore. Do you know why? @zvone
@addicted You cannot "rename the root_logger". The root logger has no name. You access it with logging.getLogger(). What you did is you configured some other logger and not the root logger.
@zvone I want the other loggers to follow a certain application name as their prefix. Can I configure that logger and have the other modules' logger as a child to that configured logger? I want the child logger in other modules to have the main logger's name as a prefix in the logging name.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.