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():
|
||||
# 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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue