Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #18993 -- 'django' logger logs to console when DEBUG=True

Thanks Preston Holmes for the review.
  • Loading branch information...
commit f0f327bbfe1caae6d11fbe20a3b5b96eed1704cf 1 parent a014ddf
@claudep claudep authored
View
25 django/utils/log.py
@@ -24,18 +24,25 @@ def emit(self, record):
getLogger = logging.getLogger
-# Default logging for Django. This sends an email to
-# the site admins on every HTTP 500 error. All other log
-# records are sent to the bit bucket.
+# Default logging for Django. This sends an email to the site admins on every
+# HTTP 500 error. Depending on DEBUG, all other log records are either sent to
+# the console (DEBUG=True) or discarded by mean of the NullHandler (DEBUG=False).
DEFAULT_LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
- }
+ },
+ 'require_debug_true': {
+ '()': 'django.utils.log.RequireDebugTrue',
+ },
},
'handlers': {
+ 'console':{
+ 'level': 'INFO',
+ 'class': 'logging.StreamHandler',
+ },
'null': {
'class': 'django.utils.log.NullHandler',
},
@@ -47,12 +54,13 @@ def emit(self, record):
},
'loggers': {
'django': {
- 'handlers': ['null'],
+ 'handlers': ['console'],
+ 'filters': ['require_debug_true'],
},
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
- 'propagate': True,
+ 'propagate': False,
},
}
}
@@ -130,3 +138,8 @@ def filter(self, record):
class RequireDebugFalse(logging.Filter):
def filter(self, record):
return not settings.DEBUG
+
+
+class RequireDebugTrue(logging.Filter):
+ def filter(self, record):
+ return settings.DEBUG
View
4 docs/releases/1.5.txt
@@ -172,6 +172,10 @@ Django 1.5 also includes several smaller improvements worth noting:
* An instance of :class:`~django.core.urlresolvers.ResolverMatch` is stored on
the request as ``resolver_match``.
+* By default, all logging messages reaching the `django` logger when
+ :setting:`DEBUG` is `True` are sent to the console (unless you redefine the
+ logger in your :setting:`LOGGING` setting).
+
Backwards incompatible changes in 1.5
=====================================
View
20 docs/topics/logging.txt
@@ -546,6 +546,13 @@ logging module.
}
},
+.. class:: RequireDebugTrue()
+
+ .. versionadded:: 1.5
+
+ This filter is similar to :class:`RequireDebugFalse`, except that records are
+ passed only when :setting:`DEBUG` is `True`.
+
.. _default-logging-configuration:
Django's default logging configuration
@@ -555,5 +562,14 @@ By default, Django configures the ``django.request`` logger so that all messages
with ``ERROR`` or ``CRITICAL`` level are sent to :class:`AdminEmailHandler`, as
long as the :setting:`DEBUG` setting is set to ``False``.
-All messages reaching the ``django`` catch-all logger are discarded
-(sent to ``NullHandler``).
+All messages reaching the ``django`` catch-all logger when :setting:`DEBUG` is
+`True` are sent ot the console. They are simply discarded (sent to
+``NullHandler``) when :setting:`DEBUG` is `False`.
+
+.. versionchanged:: 1.5
+
+ Before Django 1.5, all messages reaching the ``django`` logger were
+ discarded, regardless of :setting:`DEBUG`.
+
+See also :ref:`Configuring logging <configuring-logging>` to learn how you can
+complement or replace this default logging configuration.
View
40 tests/regressiontests/logging_tests/tests.py
@@ -9,6 +9,7 @@
from django.test import TestCase, RequestFactory
from django.test.utils import override_settings
from django.utils.log import CallbackFilter, RequireDebugFalse
+from django.utils.six import StringIO
from ..admin_scripts.tests import AdminScriptTestCase
@@ -109,6 +110,28 @@ def test_no_patch_if_no_mail_admins_handler(self):
self.assertEqual(config, new_config)
+class DefaultLoggingTest(TestCase):
+ def setUp(self):
+ self.logger = logging.getLogger('django')
+ self.old_stream = self.logger.handlers[0].stream
+
+ def tearDown(self):
+ self.logger.handlers[0].stream = self.old_stream
+
+ def test_django_logger(self):
+ """
+ The 'django' base logger only output anything when DEBUG=True.
+ """
+ output = StringIO()
+ self.logger.handlers[0].stream = output
+ self.logger.error("Hey, this is an error.")
+ self.assertEqual(output.getvalue(), '')
+
+ with self.settings(DEBUG=True):
+ self.logger.error("Hey, this is an error.")
+ self.assertEqual(output.getvalue(), 'Hey, this is an error.\n')
+
+
class CallbackFilterTest(TestCase):
def test_sense(self):
f_false = CallbackFilter(lambda r: False)
@@ -131,6 +154,7 @@ def _callback(record):
class AdminEmailHandlerTest(TestCase):
+ logger = logging.getLogger('django.request')
def get_admin_email_handler(self, logger):
# Inspired from regressiontests/views/views.py: send_log()
@@ -156,14 +180,13 @@ def test_accepts_args(self):
token1 = 'ping'
token2 = 'pong'
- logger = logging.getLogger('django.request')
- admin_email_handler = self.get_admin_email_handler(logger)
+ admin_email_handler = self.get_admin_email_handler(self.logger)
# Backup then override original filters
orig_filters = admin_email_handler.filters
try:
admin_email_handler.filters = []
- logger.error(message, token1, token2)
+ self.logger.error(message, token1, token2)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].to, ['admin@example.com'])
@@ -187,15 +210,14 @@ def test_accepts_args_and_request(self):
token1 = 'ping'
token2 = 'pong'
- logger = logging.getLogger('django.request')
- admin_email_handler = self.get_admin_email_handler(logger)
+ admin_email_handler = self.get_admin_email_handler(self.logger)
# Backup then override original filters
orig_filters = admin_email_handler.filters
try:
admin_email_handler.filters = []
rf = RequestFactory()
request = rf.get('/')
- logger.error(message, token1, token2,
+ self.logger.error(message, token1, token2,
extra={
'status_code': 403,
'request': request,
@@ -225,8 +247,7 @@ def test_subject_accepts_newlines(self):
self.assertEqual(len(mail.outbox), 0)
- logger = logging.getLogger('django.request')
- logger.error(message)
+ self.logger.error(message)
self.assertEqual(len(mail.outbox), 1)
self.assertFalse('\n' in mail.outbox[0].subject)
@@ -250,8 +271,7 @@ def test_truncate_subject(self):
self.assertEqual(len(mail.outbox), 0)
- logger = logging.getLogger('django.request')
- logger.error(message)
+ self.logger.error(message)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, expected_subject)
Please sign in to comment.
Something went wrong with that request. Please try again.