Add internal speed pages
This commit is contained in:
parent
d5b21935ae
commit
92e2b45ada
7 changed files with 205 additions and 18 deletions
20
dmoj/urls.py
20
dmoj/urls.py
|
@ -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",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -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
|
||||||
|
url_name = resolve(request.path).url_name
|
||||||
|
|
||||||
|
message = {
|
||||||
|
"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,
|
||||||
|
}
|
||||||
if response_time > 9:
|
if response_time > 9:
|
||||||
message = {
|
logger_slow.info(json.dumps(message))
|
||||||
"message": "Slow request",
|
if random.random() < 0.1:
|
||||||
"url": request.build_absolute_uri(),
|
logger.info(json.dumps(message))
|
||||||
"response_time": response_time * 1000,
|
|
||||||
"method": request.method,
|
|
||||||
"profile": request.profile,
|
|
||||||
}
|
|
||||||
logger.info(message)
|
|
||||||
return response
|
return response
|
||||||
|
|
|
@ -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):
|
||||||
return HttpResponseForbidden()
|
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"
|
||||||
|
|
5
templates/internal/left-sidebar.html
Normal file
5
templates/internal/left-sidebar.html
Normal 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>
|
|
@ -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 %}
|
28
templates/internal/request_time.html
Normal file
28
templates/internal/request_time.html
Normal 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 %}
|
36
templates/internal/request_time_detail.html
Normal file
36
templates/internal/request_time_detail.html
Normal 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 %}
|
Loading…
Reference in a new issue