feat: Add simple profiler capability
This commit is contained in:
@@ -37,6 +37,26 @@
|
|||||||
{% block header %}
|
{% block header %}
|
||||||
{% include "fellchensammlung/header.html" %}
|
{% include "fellchensammlung/header.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
{% if profile %}
|
||||||
|
<div class="profile">
|
||||||
|
<table class="table is-bordered is-fullwidth is-hoverable is-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>Timestamp</td>
|
||||||
|
<td>Status</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for status in profile %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ status.0 }}</td>
|
||||||
|
<td>{{ status.1 }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
<div class="main-content">
|
<div class="main-content">
|
||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import datetime as datetime
|
import datetime as datetime
|
||||||
import logging
|
import logging
|
||||||
|
import time
|
||||||
|
|
||||||
from django.utils.translation import ngettext
|
from django.utils.translation import ngettext
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
@@ -75,3 +76,20 @@ def is_404(url):
|
|||||||
return result.status_code == 404
|
return result.status_code == 404
|
||||||
except requests.RequestException as e:
|
except requests.RequestException as e:
|
||||||
logging.warning(f"Request to {url} failed: {e}")
|
logging.warning(f"Request to {url} failed: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
class RequestProfiler:
|
||||||
|
data = []
|
||||||
|
|
||||||
|
def add_status(self, status):
|
||||||
|
self.data.append((time.time(), status))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def as_relative(self):
|
||||||
|
first_ts = self.data[0][0]
|
||||||
|
return [(datum[0] - first_ts, datum[1]) for datum in self.data]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def as_relative_with_ms(self):
|
||||||
|
first_ts = self.data[0][0]
|
||||||
|
return [(f"{(datum[0] - first_ts)*1000:.4}ms", datum[1]) for datum in self.data]
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import logging
|
import logging
|
||||||
from datetime import timedelta
|
|
||||||
|
|
||||||
from django.contrib.auth.views import redirect_to_login
|
from django.contrib.auth.views import redirect_to_login
|
||||||
from django.core.paginator import Paginator
|
from django.core.paginator import Paginator
|
||||||
@@ -37,6 +36,7 @@ from .tools.admin import clean_locations, get_unchecked_adoption_notices, deacti
|
|||||||
from .tasks import post_adoption_notice_save
|
from .tasks import post_adoption_notice_save
|
||||||
from rest_framework.authtoken.models import Token
|
from rest_framework.authtoken.models import Token
|
||||||
|
|
||||||
|
from .tools.misc import RequestProfiler
|
||||||
from .tools.model_helpers import AdoptionNoticeStatusChoices, AdoptionNoticeProcessTemplates, RegularCheckStatusChoices
|
from .tools.model_helpers import AdoptionNoticeStatusChoices, AdoptionNoticeProcessTemplates, RegularCheckStatusChoices
|
||||||
from .tools.search import AdoptionNoticeSearch, RescueOrgSearch
|
from .tools.search import AdoptionNoticeSearch, RescueOrgSearch
|
||||||
|
|
||||||
@@ -242,11 +242,17 @@ def search_important_locations(request, important_location_slug):
|
|||||||
|
|
||||||
|
|
||||||
def search(request, templatename="fellchensammlung/search.html"):
|
def search(request, templatename="fellchensammlung/search.html"):
|
||||||
|
search_profile = RequestProfiler()
|
||||||
|
search_profile.add_status("Start")
|
||||||
|
|
||||||
# A user just visiting the search site did not search, only upon completing the search form a user has really
|
# A user just visiting the search site did not search, only upon completing the search form a user has really
|
||||||
# searched. This will toggle the "subscribe" button
|
# searched. This will toggle the "subscribe" button
|
||||||
searched = False
|
searched = False
|
||||||
|
search_profile.add_status("Init Search")
|
||||||
search = AdoptionNoticeSearch()
|
search = AdoptionNoticeSearch()
|
||||||
|
search_profile.add_status("Search from request starting")
|
||||||
search.adoption_notice_search_from_request(request)
|
search.adoption_notice_search_from_request(request)
|
||||||
|
search_profile.add_status("Search from request finished")
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
searched = True
|
searched = True
|
||||||
if "subscribe_to_search" in request.POST:
|
if "subscribe_to_search" in request.POST:
|
||||||
@@ -266,10 +272,12 @@ def search(request, templatename="fellchensammlung/search.html"):
|
|||||||
subscribed_search = search.get_subscription_or_none(request.user)
|
subscribed_search = search.get_subscription_or_none(request.user)
|
||||||
else:
|
else:
|
||||||
subscribed_search = None
|
subscribed_search = None
|
||||||
|
search_profile.add_status("End of POST")
|
||||||
site_title = _("Suche")
|
site_title = _("Suche")
|
||||||
site_description = _("Ratten in Tierheimen und Rattenhilfen in der Nähe suchen.")
|
site_description = _("Ratten in Tierheimen und Rattenhilfen in der Nähe suchen.")
|
||||||
canonical_url = reverse("search")
|
canonical_url = reverse("search")
|
||||||
|
|
||||||
|
search_profile.add_status("Start of context")
|
||||||
context = {"adoption_notices": search.get_adoption_notices(),
|
context = {"adoption_notices": search.get_adoption_notices(),
|
||||||
"search_form": search.search_form,
|
"search_form": search.search_form,
|
||||||
"place_not_found": search.place_not_found,
|
"place_not_found": search.place_not_found,
|
||||||
@@ -286,6 +294,10 @@ def search(request, templatename="fellchensammlung/search.html"):
|
|||||||
"site_title": site_title,
|
"site_title": site_title,
|
||||||
"site_description": site_description,
|
"site_description": site_description,
|
||||||
"canonical_url": canonical_url}
|
"canonical_url": canonical_url}
|
||||||
|
search_profile.add_status("End of context")
|
||||||
|
if request.user.is_superuser:
|
||||||
|
context["profile"] = search_profile.as_relative_with_ms
|
||||||
|
search_profile.add_status("Finished - returing render")
|
||||||
return render(request, templatename, context=context)
|
return render(request, templatename, context=context)
|
||||||
|
|
||||||
|
|
||||||
@@ -578,12 +590,20 @@ def report_detail_success(request, report_id):
|
|||||||
|
|
||||||
|
|
||||||
def user_detail(request, user, token=None):
|
def user_detail(request, user, token=None):
|
||||||
|
user_detail_profile = RequestProfiler()
|
||||||
|
user_detail_profile.add_status("Start")
|
||||||
|
adoption_notices = AdoptionNotice.objects.filter(owner=user)
|
||||||
|
user_detail_profile.add_status("Finished fetching adoption notices")
|
||||||
context = {"user": user,
|
context = {"user": user,
|
||||||
"adoption_notices": AdoptionNotice.objects.filter(owner=user),
|
"adoption_notices": adoption_notices,
|
||||||
"notifications": Notification.objects.filter(user_to_notify=user, read=False),
|
"notifications": Notification.objects.filter(user_to_notify=user, read=False),
|
||||||
"search_subscriptions": SearchSubscription.objects.filter(owner=user), }
|
"search_subscriptions": SearchSubscription.objects.filter(owner=user), }
|
||||||
|
user_detail_profile.add_status("End of context")
|
||||||
if token is not None:
|
if token is not None:
|
||||||
context["token"] = token
|
context["token"] = token
|
||||||
|
user_detail_profile.add_status("Finished - returning to renderer")
|
||||||
|
if request.user.is_superuser:
|
||||||
|
context["profile"] = user_detail_profile.as_relative_with_ms
|
||||||
return render(request, 'fellchensammlung/details/detail-user.html', context=context)
|
return render(request, 'fellchensammlung/details/detail-user.html', context=context)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user