Skip to content

Instantly share code, notes, and snippets.

@danizen
Last active December 11, 2023 07:59
Show Gist options
  • Save danizen/d92b0705eb526c74d2022897ff94f401 to your computer and use it in GitHub Desktop.
Save danizen/d92b0705eb526c74d2022897ff94f401 to your computer and use it in GitHub Desktop.
Django middleware to collect slow queries using force_debug_cursor
import logging
import time
from django.conf import settings
from django.db import connection
THRESHOLD = getattr(settings, 'SLOW_REQUEST_THRESHOLD', 1.0)
LOG_SQL = getattr(settings, 'SLOW_REQUEST_LOG_SQL', False)
LOG = logging.getLogger(__name__)
class SlowRequestMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
self.before(request)
response = self.get_response(request)
self.after(request)
return response
def before(self, request):
self.start = time.perf_counter()
# NOTE: probably better to monkey patch
connection.force_debug_cursor = True
def after(self, request):
# create metrics
duration = time.perf_counter() - self.start
queries_time = (float(q['time']) for q in connection.queries_log)
query_time = sum(queries_time, 0.0)
# check whether to log
if duration > THRESHOLD or query_time > THRESHOLD:
LOG.warning('%s %s: duration=%.3f, num_queries=%d, query_time=%.3f',
request.method,
request.path,
duration,
len(connection.queries_log),
query_time)
if LOG_SQL:
for query in connection.queries_log:
LOG.warning(
'(%s) %s', query['time'], query['sql']
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment