Skip to content

Commit 5fc9a64

Browse files
committed
Preserve logs that LoggingPanel would previously overwrite
LoggingPanel upon its import, changes the Python interpreter's root logger to log into a handler that collects its records for the LoggingPanel's display. However for users that don't explicitly configure the root logger this looks like the Debug Toolbar suppresses their logs that previously went to standard error. With this commit, the logs will still keep going to standard error even if the LoggingPanel is installed, but only if the root logger has not been explicitly configured with a handler yet. This behavior will make it so that installing DDT won't break logging neither for users that already have logging customizations nor for users that have an out-of-the-box django default logging setup. Also: change LOGGING config in tests/settings.py because now DDT's own test suite would show more logs without an explicit config.
1 parent 6d401ad commit 5fc9a64

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

debug_toolbar/panels/logging.py

+18
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,24 @@ def emit(self, record):
4545
self.collector.collect(record)
4646

4747

48+
# Preserve Python's fallback log mechanism before adding ThreadTrackingHandler.
49+
50+
# If the root logger has no handlers attached then everything that reaches it goes
51+
# to the "handler of last resort".
52+
# So a Django app that doesn't explicitly configure the root logger actually logs
53+
# through logging.lastResort.
54+
# However, logging.lastResort is not used after ThreadTrackingHandler gets added to
55+
# the root logger below. This means that users who have LoggingPanel enabled might
56+
# find their logs are gone from their app as soon as they install DDT.
57+
# Explicitly adding logging.lastResort to logging.root's handler sidesteps this
58+
# potential confusion.
59+
# Note that if root has already been configured, or logging.lastResort has been
60+
# removed, then the configuration is unchanged, so users who configured their
61+
# logging aren't exposed to the opposite confusion of seeing extra log lines from
62+
# their app.
63+
if not logging.root.hasHandlers() and logging.lastResort is not None:
64+
logging.root.addHandler(logging.lastResort)
65+
4866
# We don't use enable/disable_instrumentation because logging is global.
4967
# We can't add thread-local logging handlers. Hopefully logging is cheap.
5068

0 commit comments

Comments
 (0)