diff options
Diffstat (limited to 'django')
| -rw-r--r-- | django/core/servers/basehttp.py | 62 | ||||
| -rw-r--r-- | django/utils/log.py | 50 |
2 files changed, 78 insertions, 34 deletions
diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py index b9184ca20d..60fc09a122 100644 --- a/django/core/servers/basehttp.py +++ b/django/core/servers/basehttp.py @@ -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 @@ -24,6 +24,8 @@ from django.utils.six.moves import socketserver __all__ = ('WSGIServer', 'WSGIRequestHandler') +logger = logging.getLogger('django.server') + def get_internal_wsgi_application(): """ @@ -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) @@ -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 diff --git a/django/utils/log.py b/django/utils/log.py index 6fb487b7fc..fcc7575180 100644 --- a/django/utils/log.py +++ b/django/utils/log.py @@ -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 @@ -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'], @@ -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'], }, @@ -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) |
