Fixed #21714 -- Moved logging configuration to global setup()
Thanks Aymeric Augustin for the report and the review.
This commit is contained in:
parent
1d23d766ab
commit
b8e3373f45
|
@ -9,8 +9,13 @@ def get_version(*args, **kwargs):
|
||||||
|
|
||||||
|
|
||||||
def setup():
|
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.apps import apps
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.utils.log import configure_logging
|
||||||
|
|
||||||
|
configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
|
||||||
apps.populate(settings.INSTALLED_APPS)
|
apps.populate(settings.INSTALLED_APPS)
|
||||||
|
|
|
@ -7,16 +7,12 @@ a list of all possible variables.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import importlib
|
import importlib
|
||||||
import logging
|
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import time # Needed for Windows
|
import time # Needed for Windows
|
||||||
import warnings
|
|
||||||
|
|
||||||
from django.conf import global_settings
|
from django.conf import global_settings
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.utils.functional import LazyObject, empty
|
from django.utils.functional import LazyObject, empty
|
||||||
from django.utils.module_loading import import_by_path
|
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
|
|
||||||
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
|
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
|
||||||
|
@ -44,34 +40,12 @@ class LazySettings(LazyObject):
|
||||||
% (desc, ENVIRONMENT_VARIABLE))
|
% (desc, ENVIRONMENT_VARIABLE))
|
||||||
|
|
||||||
self._wrapped = Settings(settings_module)
|
self._wrapped = Settings(settings_module)
|
||||||
self._configure_logging()
|
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
if self._wrapped is empty:
|
if self._wrapped is empty:
|
||||||
self._setup(name)
|
self._setup(name)
|
||||||
return getattr(self._wrapped, 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):
|
def configure(self, default_settings=global_settings, **options):
|
||||||
"""
|
"""
|
||||||
Called to manually configure the settings. The 'default_settings'
|
Called to manually configure the settings. The 'default_settings'
|
||||||
|
@ -84,7 +58,6 @@ class LazySettings(LazyObject):
|
||||||
for name, value in options.items():
|
for name, value in options.items():
|
||||||
setattr(holder, name, value)
|
setattr(holder, name, value)
|
||||||
self._wrapped = holder
|
self._wrapped = holder
|
||||||
self._configure_logging()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def configured(self):
|
def configured(self):
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import logging
|
import logging
|
||||||
|
import sys
|
||||||
|
import warnings
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.core.mail import get_connection
|
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
|
from django.views.debug import ExceptionReporter, get_exception_reporter_filter
|
||||||
|
|
||||||
# Imports kept for backwards-compatibility in Django 1.7.
|
# 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):
|
class AdminEmailHandler(logging.Handler):
|
||||||
"""An exception log handler that emails log entries to site admins.
|
"""An exception log handler that emails log entries to site admins.
|
||||||
|
|
||||||
|
|
|
@ -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
|
overridden. Alternatively you can redefine some or all of the loggers by
|
||||||
setting ``disable_existing_loggers`` to ``False``.
|
setting ``disable_existing_loggers`` to ``False``.
|
||||||
|
|
||||||
Logging is configured as soon as settings have been loaded
|
Logging is configured as part of the general Django ``setup()`` function.
|
||||||
(either manually using :func:`~django.conf.settings.configure` or when at least
|
Therefore, you can be certain that loggers are always ready for use in your
|
||||||
one setting is accessed). Since the loading of settings is one of the first
|
project code.
|
||||||
things that Django does, 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
|
.. _dictConfig format: http://docs.python.org/library/logging.config.html#configuration-dictionary-schema
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ from __future__ import unicode_literals
|
||||||
import logging
|
import logging
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from django.conf import LazySettings
|
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.test import TestCase, RequestFactory, override_settings
|
from django.test import TestCase, RequestFactory, override_settings
|
||||||
from django.test.utils import patch_logger
|
from django.test.utils import patch_logger
|
||||||
|
@ -342,15 +341,14 @@ def dictConfig(config):
|
||||||
dictConfig.called = False
|
dictConfig.called = False
|
||||||
|
|
||||||
|
|
||||||
class SettingsConfigureLogging(TestCase):
|
class SetupConfigureLogging(TestCase):
|
||||||
"""
|
"""
|
||||||
Test that calling settings.configure() initializes the logging
|
Test that calling django.setup() initializes the logging configuration.
|
||||||
configuration.
|
|
||||||
"""
|
"""
|
||||||
|
@override_settings(LOGGING_CONFIG='logging_tests.tests.dictConfig')
|
||||||
def test_configure_initializes_logging(self):
|
def test_configure_initializes_logging(self):
|
||||||
settings = LazySettings()
|
from django import setup
|
||||||
settings.configure(
|
setup()
|
||||||
LOGGING_CONFIG='logging_tests.tests.dictConfig')
|
|
||||||
self.assertTrue(dictConfig.called)
|
self.assertTrue(dictConfig.called)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue