Add internal speed pages

This commit is contained in:
cuom1999 2023-03-07 01:19:45 -06:00
parent d5b21935ae
commit 92e2b45ada
7 changed files with 205 additions and 18 deletions

View file

@ -1069,6 +1069,26 @@ urlpatterns = [
internal.InternalProblem.as_view(),
name="internal_problem",
),
url(
r"^request_time$",
internal.InternalRequestTime.as_view(),
name="internal_request_time",
),
url(
r"^request_time_detail$",
internal.InternalRequestTimeDetail.as_view(),
name="internal_request_time_detail",
),
url(
r"^internal_slow_request$",
internal.InternalSlowRequest.as_view(),
name="internal_slow_request",
),
url(
r"^internal_slow_request_detail$",
internal.InternalSlowRequestDetail.as_view(),
name="internal_slow_request_detail",
),
]
),
),

View file

@ -1,5 +1,8 @@
import time
import logging
import random
import json
from datetime import datetime
from django.conf import settings
from django.http import HttpResponseRedirect, Http404
@ -148,17 +151,23 @@ class SlowRequestMiddleware(object):
self.get_response = get_response
def __call__(self, request):
logger = logging.getLogger("judge.slow_request")
logger = logging.getLogger("judge.request_time")
logger_slow = logging.getLogger("judge.slow_request")
start_time = time.time()
response = self.get_response(request)
response_time = time.time() - start_time
if response_time > 9:
url_name = resolve(request.path).url_name
message = {
"message": "Slow request",
"url": request.build_absolute_uri(),
"url_name": url_name,
"response_time": response_time * 1000,
"profile": request.user.username,
"date": datetime.now().strftime("%Y/%m/%d"),
"url": request.build_absolute_uri(),
"method": request.method,
"profile": request.profile,
}
logger.info(message)
if response_time > 9:
logger_slow.info(json.dumps(message))
if random.random() < 0.1:
logger.info(json.dumps(message))
return response

View file

@ -1,16 +1,27 @@
import logging
import json
from django.views.generic import ListView
from django.utils.translation import gettext as _, gettext_lazy
from django.db.models import Count
from django.http import HttpResponseForbidden
from django.urls import reverse
from judge.utils.diggpaginator import DiggPaginator
from judge.models import VolunteerProblemVote, Problem
class InternalProblem(ListView):
class InternalView(object):
def get(self, request, *args, **kwargs):
if request.user.is_superuser:
return super(InternalView, self).get(request, *args, **kwargs)
return HttpResponseForbidden()
class InternalProblem(ListView, InternalView):
model = Problem
title = _("Internal problems")
template_name = "internal/base.html"
template_name = "internal/problem.html"
paginate_by = 100
context_object_name = "problems"
@ -44,7 +55,87 @@ class InternalProblem(ListView):
return context
def get(self, request, *args, **kwargs):
if request.user.is_superuser:
return super(InternalProblem, self).get(request, *args, **kwargs)
class RequestTimeMixin(object):
def get_requests_data(self):
logger = logging.getLogger(self.log_name)
log_filename = logger.handlers[0].baseFilename
requests = []
with open(log_filename, "r") as f:
for line in f:
try:
info = json.loads(line)
requests.append(info)
except:
continue
return requests
class InternalRequestTime(ListView, InternalView, RequestTimeMixin):
title = _("Request times")
template_name = "internal/request_time.html"
context_object_name = "pages"
log_name = "judge.request_time"
detail_url_name = "internal_request_time_detail"
page_type = "request_time"
def get_queryset(self):
requests = self.get_requests_data()
table = {}
for r in requests:
url_name = r["url_name"]
if url_name not in table:
table[url_name] = {
"time": 0,
"count": 0,
"url_name": url_name,
"pattern": reverse(url_name) if url_name else None,
}
old_sum = table[url_name]["time"] * table[url_name]["count"]
table[url_name]["count"] += 1
table[url_name]["time"] = (old_sum + float(r["response_time"])) / table[
url_name
]["count"]
order = self.request.GET.get("order", "time")
return sorted(table.values(), key=lambda x: x[order], reverse=True)
def get_context_data(self, **kwargs):
context = super(InternalRequestTime, self).get_context_data(**kwargs)
context["page_type"] = self.page_type
context["title"] = self.title
context["current_path"] = self.request.path
context["detail_path"] = reverse(self.detail_url_name)
return context
class InternalRequestTimeDetail(InternalRequestTime):
template_name = "internal/request_time_detail.html"
context_object_name = "requests"
def get_queryset(self):
url_name = self.request.GET.get("url_name", None)
if not url_name:
return HttpResponseForbidden()
if url_name == "None":
url_name = None
self.title = url_name
requests = self.get_requests_data()
filtered_requests = [r for r in requests if r["url_name"] == url_name]
order = self.request.GET.get("order", "response_time")
return sorted(filtered_requests, key=lambda x: x[order], reverse=True)[:200]
def get_context_data(self, **kwargs):
context = super(InternalRequestTimeDetail, self).get_context_data(**kwargs)
context["url_name"] = self.request.GET.get("url_name", None)
return context
class InternalSlowRequest(InternalRequestTime):
log_name = "judge.slow_request"
detail_url_name = "internal_slow_request_detail"
page_type = "slow_request"
class InternalSlowRequestDetail(InternalRequestTimeDetail):
log_name = "judge.slow_request"

View file

@ -0,0 +1,5 @@
<div class="left-sidebar">
{{ make_tab_item('problem', 'fa fa-list', url('internal_problem'), _('Problem')) }}
{{ make_tab_item('request_time', 'fa fa-angle-right', url('internal_request_time'), _('Average speed')) }}
{{ make_tab_item('slow_request', 'fa fa-asterisk', url('internal_slow_request'), _('Slow requests')) }}
</div>

View file

@ -25,9 +25,7 @@
{% endblock %}
{% block left_sidebar %}
<div class="left-sidebar">
{{ make_tab_item('problem', 'fa fa-list', url('internal_problem'), _('Problem')) }}
</div>
{% include "internal/left-sidebar.html" %}
{% endblock %}
{% block middle_content %}

View file

@ -0,0 +1,28 @@
{% extends "two-column-content.html" %}
{% block left_sidebar %}
{% include "internal/left-sidebar.html" %}
{% endblock %}
{% block middle_content %}
<table class="table">
<thead>
<tr>
<th>URL Name</th>
<th>Pattern</th>
<th><a href="{{current_path}}?order=time">Time (ms)</a></th>
<th><a href="{{current_path}}?order=count">Count</a></th>
</tr>
</thead>
<tbody>
{% for page in pages %}
<tr>
<td><a href="{{detail_path}}?url_name={{page['url_name']}}">{{page['url_name']}}</a></td>
<td>{{page['pattern']}}</td>
<td>{{page['time'] | floatformat(2)}}</td>
<td>{{page['count']}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View file

@ -0,0 +1,36 @@
{% extends "two-column-content.html" %}
{% block left_sidebar %}
{% include "internal/left-sidebar.html" %}
{% endblock %}
{% block middle_content %}
<table class="table">
<thead>
<tr>
<th>Profile</th>
<th>URL</th>
<th>Method</th>
<th><a href="{{current_path}}?order=response_time&url_name={{url_name}}">Time (ms)</a></th>
<th><a href="{{current_path}}?order=date&url_name={{url_name}}">Date</a></th>
</tr>
</thead>
<tbody>
{% for request in requests %}
<tr>
<td>
{% if request['profile'] %}
<a href="/user/{{request['profile']}}">{{request['profile']}}</a>
{% else %}
None
{% endif %}
</td>
<td>{{request['url']}}</td>
<td>{{request['method']}}</td>
<td>{{request['response_time'] | floatformat(2)}}</td>
<td>{{request['date']}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}