Skip to content

Log through named module loggers instead of the root logger - #140

Open
asaraog wants to merge 1 commit into
MIC-DKFZ:masterfrom
asaraog:fix/named-loggers
Open

Log through named module loggers instead of the root logger#140
asaraog wants to merge 1 commit into
MIC-DKFZ:masterfrom
asaraog:fix/named-loggers

Conversation

@asaraog

@asaraog asaraog commented Sep 1, 2026

Copy link
Copy Markdown

Fixes #123.

MultiThreadedAugmenter and NonDetMultiThreadedAugmenter log through the module-level logging.debug() / logging.error(), which go to the root logger. The first such call runs basicConfig() and installs a StreamHandler on root as a side effect, so an application with its own logger and handler sees every record twice — once from its own handler, once echoed from root:

>>> logging.getLogger().handlers
[]
>>> logging.debug("MultiThreadedGenerator: destructor was called")   # before
>>> logging.getLogger().handlers
[<StreamHandler <stderr> (NOTSET)>]

>>> logging.getLogger().handlers.clear()
>>> logging.getLogger("batchgenerators.dataloading.multi_threaded_augmenter").debug("...")   # after
>>> logging.getLogger().handlers
[]

Each module now takes logger = logging.getLogger(__name__) and the nine logging.* calls become logger.*.

One deviation from the suggestion in the issue: it proposes attaching a StreamHandler inside the package. I have deliberately not done that — a library adding its own handler is the same class of problem, just quieter, and it takes the choice of destination and format away from the application. With named loggers and no handler, records propagate to whatever the application configured, and anyone who wants batchgenerators output specifically can reach for it by name:

logging.getLogger("batchgenerators").setLevel(logging.DEBUG)

No behaviour change for callers who never configure logging: logging.lastResort still prints WARNING and above to stderr.

The augmenters called module-level logging.debug()/logging.error(), which go to
the root logger. The first such call runs basicConfig() and installs a
StreamHandler on root, so an application with its own logger and handler sees
every record twice.

Take logging.getLogger(__name__) in each module and log through it. No handler
is attached: a library adding one takes the choice of destination and format
away from the application.

Fixes MIC-DKFZ#123
@asaraog

asaraog commented Sep 1, 2026

Copy link
Copy Markdown
Author

Full test suite passes on this branch: 71 passed in 159.95s (Python 3.11, macOS).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Logging should not be done with the root logger

1 participant