Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement new list view for requests on start page #710

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions silk/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
from django.conf import settings
from django.db import models, transaction
from django.db.models import (
Avg,
BooleanField,
CharField,
Count,
DateTimeField,
FileField,
FloatField,
Expand All @@ -19,12 +21,15 @@
OneToOneField,
TextField,
)
from django.shortcuts import render
from django.utils import timezone
from django.utils.safestring import mark_safe

from silk.config import SilkyConfig
from silk.utils.profile_parser import parse_profile

from .models import Request

try:
# New in Django 4.2
from django.core.files.storage import storages
Expand Down Expand Up @@ -203,6 +208,41 @@ def save(self, *args, **kwargs):
super().save(*args, **kwargs)
Request.garbage_collect(force=False)

def summary_view(request):
num_requests = Request.objects.count()
avg_overall_time = Request.objects.aggregate(Avg('time_taken'))['time_taken__avg'] or 0
avg_num_queries = Request.objects.aggregate(Avg('meta_num_queries'))['meta_num_queries__avg'] or 0
avg_time_spent_on_queries = Request.objects.aggregate(Avg('meta_time_spent_queries'))['meta_time_spent_queries__avg'] or 0

longest_queries_by_view = Request.objects.order_by('-time_taken')[:10]
most_time_spent_in_db = Request.objects.order_by('-meta_time_spent_queries')[:10]
most_queries = Request.objects.order_by('-meta_num_queries')[:10]

options_view_style = [{'value': 'row', 'label': 'Row'}, {'value': 'grid', 'label': 'Grid'}]
options_show = [25, 50, 100]
options_order_by = [{'value': 'start_time', 'label': 'Start Time'}, {'value': 'time_taken', 'label': 'Time Taken'}]
options_order_dir = [{'value': 'asc', 'label': 'Ascending'}, {'value': 'desc', 'label': 'Descending'}]

context = {
'num_requests': num_requests,
'avg_overall_time': avg_overall_time,
'avg_num_queries': avg_num_queries,
'avg_time_spent_on_queries': avg_time_spent_on_queries,
'longest_queries_by_view': longest_queries_by_view,
'most_time_spent_in_db': most_time_spent_in_db,
'most_queries': most_queries,
'view_style': request.GET.get('view_style', 'row'),
'show': request.GET.get('show', 25),
'order_by': request.GET.get('order_by', 'start_time'),
'order_dir': request.GET.get('order_dir', 'asc'),
'options_view_style': options_view_style,
'options_show': options_show,
'options_order_by': options_order_by,
'options_order_dir': options_order_dir,
}

return render(request, 'silk/summary.html', context)


class Response(models.Model):
id = CharField(max_length=36, default=uuid4, primary_key=True)
Expand Down
243 changes: 147 additions & 96 deletions silk/templates/silk/summary.html
Original file line number Diff line number Diff line change
@@ -1,148 +1,199 @@
{% extends 'silk/base/root_base.html' %}
{% load silk_inclusion %}
{% load static %}
{% block menu %}
{% root_menu request %}
{% endblock %}

{% block pagetitle %}Silky - Summary{% endblock %}

{% block style %}
{{ block.super }}
<link rel="stylesheet" href="{% static 'silk/css/pages/summary.css' %}"/>
<link rel="stylesheet" href="{% static 'silk/css/pages/requests.css' %}"/>
<style>
.row-wrapper {
display: flex;
flex-direction: column;
margin-top: 20px;
}

.row {
display: flex;
justify-content: space-between;
padding: 10px;
border: 1px solid #ddd;
margin-bottom: 5px;
background-color: #fff; /* Ensuring rows have a white background */
color: #000; /* Ensuring text color is black */
border-radius: 5px;
}

.row div {
flex: 1;
text-align: center;
}

.summary-cell {
display: inline-block;
width: 18%;
text-align: center;
margin: 10px 1%;
}

.summary-cell .num {
font-size: 24px;
}

.no-data {
text-align: center;
font-size: 18px;
color: #888;
}
</style>
{% endblock %}

{% block menu %}
{% root_menu request %}
{% endblock %}

{% block js %}
{{ block.super }}
<script src="{% static 'silk/js/pages/summary.js' %}"></script>
<script src="{% static 'silk/js/pages/requests.js' %}"></script>
{% endblock %}

{% block filter %}
<form id="filter-form" action="." method="get"></form>
<div class="menu-item ">
<div class="menu-item-outer">
<div class="menu-item-inner">
<label>View:
<select name="view_style" form="filter-form" onchange="this.form.submit();">
{% for option in options_view_style %}
<option value="{{ option.value }}"
{% if option.value == view_style %}selected{% endif %}>{{ option.label }}</option>
{% endfor %}
</select>
</label>
</div>
</div>
</div>
<div class="menu-item ">
<div class="menu-item-outer">
<div class="menu-item-inner">
<label>Show:
<select name="show" form="filter-form" onchange="this.form.submit();">
{% for option in options_show %}
<option value="{{ option }}"
{% if option == show %}selected{% endif %}>{{ option }}</option>
{% endfor %}
</select>
</label>
</div>
</div>
</div>
<div class="menu-item">
<div class="menu-item-outer">
<div class="menu-item-inner">
<label>Order:
<select name="order_by" form="filter-form" onchange="this.form.submit();">
{% for option in options_order_by %}
<option value="{{ option.value }}"
{% if option.value == order_by %}selected{% endif %}>{{ option.label }}</option>
{% endfor %}
</select>
</label>
</div>
</div>
</div>
<div class="menu-item">
<div class="menu-item-outer">
<div class="menu-item-inner">
<label>Order:
<select name="order_dir" form="filter-form" onchange="this.form.submit();">
{% for option in options_order_dir %}
<option value="{{ option.value }}"
{% if option.value == order_dir %}selected{% endif %}>{{ option.label }}</option>
{% endfor %}
</select>
</label>
</div>
</div>
</div>
{{ block.super }}
{% endblock %}

{% block data %}
<div class="wrapper">
<div class="inner">
<div id="filters">
<form action="." name="filter-form" id="filter-form" method="post">
{% csrf_token %}
</form>
<table id="filter-table">
<tr>
<td>
<img id="filter-image" src="{% static 'silk/filter2.png' %}">

</td>
<td id="filter-cell">
<div class="resizing-input">
Using requests that executed
<input form="filter-form"
class="typ"
type="hidden"
value="SecondsFilter"
name="filter-seconds-typ">
<input type="text"
placeholder="seconds"
form="filter-form"
name="filter-seconds-value"
value="{{ filters.seconds.value }}"
>
seconds ago,
<span style="display:none"></span>
</div>
<div class="resizing-input">
before
<input form="filter-form"
class="typ"
type="hidden"
value="BeforeDateFilter"
name="filter-beforedate-typ">
<input class="datetimepicker"
type="text"
placeholder="date"
form="filter-form"
name="filter-beforedate-value"
value="{{ filters.beforedate.value }}"
/>,
<span style="display:none"></span>
</div>
<div class="resizing-input">
and after
<input form="filter-form"
class="typ"
type="hidden"
value="AfterDateFilter"
name="filter-afterdate-typ">
<input class="datetimepicker"
type="text"
placeholder="date"
form="filter-form"
name="filter-afterdate-value"
value="{{ filters.afterdate.value }}"
>.
<span style="display:none"></span>
</div>
</td>
</tr>
</table>

</div>
<h2>Summary</h2>
{% if num_requests %}
<div class="summary-cell">
<div class="num"><span class="numeric">{{ num_requests }}</span></div>
<div class="desc">Requests</div>
</div>
<div class="summary-cell">
<div class="num"><span class="numeric">{{ num_profiles }}</span></div>
<div class="desc">Profiles</div>
</div>
<div class="summary-cell">
<div class="num"><span class="numeric">{{ avg_overall_time | floatformat:0 }}<span class="unit">ms</span></span></div>
<div class="num"><span class="numeric">{{ avg_overall_time|floatformat:0 }}<span class="unit">ms</span></span></div>
<div class="desc">Avg. Time</div>
</div>
<div class="summary-cell">
<div class="num"><span class="numeric">{{ avg_num_queries | floatformat:2 }}</span></div>
<div class="num"><span class="numeric">{{ avg_num_queries|floatformat:2 }}</span></div>
<div class="desc">Avg. #Queries</div>
</div>
<div class="summary-cell">
<div class="num"><span class="numeric">{{ avg_time_spent_on_queries |floatformat:0 }}<span class="unit">ms</span></span></div>
<div class="num"><span class="numeric">{{ avg_time_spent_on_queries|floatformat:0 }}<span class="unit">ms</span></span></div>
<div class="desc">Avg. DB Time</div>
</div>
{% else %}
<p class="no-data">No data</p>
{% endif %}

<h2>Most Time Overall</h2>
{% if longest_queries_by_view %}
{% for x in longest_queries_by_view %}
<a href="{% url "silk:request_detail" request_id=x.pk %}">
{% request_summary x %}
</a>
{% endfor %}
<div class="row-wrapper">
{% for x in longest_queries_by_view %}
<a href="{% url 'silk:request_detail' request_id=x.pk %}" class="row">
<div>{{ x.start_time }}</div>
<div>{{ x.path }}</div>
<div>{{ x.meta_num_queries }} queries</div>
<div>{{ x.time_taken }} ms</div>
<div>{{ x.meta_time_spent_queries }} ms</div>
</a>
{% endfor %}
</div>
{% else %}
<p class="no-data">No data</p>
{% endif %}

<h2>Most Time Spent in Database</h2>
{% if most_time_spent_in_db %}
{% for x in most_time_spent_in_db %}
<a href="{% url "silk:request_detail" request_id=x.pk %}">
{% request_summary x %}
</a>
{% endfor %}
<div class="row-wrapper">
{% for x in most_time_spent_in_db %}
<a href="{% url 'silk:request_detail' request_id=x.pk %}" class="row">
<div>{{ x.start_time }}</div>
<div>{{ x.path }}</div>
<div>{{ x.meta_num_queries }} queries</div>
<div>{{ x.time_taken }} ms</div>
<div>{{ x.meta_time_spent_queries }} ms</div>
</a>
{% endfor %}
</div>
{% else %}
<p class="no-data">No data</p>
{% endif %}

<h2>Most Database Queries</h2>
{% if most_queries %}
{% for x in most_queries %}
<a href="{% url "silk:request_detail" request_id=x.pk %}">
{% request_summary x %}
</a>
{% endfor %}
<div class="row-wrapper">
{% for x in most_queries %}
<a href="{% url 'silk:request_detail' request_id=x.pk %}" class="row">
<div>{{ x.start_time }}</div>
<div>{{ x.path }}</div>
<div>{{ x.meta_num_queries }} queries</div>
<div>{{ x.time_taken }} ms</div>
<div>{{ x.meta_time_spent_queries }} ms</div>
</a>
{% endfor %}
</div>
{% else %}
<p class="no-data">No data</p>
{% endif %}
</div>
</div>

{% endblock %}

{# Hide filter hamburger menu #}
{% block top %}{% endblock %}
{% block filter %}{% endblock %}
Loading