I upgraded django-debug-toolbar from 0.9.4. to 1.0.1, and I noticed my application was quickly leaking memory even when settings.DEBUG was set to False. Once I removed debug_toolbar from the list of applications, the problem disappeared.
Upon further investigation, I found that LoggingPanel was quietly collecting all my log messages and never releasing them.
This problem only occurs if the Django application is fully initialized (e.g. using runserver), since this causes the LoggingPanel to register its handlers. Here is a simple application that illustrates the problem:
from django.core.management import ManagementUtility
utility = ManagementUtility()
command = utility.fetch_command('runserver')
logger = logging.getLogger('test')
logger.info('This logger will leak memory')
Run this application with the default debug_toolbar settings, and then use 'top' to watch the memory grow without bound. The problem appears that the LoggingPanel does not use the enable_instrumentation() function normally called by the middleware, which does the DEBUG check beforehand.
I think the simplest fix is to check if DEBUG is enabled before initializing the LogCollector. This pull request does just that, and it appears to fix the issue.
In addition, I think we should consider a few other things:
Warn the user that under DEBUG mode, memory used for log messages can grow without bounds (this might be true for other panels already).
Limit the number/age of messages stored (perhaps as a configuration option).
Disable Logging panel when DEBUG is set to False to prevent memory leaks
Initialize LogCollector to ensure LoggingPanel can always run
Fix tests by ensuring LogCollector is in the right state based on the…
… DEBUG state
Refactor enable_collector() into a method for LogCollector that
can be called explicitly to ensure logging is initiated.
Remove unneeded comments
I think we have to bite the bullet and write a logging.Filter that checks a thread-local flag set by enable/disable_instrumentation if we want to avoid running into further problems.