omni
omni

Reputation: 4515

Python logging handler ignored in submodules

situation

I got my logging handler configured like this in my main.py

logger = logging.getLogger("__name__")
fh = logging.FileHandler("./log/error.log")
fh.setLevel(logging.WARN)
logger.addHandler(fh)

From my main.py I'm calling some @staticmethod in a submodule sub.py. Because these are static, in every method at the beginning I get the logger of my main.py using logger = logging.getLogger(__name__) (maybe you know a better way to grab that logger? Currently this is breaking DRY imho).

issue

when I log something in my main.py using e.g. logger.error("something went wrong") then it will be saved in my error.log file just as I configured it. It will not be send to console, just as I want it. But when I do the same logging call from my sub.py method it is send to console (stderr) in addition, which is not what I want.

What am I doing wrong?

Upvotes: 0

Views: 1145

Answers (1)

Guy Gangemi
Guy Gangemi

Reputation: 1773

Error level printing to console is the default configuration so main.py isn't configuring your logger.

That's because main.py is configuring a logger literally named "_name_". Sub is configuring a logger named "main.sub" (Assuming a basic package structure and you execute main.py).

The Fix

Quickest fix is to update this line in main.py:

logger = logging.getLogger("main")

Calls to logger main.sub will bubble up to logger main and get caught by it's handler.

Take away

You may still want to use __name__ in main.py because you've read it's good practice. That's only the case for modules called by other modules. Here's what to keep in mind:

Strings stay strings so if calling main.py or sub.py:

print('__name__')  # '__name__'

If you run python main.py:

import sub
print(__name__)  # '__main__'
print(sub.__name__)  # 'main.sub'

If you run python sub.py:

import main
print(main.__name__)  # 'main'
print(__name__)  # '__main__'

Upvotes: 1

Related Questions