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(), internal.InternalProblem.as_view(),
name="internal_problem", 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 time
import logging import logging
import random
import json
from datetime import datetime
from django.conf import settings from django.conf import settings
from django.http import HttpResponseRedirect, Http404 from django.http import HttpResponseRedirect, Http404
@ -148,17 +151,23 @@ class SlowRequestMiddleware(object):
self.get_response = get_response self.get_response = get_response
def __call__(self, request): 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() start_time = time.time()
response = self.get_response(request) response = self.get_response(request)
response_time = time.time() - start_time response_time = time.time() - start_time
if response_time > 9: url_name = resolve(request.path).url_name
message = { message = {
"message": "Slow request", "url_name": url_name,
"url": request.build_absolute_uri(),
"response_time": response_time * 1000, "response_time": response_time * 1000,
"profile": request.user.username,
"date": datetime.now().strftime("%Y/%m/%d"),
"url": request.build_absolute_uri(),
"method": request.method, "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 return response

View file

@ -1,16 +1,27 @@
import logging
import json
from django.views.generic import ListView from django.views.generic import ListView
from django.utils.translation import gettext as _, gettext_lazy from django.utils.translation import gettext as _, gettext_lazy
from django.db.models import Count from django.db.models import Count
from django.http import HttpResponseForbidden from django.http import HttpResponseForbidden
from django.urls import reverse
from judge.utils.diggpaginator import DiggPaginator from judge.utils.diggpaginator import DiggPaginator
from judge.models import VolunteerProblemVote, Problem 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 model = Problem
title = _("Internal problems") title = _("Internal problems")
template_name = "internal/base.html" template_name = "internal/problem.html"
paginate_by = 100 paginate_by = 100
context_object_name = "problems" context_object_name = "problems"
@ -44,7 +55,87 @@ class InternalProblem(ListView):
return context return context
def get(self, request, *args, **kwargs):
if request.user.is_superuser: class RequestTimeMixin(object):
return super(InternalProblem, self).get(request, *args, **kwargs) 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() 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 %} {% endblock %}
{% block left_sidebar %} {% block left_sidebar %}
<div class="left-sidebar"> {% include "internal/left-sidebar.html" %}
{{ make_tab_item('problem', 'fa fa-list', url('internal_problem'), _('Problem')) }}
</div>
{% endblock %} {% endblock %}
{% block middle_content %} {% 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 %}