Browse Source

Fixed #21714 -- Moved logging configuration to global setup()

Thanks Aymeric Augustin for the report and the review.
Claude Paroz 11 years ago
parent
commit
b8e3373f45
5 changed files with 36 additions and 41 deletions
  1. 7 2
      django/__init__.py
  2. 0 27
      django/conf/__init__.py
  3. 21 0
      django/utils/log.py
  4. 3 5
      docs/topics/logging.txt
  5. 5 7
      tests/logging_tests/tests.py

+ 7 - 2
django/__init__.py

@@ -9,8 +9,13 @@ def get_version(*args, **kwargs):
 
 
 def setup():
-    # Configure the settings (this happens as a side effect of accessing
-    # INSTALLED_APPS or any other setting) and populate the app registry.
+    """
+    Configure the settings (this happens as a side effect of accessing the
+    first setting), configure logging and populate the app registry.
+    """
     from django.apps import apps
     from django.conf import settings
+    from django.utils.log import configure_logging
+
+    configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
     apps.populate(settings.INSTALLED_APPS)

+ 0 - 27
django/conf/__init__.py

@@ -7,16 +7,12 @@ a list of all possible variables.
 """
 
 import importlib
-import logging
 import os
-import sys
 import time     # Needed for Windows
-import warnings
 
 from django.conf import global_settings
 from django.core.exceptions import ImproperlyConfigured
 from django.utils.functional import LazyObject, empty
-from django.utils.module_loading import import_by_path
 from django.utils import six
 
 ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
@@ -44,34 +40,12 @@ class LazySettings(LazyObject):
                 % (desc, ENVIRONMENT_VARIABLE))
 
         self._wrapped = Settings(settings_module)
-        self._configure_logging()
 
     def __getattr__(self, name):
         if self._wrapped is empty:
             self._setup(name)
         return getattr(self._wrapped, name)
 
-    def _configure_logging(self):
-        """
-        Setup logging from LOGGING_CONFIG and LOGGING settings.
-        """
-        if not sys.warnoptions:
-            # Route warnings through python logging
-            logging.captureWarnings(True)
-            # Allow DeprecationWarnings through the warnings filters
-            warnings.simplefilter("default", DeprecationWarning)
-
-        if self.LOGGING_CONFIG:
-            from django.utils.log import DEFAULT_LOGGING
-            # First find the logging configuration function ...
-            logging_config_func = import_by_path(self.LOGGING_CONFIG)
-
-            logging_config_func(DEFAULT_LOGGING)
-
-            # ... then invoke it with the logging settings
-            if self.LOGGING:
-                logging_config_func(self.LOGGING)
-
     def configure(self, default_settings=global_settings, **options):
         """
         Called to manually configure the settings. The 'default_settings'
@@ -84,7 +58,6 @@ class LazySettings(LazyObject):
         for name, value in options.items():
             setattr(holder, name, value)
         self._wrapped = holder
-        self._configure_logging()
 
     @property
     def configured(self):

+ 21 - 0
django/utils/log.py

@@ -1,8 +1,11 @@
 import logging
+import sys
+import warnings
 
 from django.conf import settings
 from django.core import mail
 from django.core.mail import get_connection
+from django.utils.module_loading import import_by_path
 from django.views.debug import ExceptionReporter, get_exception_reporter_filter
 
 # Imports kept for backwards-compatibility in Django 1.7.
@@ -61,6 +64,24 @@ DEFAULT_LOGGING = {
 }
 
 
+def configure_logging(logging_config, logging_settings):
+    if not sys.warnoptions:
+        # Route warnings through python logging
+        logging.captureWarnings(True)
+        # Allow DeprecationWarnings through the warnings filters
+        warnings.simplefilter("default", DeprecationWarning)
+
+    if logging_config:
+         # First find the logging configuration function ...
+        logging_config_func = import_by_path(logging_config)
+
+        logging_config_func(DEFAULT_LOGGING)
+
+        # ... then invoke it with the logging settings
+        if logging_settings:
+            logging_config_func(logging_settings)
+
+
 class AdminEmailHandler(logging.Handler):
     """An exception log handler that emails log entries to site admins.
 

+ 3 - 5
docs/topics/logging.txt

@@ -222,11 +222,9 @@ set to ``True`` (which is the default) the default configuration is completely
 overridden. Alternatively you can redefine some or all of the loggers by
 setting ``disable_existing_loggers`` to ``False``.
 
-Logging is configured as soon as settings have been loaded
-(either manually using :func:`~django.conf.settings.configure` or when at least
-one setting is accessed). Since the loading of settings is one of the first
-things that Django does, you can be certain that loggers are always ready for
-use in your project code.
+Logging is configured as part of the general Django ``setup()`` function.
+Therefore, you can be certain that loggers are always ready for use in your
+project code.
 
 .. _dictConfig format: http://docs.python.org/library/logging.config.html#configuration-dictionary-schema
 

+ 5 - 7
tests/logging_tests/tests.py

@@ -3,7 +3,6 @@ from __future__ import unicode_literals
 import logging
 import warnings
 
-from django.conf import LazySettings
 from django.core import mail
 from django.test import TestCase, RequestFactory, override_settings
 from django.test.utils import patch_logger
@@ -342,15 +341,14 @@ def dictConfig(config):
 dictConfig.called = False
 
 
-class SettingsConfigureLogging(TestCase):
+class SetupConfigureLogging(TestCase):
     """
-    Test that calling settings.configure() initializes the logging
-    configuration.
+    Test that calling django.setup() initializes the logging configuration.
     """
+    @override_settings(LOGGING_CONFIG='logging_tests.tests.dictConfig')
     def test_configure_initializes_logging(self):
-        settings = LazySettings()
-        settings.configure(
-            LOGGING_CONFIG='logging_tests.tests.dictConfig')
+        from django import setup
+        setup()
         self.assertTrue(dictConfig.called)