Loading django/core/servers/basehttp.py +28 −34 Original line number Diff line number Diff line Loading @@ -9,13 +9,13 @@ been reviewed for security issues. DON'T USE IT FOR PRODUCTION USE! from __future__ import unicode_literals import logging import socket import sys from wsgiref import simple_server from django.core.exceptions import ImproperlyConfigured from django.core.handlers.wsgi import ISO_8859_1, UTF_8 from django.core.management.color import color_style from django.core.wsgi import get_wsgi_application from django.utils import six from django.utils.encoding import uri_to_iri Loading @@ -24,6 +24,8 @@ from django.utils.six.moves import socketserver __all__ = ('WSGIServer', 'WSGIRequestHandler') logger = logging.getLogger('django.server') def get_internal_wsgi_application(): """ Loading Loading @@ -80,7 +82,7 @@ class WSGIServer(simple_server.WSGIServer, object): def handle_error(self, request, client_address): if is_broken_pipe_error(): sys.stderr.write("- Broken pipe from %s\n" % (client_address,)) logger.info("- Broken pipe from %s\n", client_address) else: super(WSGIServer, self).handle_error(request, client_address) Loading @@ -94,47 +96,39 @@ class ServerHandler(simple_server.ServerHandler, object): class WSGIRequestHandler(simple_server.WSGIRequestHandler, object): def __init__(self, *args, **kwargs): self.style = color_style() super(WSGIRequestHandler, self).__init__(*args, **kwargs) def address_string(self): # Short-circuit parent method to not call socket.getfqdn return self.client_address[0] def log_message(self, format, *args): msg = "[%s] " % self.log_date_time_string() try: msg += "%s\n" % (format % args) except UnicodeDecodeError: # e.g. accessing the server via SSL on Python 2 msg += "\n" # Utilize terminal colors, if available if args[1][0] == '2': # Put 2XX first, since it should be the common case msg = self.style.HTTP_SUCCESS(msg) elif args[1][0] == '1': msg = self.style.HTTP_INFO(msg) elif args[1] == '304': msg = self.style.HTTP_NOT_MODIFIED(msg) elif args[1][0] == '3': msg = self.style.HTTP_REDIRECT(msg) elif args[1] == '404': msg = self.style.HTTP_NOT_FOUND(msg) elif args[1][0] == '4': extra = { 'request': self.request, 'server_time': self.log_date_time_string(), } if args[1][0] == '4': # 0x16 = Handshake, 0x03 = SSL 3.0 or TLS 1.x if args[0].startswith(str('\x16\x03')): msg = ("You're accessing the development server over HTTPS, " "but it only supports HTTP.\n") msg = self.style.HTTP_BAD_REQUEST(msg) extra['status_code'] = 500 logger.error( "You're accessing the development server over HTTPS, but " "it only supports HTTP.\n", extra=extra, ) return if args[1].isdigit() and len(args[1]) == 3: status_code = int(args[1]) extra['status_code'] = status_code if status_code >= 500: level = logger.error elif status_code >= 400: level = logger.warning else: level = logger.info else: # Any 5XX, or any other response msg = self.style.HTTP_SERVER_ERROR(msg) level = logger.info sys.stderr.write(msg) level(format, *args, extra=extra) def get_environ(self): # Strip all headers with underscores in the name before constructing Loading django/utils/log.py +50 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ from copy import copy from django.conf import settings from django.core import mail from django.core.mail import get_connection from django.core.management.color import color_style from django.utils.deprecation import RemovedInNextVersionWarning from django.utils.module_loading import import_string from django.views.debug import ExceptionReporter Loading @@ -28,12 +29,23 @@ DEFAULT_LOGGING = { '()': 'django.utils.log.RequireDebugTrue', }, }, 'formatters': { 'django.server': { '()': 'django.utils.log.ServerFormatter', 'format': '[%(server_time)s] %(message)s', } }, 'handlers': { 'console': { 'level': 'INFO', 'filters': ['require_debug_true'], 'class': 'logging.StreamHandler', }, 'django.server': { 'level': 'INFO', 'class': 'logging.StreamHandler', 'formatter': 'django.server', }, 'mail_admins': { 'level': 'ERROR', 'filters': ['require_debug_false'], Loading @@ -45,6 +57,11 @@ DEFAULT_LOGGING = { 'handlers': ['console', 'mail_admins'], 'level': 'INFO', }, 'django.server': { 'handlers': ['django.server'], 'level': 'INFO', 'propagate': False, }, 'py.warnings': { 'handlers': ['console'], }, Loading Loading @@ -155,3 +172,36 @@ class RequireDebugFalse(logging.Filter): class RequireDebugTrue(logging.Filter): def filter(self, record): return settings.DEBUG class ServerFormatter(logging.Formatter): def __init__(self, *args, **kwargs): self.style = color_style() super(ServerFormatter, self).__init__(*args, **kwargs) def format(self, record): args = record.args msg = record.msg if len(args) == 0: msg = self.style.HTTP_BAD_REQUEST(msg) else: if args[1][0] == '2': # Put 2XX first, since it should be the common case msg = self.style.HTTP_SUCCESS(msg) elif args[1][0] == '1': msg = self.style.HTTP_INFO(msg) elif args[1] == '304': msg = self.style.HTTP_NOT_MODIFIED(msg) elif args[1][0] == '3': msg = self.style.HTTP_REDIRECT(msg) elif args[1] == '404': msg = self.style.HTTP_NOT_FOUND(msg) elif args[1][0] == '4': msg = self.style.HTTP_BAD_REQUEST(msg) else: # Any 5XX, or any other response msg = self.style.HTTP_SERVER_ERROR(msg) record.msg = msg return super(ServerFormatter, self).format(record) docs/ref/django-admin.txt +8 −0 Original line number Diff line number Diff line Loading @@ -827,6 +827,14 @@ with its own :ref:`runserver<staticfiles-runserver>` command. If :djadmin:`migrate` was not previously executed, the table that stores the history of migrations is created at first run of ``runserver``. Logging of each request and response of the server is sent to the :ref:`django-server-logger` logger. .. versionchanged:: 1.10 In older versions, log messages were written to ``sys.stderr`` instead of being handled through Python logging. .. django-admin-option:: --noreload Use the ``--noreload`` option to disable the use of the auto-reloader. This Loading docs/releases/1.10.txt +30 −0 Original line number Diff line number Diff line Loading @@ -397,6 +397,36 @@ Dropped support for PostgreSQL 9.1 Upstream support for PostgreSQL 9.1 ends in September 2016. As a consequence, Django 1.10 sets PostgreSQL 9.2 as the minimum version it officially supports. ``runserver`` output goes through logging ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Request and response handling of the ``runserver`` command is sent to the :ref:`django-server-logger` logger instead of to ``sys.stderr``. If you disable Django's logging configuration or override it with your own, you'll need to add the appropriate logging configuration if you want to see that output:: 'formatters': { 'django.server': { '()': 'django.utils.log.ServerFormatter', 'format': '[%(server_time)s] %(message)s', } }, 'handlers': { 'django.server': { 'level': 'INFO', 'class': 'logging.StreamHandler', 'formatter': 'django.server', }, }, 'loggers': { 'django.server': { 'handlers': ['django.server'], 'level': 'INFO', 'propagate': False, } } Miscellaneous ~~~~~~~~~~~~~ Loading docs/topics/logging.txt +23 −0 Original line number Diff line number Diff line Loading @@ -484,6 +484,24 @@ Messages to this logger have the following extra context: * ``request``: The request object that generated the logging message. .. _django-server-logger: ``django.server`` ~~~~~~~~~~~~~~~~~ .. versionadded:: 1.10 Log messages related to the handling of requests received by the server invoked by the :djadmin:`runserver` command. HTTP 5XX responses are logged as ``ERROR`` messages, 4XX responses are logged as ``WARNING`` messages, and everything else is logged as ``INFO``. Messages to this logger have the following extra context: * ``status_code``: The HTTP response code associated with the request. * ``request``: The request object that generated the logging message. .. _django-template-logger: ``django.template`` Loading Loading @@ -729,6 +747,11 @@ When :setting:`DEBUG` is ``False``: * The ``django`` logger send messages with ``ERROR`` or ``CRITICAL`` level to :class:`AdminEmailHandler`. Independent of the value of :setting:`DEBUG`: * The :ref:`django-server-logger` logger sends all messages at the ``INFO`` level or higher to the console. .. versionchanged:: 1.9 Django's default logging configuration changed. See :ref:`the release notes Loading Loading
django/core/servers/basehttp.py +28 −34 Original line number Diff line number Diff line Loading @@ -9,13 +9,13 @@ been reviewed for security issues. DON'T USE IT FOR PRODUCTION USE! from __future__ import unicode_literals import logging import socket import sys from wsgiref import simple_server from django.core.exceptions import ImproperlyConfigured from django.core.handlers.wsgi import ISO_8859_1, UTF_8 from django.core.management.color import color_style from django.core.wsgi import get_wsgi_application from django.utils import six from django.utils.encoding import uri_to_iri Loading @@ -24,6 +24,8 @@ from django.utils.six.moves import socketserver __all__ = ('WSGIServer', 'WSGIRequestHandler') logger = logging.getLogger('django.server') def get_internal_wsgi_application(): """ Loading Loading @@ -80,7 +82,7 @@ class WSGIServer(simple_server.WSGIServer, object): def handle_error(self, request, client_address): if is_broken_pipe_error(): sys.stderr.write("- Broken pipe from %s\n" % (client_address,)) logger.info("- Broken pipe from %s\n", client_address) else: super(WSGIServer, self).handle_error(request, client_address) Loading @@ -94,47 +96,39 @@ class ServerHandler(simple_server.ServerHandler, object): class WSGIRequestHandler(simple_server.WSGIRequestHandler, object): def __init__(self, *args, **kwargs): self.style = color_style() super(WSGIRequestHandler, self).__init__(*args, **kwargs) def address_string(self): # Short-circuit parent method to not call socket.getfqdn return self.client_address[0] def log_message(self, format, *args): msg = "[%s] " % self.log_date_time_string() try: msg += "%s\n" % (format % args) except UnicodeDecodeError: # e.g. accessing the server via SSL on Python 2 msg += "\n" # Utilize terminal colors, if available if args[1][0] == '2': # Put 2XX first, since it should be the common case msg = self.style.HTTP_SUCCESS(msg) elif args[1][0] == '1': msg = self.style.HTTP_INFO(msg) elif args[1] == '304': msg = self.style.HTTP_NOT_MODIFIED(msg) elif args[1][0] == '3': msg = self.style.HTTP_REDIRECT(msg) elif args[1] == '404': msg = self.style.HTTP_NOT_FOUND(msg) elif args[1][0] == '4': extra = { 'request': self.request, 'server_time': self.log_date_time_string(), } if args[1][0] == '4': # 0x16 = Handshake, 0x03 = SSL 3.0 or TLS 1.x if args[0].startswith(str('\x16\x03')): msg = ("You're accessing the development server over HTTPS, " "but it only supports HTTP.\n") msg = self.style.HTTP_BAD_REQUEST(msg) extra['status_code'] = 500 logger.error( "You're accessing the development server over HTTPS, but " "it only supports HTTP.\n", extra=extra, ) return if args[1].isdigit() and len(args[1]) == 3: status_code = int(args[1]) extra['status_code'] = status_code if status_code >= 500: level = logger.error elif status_code >= 400: level = logger.warning else: level = logger.info else: # Any 5XX, or any other response msg = self.style.HTTP_SERVER_ERROR(msg) level = logger.info sys.stderr.write(msg) level(format, *args, extra=extra) def get_environ(self): # Strip all headers with underscores in the name before constructing Loading
django/utils/log.py +50 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ from copy import copy from django.conf import settings from django.core import mail from django.core.mail import get_connection from django.core.management.color import color_style from django.utils.deprecation import RemovedInNextVersionWarning from django.utils.module_loading import import_string from django.views.debug import ExceptionReporter Loading @@ -28,12 +29,23 @@ DEFAULT_LOGGING = { '()': 'django.utils.log.RequireDebugTrue', }, }, 'formatters': { 'django.server': { '()': 'django.utils.log.ServerFormatter', 'format': '[%(server_time)s] %(message)s', } }, 'handlers': { 'console': { 'level': 'INFO', 'filters': ['require_debug_true'], 'class': 'logging.StreamHandler', }, 'django.server': { 'level': 'INFO', 'class': 'logging.StreamHandler', 'formatter': 'django.server', }, 'mail_admins': { 'level': 'ERROR', 'filters': ['require_debug_false'], Loading @@ -45,6 +57,11 @@ DEFAULT_LOGGING = { 'handlers': ['console', 'mail_admins'], 'level': 'INFO', }, 'django.server': { 'handlers': ['django.server'], 'level': 'INFO', 'propagate': False, }, 'py.warnings': { 'handlers': ['console'], }, Loading Loading @@ -155,3 +172,36 @@ class RequireDebugFalse(logging.Filter): class RequireDebugTrue(logging.Filter): def filter(self, record): return settings.DEBUG class ServerFormatter(logging.Formatter): def __init__(self, *args, **kwargs): self.style = color_style() super(ServerFormatter, self).__init__(*args, **kwargs) def format(self, record): args = record.args msg = record.msg if len(args) == 0: msg = self.style.HTTP_BAD_REQUEST(msg) else: if args[1][0] == '2': # Put 2XX first, since it should be the common case msg = self.style.HTTP_SUCCESS(msg) elif args[1][0] == '1': msg = self.style.HTTP_INFO(msg) elif args[1] == '304': msg = self.style.HTTP_NOT_MODIFIED(msg) elif args[1][0] == '3': msg = self.style.HTTP_REDIRECT(msg) elif args[1] == '404': msg = self.style.HTTP_NOT_FOUND(msg) elif args[1][0] == '4': msg = self.style.HTTP_BAD_REQUEST(msg) else: # Any 5XX, or any other response msg = self.style.HTTP_SERVER_ERROR(msg) record.msg = msg return super(ServerFormatter, self).format(record)
docs/ref/django-admin.txt +8 −0 Original line number Diff line number Diff line Loading @@ -827,6 +827,14 @@ with its own :ref:`runserver<staticfiles-runserver>` command. If :djadmin:`migrate` was not previously executed, the table that stores the history of migrations is created at first run of ``runserver``. Logging of each request and response of the server is sent to the :ref:`django-server-logger` logger. .. versionchanged:: 1.10 In older versions, log messages were written to ``sys.stderr`` instead of being handled through Python logging. .. django-admin-option:: --noreload Use the ``--noreload`` option to disable the use of the auto-reloader. This Loading
docs/releases/1.10.txt +30 −0 Original line number Diff line number Diff line Loading @@ -397,6 +397,36 @@ Dropped support for PostgreSQL 9.1 Upstream support for PostgreSQL 9.1 ends in September 2016. As a consequence, Django 1.10 sets PostgreSQL 9.2 as the minimum version it officially supports. ``runserver`` output goes through logging ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Request and response handling of the ``runserver`` command is sent to the :ref:`django-server-logger` logger instead of to ``sys.stderr``. If you disable Django's logging configuration or override it with your own, you'll need to add the appropriate logging configuration if you want to see that output:: 'formatters': { 'django.server': { '()': 'django.utils.log.ServerFormatter', 'format': '[%(server_time)s] %(message)s', } }, 'handlers': { 'django.server': { 'level': 'INFO', 'class': 'logging.StreamHandler', 'formatter': 'django.server', }, }, 'loggers': { 'django.server': { 'handlers': ['django.server'], 'level': 'INFO', 'propagate': False, } } Miscellaneous ~~~~~~~~~~~~~ Loading
docs/topics/logging.txt +23 −0 Original line number Diff line number Diff line Loading @@ -484,6 +484,24 @@ Messages to this logger have the following extra context: * ``request``: The request object that generated the logging message. .. _django-server-logger: ``django.server`` ~~~~~~~~~~~~~~~~~ .. versionadded:: 1.10 Log messages related to the handling of requests received by the server invoked by the :djadmin:`runserver` command. HTTP 5XX responses are logged as ``ERROR`` messages, 4XX responses are logged as ``WARNING`` messages, and everything else is logged as ``INFO``. Messages to this logger have the following extra context: * ``status_code``: The HTTP response code associated with the request. * ``request``: The request object that generated the logging message. .. _django-template-logger: ``django.template`` Loading Loading @@ -729,6 +747,11 @@ When :setting:`DEBUG` is ``False``: * The ``django`` logger send messages with ``ERROR`` or ``CRITICAL`` level to :class:`AdminEmailHandler`. Independent of the value of :setting:`DEBUG`: * The :ref:`django-server-logger` logger sends all messages at the ``INFO`` level or higher to the console. .. versionchanged:: 1.9 Django's default logging configuration changed. See :ref:`the release notes Loading