Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python difficulty understanding getLogger(__name__)

Tags:

python

logging

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

like image 621
meg hidey Avatar asked Oct 29 '25 09:10

meg hidey


1 Answers

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.

like image 184
Nishant Avatar answered Oct 31 '25 12:10

Nishant



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!