-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
logging.config: configuring root through dictConfig won't update already existing loggers #120785
Comments
|
After some further research it seems this behavior is caused by the way the Far from being a proper fix, a small workaround like the following one helps changing such behavior (applicable on v3.12.2): diff --git a/Lib/logging/config.py b/Lib/logging/config.py
index 33417b75d5..349fd6ded4 100644
--- a/Lib/logging/config.py
+++ b/Lib/logging/config.py
@@ -650,6 +650,8 @@ def configure(self):
# logger.propagate = True
# elif disable_existing:
# logger.disabled = True
+ if 'root' in config:
+ child_loggers = existing
_handle_existing_loggers(existing, child_loggers,
disable_existing)That way, loggers present in Again, I'm not sure if this behavior was intended or not. It's just that the behavior I found on logger configuration didn't feel quite standard across the different cases to me. [0] https://github.com/python/cpython/blob/v3.12.3/Lib/logging/config.py#L653-L654 |
|
You are normally supposed to set This behaviour is documented here (see the warning section):
The default value of |
|
Closing, as no further feedback received. |
|
Hi @vsajip, Sorry it took me so long you finally had to close the issue. Also sorry for opening an issue on an already documented behavior. I didn't notice that part before. I needed some time to understand the real meaning of the statement, though. It didn't seem quite straightforward at first sight. I assumed that I guess that what led me to misunderstanding the statement above was that the Thanks a lot! |
|
The root logger is the ancestor of all loggers, so there's nothing wrong with that assumption. All other loggers are non-root loggers (clearly, I hope) so any that exist before the call are disabled unless the
as per the documentation.
No other documentation I can particularly point you to - as far as I can see, the documentation paragraph from which the above snippet is taken (and anywhere else in the official docs that |


Bug report
Bug description:
I found an issue when the root logger is configured after some loggers were initialized (not necessarily configured).
Experiment
I wrote a small reproducer of the issue. There are 4 functions in the file. All of them initialize some loggers, configure some other loggers and finally log some messages. What it is different from each other is:
The reproducer:
Results
And the results for each of the analysed cases:
Case 0 configure_foo_then_init_loggers
First the
foologger is configured usinglogging.config.dictConfig. Then, instances forfooand its child loggerfoo.barare created viagetLogger.In simple terms, as
foowas configured, IIUC,foo.barinherits its parent configuration. Then, both logs are put into the stdout.Case 1 configure_root_then_init_loggers
First the
rootlogger is configured usinglogging.config.dictConfig. Then, instances forfooand its child loggerfoo.barare created viagetLogger.In simple terms, as the
rootlogger was configured, bothfooandfoo.barinherit the configuration from its parent configuration, which this time isroot.Case 2 init_loggers_then_config_foo
Now, the logger instances are first initialized for both
fooandfoo.bar. Then, only the parentfoologger is configured by usinglogging.config.dictConfig.During
foo's configuration its already existing children (foo.bar) will be also treated. IIUC, that will happen approximately in https://github.com/python/cpython/blob/v3.12.3/Lib/logging/config.py#L653-L654, asfoo.baris in theexistingloggers list as well as in thechild_loggers list.The output (written into the stdout), will be the same as case 0.
Case 3 init_loggers_then_config_root
In this case,
fooandfoo.barloggers are initialized first, but not configured, as in case 2. Then, therootlogger is configured by means oflogging.config.dictConfig.In this specific case, the already existing loggers (
fooandfoo.bar) won't be processed in_handle_existing_loggers, as they exist but are not in thechild_loggerslist.There won't be any log written to the stdout.
Case 4 init_loggers_then_config_foobar_then_foo
Last case:
fooandfoo.barare initialized. Then,foo.baris configured. It's also checked that it works as expected. Right after that,foois configured, which also affects its already existing and configured childfoo.bar.After that, logs from
foo.barwill follow the configuration offoo.Note about python3.9 and case 4
Case 4 doesn't report the same result for python3.9. From python3.10 on, the result is the same as the one reported above. For python3.9, though, will be the following:
But that's another topic.
Expected results
All the cases seem to follow the same behavior except for case 3. When a logger is configured, all of its children will follow the last applied configuration.
However, configuring the
rootlogger bydictConfigwon't apply that configuration over the rest of loggers. This is IMHO, a behavior conflict, compared to the expected one from configuring any other logger. Isn'trootthe parent of all the rest of loggers after all?CPython versions tested on:
3.9, 3.10, 3.11, 3.12
Operating systems tested on:
Linux
The text was updated successfully, but these errors were encountered: