from datetime import datetime
import os
import re
import sys
import urllib
import urllib2
from django.conf import settings
from django.http import Http404
class FileLogMiddleware(object):
"""Report Django exceptions to a file
Only used for licensed Kiln installs, so that people don't worry
about what data is getting sent back to Fog Creek."""
def process_response(self, request, response):
if response.status_code == 404:
domain = request.get_host()
referer = request.META.get('HTTP_REFERER', None)
path = request.get_full_path()
is_internal = _is_internal_request(domain, referer)
if referer and not _is_ignorable_404(path) and is_internal:
ua = request.META.get('HTTP_USER_AGENT', '<none>')
ip = request.META.get('REMOTE_ADDR', '<none>')
bug = {'Description': 'Broken %slink %s on %s' % ((is_internal and 'INTERNAL ' or ''), request.path, domain),
'Extra': 'Referrer: %s\nRequested URL: %s\nUser agent:%s\nIP address: %s\n' \
% (referer, request.get_full_path(), ua, ip)}
_log_error(bug)
return response
def process_exception(self, request, exception):
bug = {}
bug["Description"] = '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'
bug["Extra"] = '%s\n\n%s' % (_get_traceback(sys.exc_info()), request_repr)
_log_error(bug)
def _get_traceback(exc_info):
"""Helper function to return the traceback as a string"""
import traceback
return '\n'.join(traceback.format_exception(*(exc_info or sys.exc_info())))
def _is_internal_request(domain, referer):
"""Returns true if the referring URL is the same domain as the current
request."""
return referer is not None and re.match("^https?://%s/" % re.escape(domain), referer)
def _is_ignorable_404(uri):
"""Returns True if a 404 at the given URL *shouldn't* notify the site
managers."""
for start in settings.IGNORABLE_404_STARTS:
if uri.startswith(start):
return True
for end in settings.IGNORABLE_404_ENDS:
if uri.endswith(end):
return True
return False
def _log_error(bug):
times = '='
plus = '\n'
with open(os.path.join(settings.KILN_REPOSITORY_ROOT, r'errors.txt'), 'a') as f:
f.write('%s\n' % datetime.utcnow().isoformat())
f.write(bug['Description'])
f.write('\n\n')
f.write(bug['Extra'])
f.write(plus * 2 + times * 78 + plus * 3)
|
Loading...