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