Question: Im quite confused on the logging docs' explanation of getLogger(__name__) as a best practice. Gonna be explaining my entire thought process, feel free to leave a comment any time I make a mistake The logging docs says  A good convention to use when naming loggers is to use a module-level logger, in each module which uses logging, named as follows: logger = logging.getLogger(__name__)  Say I have a project structure: main_module.py cookbook_example ---auxiliary_module.py  main_module.py import logging from cookbook_example import auxiliary_module # Creates a new logger instance logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) # Create file handler that logs debug messages fh = logging.FileHandler('spam.log', mode='w') fh.setLevel(logging.DEBUG) # Create a formatter formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') fh.setFormatter(formatter) logger.addHandler(fh) logger.info('Creating instance of auxiliary_module.Auxiliary') a = auxiliary_module.Auxiliary() logger.info('Calling auxiliary_module.do_something') a.do_something() auxiliary_module.some_function()  auxiliary_module.py import logging # create logger module_logger = logging.getLogger(f'__main__.{__name__}') def some_function(): module_logger.info('received a call to "some_function"')  Now, from this SO thread, I infer that getLogger(__name__) should not actually be used in EVERY module that uses logging but instead in the module where a logger is configured, which in this case would be main_module.py e.g. In the auxiliary module, trying to get the custom logger through getLogger(__name__) will return the root logger, whereas getLogger(f'__main__.{__name__}') will return that custom logger. To me, this formatting of getLogger(f'__main__.{__name__}') doesn't seem much easier to write than the explicit getLogger('main_module.auxiliary_module'). Furthermore, in the log files it logs __main__.auxiliary_module rather than main_module.auxiliary_module, losing a bit of accuracy. Lastly, I previously stated that to my understanding, getLogger(__name__) should only be placed in the module where the logger is configured. However, configuration should be placed in a config file or dict anyways. Thus, I don't seem to understand any reasonable usage of getLogger(__name__) and how it is, according to the docs, a best practice. Could someone explain this and maybe link a repo that uses loggers with proper organisation that I could refer to? Thanks

Answer: Assume this simple project: project/ ├── app.py ├── core │ ├── engine.py │ └── __init__.py ├── __init__.py └── utils ├── db.py └── __init__.py  Where app.py is: import logging import sys from utils import db from core import engine logger = logging.getLogger() logger.setLevel(logging.INFO) stdout = logging.StreamHandler(sys.stdout) stdout.setFormatter(logging.Formatter("%(name)s: %(message)s")) logger.addHandler(stdout) def run(): db.start() engine.start() run()  and utils/db.py and core/engine.py is: from logging import getLogger print(__name__) # will print utils.db or core.engine logger = getLogger(__name__) print(id(logger)) # different object for each module; child of root though def start(): logger.info("started")  If you run this using python app.py, you will see that it takes care of printing the proper namespaces for you. utils.db: started core.engine: started  If your code is well organised, your module name itself is the best logger name available. If you had to reinvent those names, it usually means that you have a bad module structure (or some special, non-standard use case). For most purposes though, this should work fine (hence part of stdlib). That is all there is to it. Remember, you don't really set handlers for libraries; that is left to the consumer.