zulip/zephyr/middleware.py

82 lines
2.9 KiB
Python

from django.conf import settings
from decorator import RequestVariableMissingError, RequestVariableConversionError
from zephyr.lib.response import json_error
from django.db import connection
import logging
import time
logger = logging.getLogger('humbug.requests')
class LogRequests(object):
def process_request(self, request):
request._time_started = time.time()
def process_response(self, request, response):
# The reverse proxy might have sent us the real external IP
remote_ip = request.META.get('HTTP_X_REAL_IP')
if remote_ip is None:
remote_ip = request.META['REMOTE_ADDR']
time_delta = -1
# A time duration of -1 means the StartLogRequests middleware
# didn't run for some reason
if hasattr(request, '_time_started'):
time_delta = time.time() - request._time_started
# Get the amount of time spent doing database queries
query_time = sum(float(query.get('time', 0)) for query in connection.queries)
# Get the requestor's email address and client, if available.
try:
email = request._email
except Exception:
email = "unauth"
try:
client = request._client.name
except Exception:
client = "?"
logger.info('%-15s %-7s %3d %.3fs (db: %.3fs/%sq) %s (%s via %s)'
% (remote_ip, request.method, response.status_code,
time_delta, query_time, len(connection.queries),
request.get_full_path(), email, client))
# Log some additional data whenever we return certain 40x errors
if 400 <= response.status_code < 500 and response.status_code not in [401, 404, 405]:
content = response.content
if len(content) > 100:
content = "[content more than 100 characters]"
logger.info('status=%3d, data=%s, uid=%s' % (response.status_code, content, email))
return response
class JsonErrorHandler(object):
def process_exception(self, request, exception):
if hasattr(exception, 'to_json_error_msg') and callable(exception.to_json_error_msg):
return json_error(exception.to_json_error_msg())
return None
# Monkeypatch in time tracking to the Django non-debug cursor
# Code comes from CursorDebugWrapper
def wrapper_execute(self, action, sql, params=()):
self.set_dirty()
start = time.time()
try:
return action(sql, params)
finally:
stop = time.time()
duration = stop - start
self.db.queries.append({
'time': "%.3f" % duration,
})
from django.db.backends.util import CursorWrapper
def cursor_execute(self, sql, params=()):
return wrapper_execute(self, self.cursor.execute, sql, params)
CursorWrapper.execute = cursor_execute
def cursor_executemany(self, sql, params=()):
return wrapper_execute(self, self.cursor.executemany, sql, params)
CursorWrapper.executemany = cursor_executemany