[1.8.x] Fixed #24361 -- Clarified docs on reconfiguring logging.

Thanks Tuttle for the report and draft patch, and Carl Meyer for
help and review.

Backport of c633667da3 from master
This commit is contained in:
Tim Graham 2015-03-21 13:59:23 -04:00
parent b81ce2ed67
commit 0dc986d1c8
1 changed files with 78 additions and 27 deletions

View File

@ -212,16 +212,20 @@ handlers, filters and formatters that you want in your logging setup,
and the log levels and other properties that you want those components and the log levels and other properties that you want those components
to have. to have.
Prior to Django 1.5, the :setting:`LOGGING` setting always overwrote the By default, the :setting:`LOGGING` setting is merged with :ref:`Django's
:ref:`default Django logging configuration <default-logging-configuration>`. default logging configuration <default-logging-configuration>` using the
From Django 1.5 forward, it is possible to get the project's logging following scheme.
configuration merged with Django's defaults, hence you can decide if you want to
add to, or replace the existing configuration.
If the ``disable_existing_loggers`` key in the :setting:`LOGGING` dictConfig is If the ``disable_existing_loggers`` key in the :setting:`LOGGING` dictConfig is
set to ``True`` (which is the default) the default configuration is completely set to ``True`` (which is the default) then all loggers from the default
overridden. Alternatively you can redefine some or all of the loggers by configuration will be disabled. Disabled loggers are not the same as removed;
setting ``disable_existing_loggers`` to ``False``. the logger will still exist, but will silently discard anything logged to it,
not even propagating entries to a parent logger. Thus you should be very
careful using ``'disable_existing_loggers': True``; it's probably not what you
want. Instead, you can set ``disable_existing_loggers`` to ``False`` and
redefine some or all of the default loggers; or you can set
:setting:`LOGGING_CONFIG` to ``None`` and :ref:`handle logging config yourself
<disabling-logging-configuration>`.
Logging is configured as part of the general Django ``setup()`` function. 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 Therefore, you can be certain that loggers are always ready for use in your
@ -234,7 +238,7 @@ Examples
The full documentation for `dictConfig format`_ is the best source of The full documentation for `dictConfig format`_ is the best source of
information about logging configuration dictionaries. However, to give information about logging configuration dictionaries. However, to give
you a taste of what is possible, here are a couple examples. you a taste of what is possible, here are several examples.
First, here's a simple configuration which writes all request logging from the First, here's a simple configuration which writes all request logging from the
:ref:`django-request-logger` logger to a local file:: :ref:`django-request-logger` logger to a local file::
@ -261,12 +265,39 @@ First, here's a simple configuration which writes all request logging from the
If you use this example, be sure to change the ``'filename'`` path to a If you use this example, be sure to change the ``'filename'`` path to a
location that's writable by the user that's running the Django application. location that's writable by the user that's running the Django application.
Second, here's an example of a fairly complex logging setup, configured using Second, here's an example of how to make the logging system print Django's
:func:`logging.config.dictConfig`:: logging to the console. It overrides the fact that ``django.request`` and
``django.security`` don't propagate their log entries by default. It may be
useful during local development.
By default, this config only sends messages of level ``INFO`` or higher to the
console. Django does not log many such messages. Set the environment variable
``DJANGO_LOG_LEVEL=DEBUG`` to see all of Django's debug logging which is very
verbose as it includes all database queries::
import os
LOGGING = { LOGGING = {
'version': 1, 'version': 1,
'disable_existing_loggers': True, 'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django': {
'handlers': ['console'],
'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
},
},
}
Finally, here's an example of a fairly complex logging setup::
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': { 'formatters': {
'verbose': { 'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s' 'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
@ -321,8 +352,6 @@ This logging configuration does the following things:
* Identifies the configuration as being in 'dictConfig version 1' * Identifies the configuration as being in 'dictConfig version 1'
format. At present, this is the only dictConfig format version. format. At present, this is the only dictConfig format version.
* Disables all existing logging configurations.
* Defines two formatters: * Defines two formatters:
* ``simple``, that just outputs the log level name (e.g., * ``simple``, that just outputs the log level name (e.g.,
@ -390,20 +419,30 @@ use a different configuration process, you can use any other callable
that takes a single argument. The contents of :setting:`LOGGING` will that takes a single argument. The contents of :setting:`LOGGING` will
be provided as the value of that argument when logging is configured. be provided as the value of that argument when logging is configured.
.. _disabling-logging-configuration:
Disabling logging configuration Disabling logging configuration
------------------------------- -------------------------------
If you don't want to configure logging at all (or you want to manually If you don't want to configure logging at all (or you want to manually
configure logging using your own approach), you can set configure logging using your own approach), you can set
:setting:`LOGGING_CONFIG` to ``None``. This will disable the :setting:`LOGGING_CONFIG` to ``None``. This will disable the
configuration process. configuration process for :ref:`Django's default logging
<default-logging-configuration>`. Here's an example that disables Django's
logging configuration and then manually configures logging:
.. note:: .. snippet::
Setting :setting:`LOGGING_CONFIG` to ``None`` only means that the :filename: settings.py
configuration process is disabled, not logging itself. If you
disable the configuration process, Django will still make logging LOGGING_CONFIG = None
calls, falling back to whatever default logging behavior is
defined. import logging.config
logging.config.dictConfig(...)
Setting :setting:`LOGGING_CONFIG` to ``None`` only means that the automatic
configuration process is disabled, not logging itself. If you disable the
configuration process, Django will still make logging calls, falling back to
whatever default logging behavior is defined.
Django's logging extensions Django's logging extensions
=========================== ===========================
@ -652,13 +691,25 @@ logging module.
Django's default logging configuration Django's default logging configuration
====================================== ======================================
By default, Django configures the ``django.request`` logger so that all messages By default, Django configures the following logging:
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 when :setting:`DEBUG` is When :setting:`DEBUG` is ``True``:
``True`` are sent to the console. They are simply discarded (sent to
``NullHandler``) when :setting:`DEBUG` is ``False``. * The ``django`` catch-all logger sends all messages at the ``INFO`` level or
higher to the console. Django doesn't make any such logging calls at this
time (all logging is at the ``DEBUG`` level or handled by the
``django.request`` and ``django.security`` loggers).
* The ``py.warnings`` logger, which handles messages from ``warnings.warn()``,
sends messages to the console.
When :setting:`DEBUG` is ``False``:
* The ``django.request`` and ``django.security`` loggers send messages with
``ERROR`` or ``CRITICAL`` level to :class:`AdminEmailHandler`. These loggers
ignore anything at the ``WARNING`` level or below and log entries aren't
propagated to other loggers (they won't reach the ``django`` catch-all
logger, even when ``DEBUG`` is ``True``).
See also :ref:`Configuring logging <configuring-logging>` to learn how you can See also :ref:`Configuring logging <configuring-logging>` to learn how you can
complement or replace this default logging configuration. complement or replace this default logging configuration.