On Wed, 2010-10-06 at 07:42 -0400, Karen Tracey wrote:
> On Wed, Oct 6, 2010 at 6:53 AM, Russell Keith-Magee
> <[email protected]> wrote:
> That approach works (as in - it doesn't raise errors), but it
> means
> that under Python 2.4, you lose any of the "extra" data. In
> particular, it means that
> * it's really hard to do anything interesting with the 4XX
> series errors,
> * the HTTP 500 error emails won't have any details about the
> request
> that caused them
> * the DB logging calls won't include any details about the
> SQL that
> was being logged.
>
> The first and last don't bother me particularly -- they are new
> features that come with Django's use of logging and if they are not
> available under 2.4 I think that would be OK. That middle one is a
> killer though.
>
> What about just not adding the logging feature for Python 2.4? Make
> the calls conditional on Python version and fall back to old behavior
> in the 2.4 case? Not an approach we've taken before (that I can
> recall), but if the 2.4 level just doesn't do what we need it seems
> like it might be a reasonable restriction.
The attached patch is like my other one, but restores Django 1.2
functionality for HTTP 500 errors under Python 2.4. In all other cases
the logging calls just drop the 'extra' parameter under Python 2.4,
making them not very useful, but perhaps they will serve as a 'teaser'
to encourage people to upgrade their Python version! This is the best
compromise I can think of so far. It would need some notes in the docs
on logging, and the FAQ question on Python 2.4 functionality.
Luke
--
"Dysfunction: The only consistent feature of all of your
dissatisfying relationships is you." (despair.com)
Luke Plant || http://lukeplant.me.uk/
--
You received this message because you are subscribed to the Google Groups
"Django developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/django-developers?hl=en.
diff -r a8a9a277716d django/core/handlers/base.py
--- a/django/core/handlers/base.py Tue Oct 05 01:44:12 2010 +0000
+++ b/django/core/handlers/base.py Wed Oct 06 13:53:51 2010 +0100
@@ -1,12 +1,12 @@
-import logging
import sys
from django import http
from django.core import signals
from django.utils.encoding import force_unicode
from django.utils.importlib import import_module
+from django.utils.log import getLogger
-logger = logging.getLogger('django.request')
+logger = getLogger('django.request')
class BaseHandler(object):
@@ -169,6 +169,7 @@
available would be an error.
"""
from django.conf import settings
+ from django.core.mail import mail_admins
if settings.DEBUG_PROPAGATE_EXCEPTIONS:
raise
@@ -177,13 +178,25 @@
from django.views import debug
return debug.technical_500_response(request, *exc_info)
- logger.error('Internal Server Error: %s' % request.path,
- exc_info=exc_info,
- extra={
- 'status_code': 500,
- 'request':request
- }
- )
+ if sys.version < (2, 5):
+ # To maintain existing functionality under Python 2.4, we have to
+ # use the mail_admin feature directly, due to the fact that Python
+ # 2.4's logging module doesn't accept the 'extra' parameter.
+ subject = 'Error (%s IP): %s' % ((request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'), request.path)
+ try:
+ request_repr = repr(request)
+ except:
+ request_repr = "Request repr() unavailable"
+ message = "%s\n\n%s" % (self._get_traceback(exc_info), request_repr)
+ mail_admins(subject, message, fail_silently=True)
+ else:
+ logger.error('Internal Server Error: %s' % request.path,
+ exc_info=exc_info,
+ extra={
+ 'status_code': 500,
+ 'request':request
+ }
+ )
# If Http500 handler is not installed, re-raise last exception
if resolver.urlconf_module is None:
@@ -192,6 +205,11 @@
callback, param_dict = resolver.resolve500()
return callback(request, **param_dict)
+ def _get_traceback(self, exc_info=None):
+ "Helper function to return the traceback as a string"
+ import traceback
+ return '\n'.join(traceback.format_exception(*(exc_info or sys.exc_info())))
+
def apply_response_fixes(self, request, response):
"""
Applies each of the functions in self.response_fixes to the request and
diff -r a8a9a277716d django/core/handlers/modpython.py
--- a/django/core/handlers/modpython.py Tue Oct 05 01:44:12 2010 +0000
+++ b/django/core/handlers/modpython.py Wed Oct 06 13:53:51 2010 +0100
@@ -1,4 +1,3 @@
-import logging
import os
from pprint import pformat
import sys
@@ -10,8 +9,9 @@
from django.core.urlresolvers import set_script_prefix
from django.utils import datastructures
from django.utils.encoding import force_unicode, smart_str, iri_to_uri
+from django.utils.log import getLogger
-logger = logging.getLogger('django.request')
+logger = getLogger('django.request')
# NOTE: do *not* import settings (or any module which eventually imports
diff -r a8a9a277716d django/core/handlers/wsgi.py
--- a/django/core/handlers/wsgi.py Tue Oct 05 01:44:12 2010 +0000
+++ b/django/core/handlers/wsgi.py Wed Oct 06 13:53:51 2010 +0100
@@ -1,4 +1,3 @@
-import logging
from pprint import pformat
import sys
from threading import Lock
@@ -13,8 +12,9 @@
from django.core.urlresolvers import set_script_prefix
from django.utils import datastructures
from django.utils.encoding import force_unicode, iri_to_uri
+from django.utils.log import getLogger
-logger = logging.getLogger('django.request')
+logger = getLogger('django.request')
# See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
diff -r a8a9a277716d django/db/backends/util.py
--- a/django/db/backends/util.py Tue Oct 05 01:44:12 2010 +0000
+++ b/django/db/backends/util.py Wed Oct 06 13:53:51 2010 +0100
@@ -1,11 +1,11 @@
import datetime
import decimal
-import logging
from time import time
from django.utils.hashcompat import md5_constructor
+from django.utils.log import getLogger
-logger = logging.getLogger('django.db.backends')
+logger = getLogger('django.db.backends')
class CursorDebugWrapper(object):
def __init__(self, cursor, db):
diff -r a8a9a277716d django/middleware/common.py
--- a/django/middleware/common.py Tue Oct 05 01:44:12 2010 +0000
+++ b/django/middleware/common.py Wed Oct 06 13:53:51 2010 +0100
@@ -1,4 +1,3 @@
-import logging
import re
from django.conf import settings
@@ -7,8 +6,9 @@
from django.utils.http import urlquote
from django.core import urlresolvers
from django.utils.hashcompat import md5_constructor
+from django.utils.log import getLogger
-logger = logging.getLogger('django.request')
+logger = getLogger('django.request')
class CommonMiddleware(object):
diff -r a8a9a277716d django/middleware/csrf.py
--- a/django/middleware/csrf.py Tue Oct 05 01:44:12 2010 +0000
+++ b/django/middleware/csrf.py Wed Oct 06 13:53:51 2010 +0100
@@ -6,7 +6,6 @@
"""
import itertools
-import logging
import re
import random
@@ -14,6 +13,7 @@
from django.core.urlresolvers import get_callable
from django.utils.cache import patch_vary_headers
from django.utils.hashcompat import md5_constructor
+from django.utils.log import getLogger
from django.utils.safestring import mark_safe
_POST_FORM_RE = \
@@ -21,7 +21,7 @@
_HTML_TYPES = ('text/html', 'application/xhtml+xml')
-logger = logging.getLogger('django.request')
+logger = getLogger('django.request')
# Use the system (hardware-based) random number generator if it exists.
if hasattr(random, 'SystemRandom'):
diff -r a8a9a277716d django/utils/log.py
--- a/django/utils/log.py Tue Oct 05 01:44:12 2010 +0000
+++ b/django/utils/log.py Wed Oct 06 13:53:51 2010 +0100
@@ -1,4 +1,5 @@
import logging
+import sys
from django.core import mail
# Make sure a NullHandler is available
@@ -17,10 +18,32 @@
except ImportError:
from django.utils.dictconfig import dictConfig
+if sys.version_info < (2, 5):
+ class LoggerCompat(object):
+ def __init__(self, logger):
+ self._logger = logger
+
+ def __getattr__(self, name):
+ val = getattr(self._logger, name)
+ if callable(val):
+ def _wrapper(*args, **kwargs):
+ # Python 2.4 logging module doesn't support 'extra' parameter to
+ # methods of Logger
+ kwargs.pop('extra', None)
+ return val(*args, **kwargs)
+ return _wrapper
+ else:
+ return val
+
+ def getLogger(name=None):
+ return LoggerCompat(logging.getLogger(name=name))
+else:
+ getLogger = logging.getLogger
+
# Ensure the creation of the Django logger
# with a null handler. This ensures we don't get any
# 'No handlers could be found for logger "django"' messages
-logger = logging.getLogger('django')
+logger = getLogger('django')
if not logger.handlers:
logger.addHandler(NullHandler())
diff -r a8a9a277716d django/views/decorators/http.py
--- a/django/views/decorators/http.py Tue Oct 05 01:44:12 2010 +0000
+++ b/django/views/decorators/http.py Wed Oct 06 13:53:51 2010 +0100
@@ -10,16 +10,16 @@
from calendar import timegm
from datetime import timedelta
from email.Utils import formatdate
-import logging
from django.utils.decorators import decorator_from_middleware, available_attrs
from django.utils.http import parse_etags, quote_etag
+from django.utils.log import getLogger
from django.middleware.http import ConditionalGetMiddleware
from django.http import HttpResponseNotAllowed, HttpResponseNotModified, HttpResponse
conditional_page = decorator_from_middleware(ConditionalGetMiddleware)
-logger = logging.getLogger('django.request')
+logger = getLogger('django.request')
def require_http_methods(request_method_list):
diff -r a8a9a277716d django/views/generic/simple.py
--- a/django/views/generic/simple.py Tue Oct 05 01:44:12 2010 +0000
+++ b/django/views/generic/simple.py Wed Oct 06 13:53:51 2010 +0100
@@ -1,9 +1,8 @@
-import logging
-
from django.template import loader, RequestContext
from django.http import HttpResponse, HttpResponseRedirect, HttpResponsePermanentRedirect, HttpResponseGone
+from django.utils.log import getLogger
-logger = logging.getLogger('django.request')
+logger = getLogger('django.request')
def direct_to_template(request, template, extra_context=None, mimetype=None, **kwargs):