impuls/lib/python3.11/site-packages/debug_toolbar/panels/timer.py

107 lines
4.1 KiB
Python

from time import perf_counter
from django.template.loader import render_to_string
from django.templatetags.static import static
from django.utils.translation import gettext_lazy as _
from debug_toolbar.panels import Panel
try:
import resource # Not available on Win32 systems
except ImportError:
resource = None
class TimerPanel(Panel):
"""
Panel that displays the time a response took in milliseconds.
"""
def nav_subtitle(self):
stats = self.get_stats()
if hasattr(self, "_start_rusage"):
utime = self._end_rusage.ru_utime - self._start_rusage.ru_utime
stime = self._end_rusage.ru_stime - self._start_rusage.ru_stime
return _("CPU: %(cum)0.2fms (%(total)0.2fms)") % {
"cum": (utime + stime) * 1000.0,
"total": stats["total_time"],
}
elif "total_time" in stats:
return _("Total: %0.2fms") % stats["total_time"]
else:
return ""
has_content = resource is not None
title = _("Time")
template = "debug_toolbar/panels/timer.html"
@property
def content(self):
stats = self.get_stats()
rows = (
(_("User CPU time"), _("%(utime)0.3f msec") % stats),
(_("System CPU time"), _("%(stime)0.3f msec") % stats),
(_("Total CPU time"), _("%(total)0.3f msec") % stats),
(_("Elapsed time"), _("%(total_time)0.3f msec") % stats),
(
_("Context switches"),
_("%(vcsw)d voluntary, %(ivcsw)d involuntary") % stats,
),
)
return render_to_string(self.template, {"rows": rows})
@property
def scripts(self):
scripts = super().scripts
scripts.append(static("debug_toolbar/js/timer.js"))
return scripts
def process_request(self, request):
self._start_time = perf_counter()
if self.has_content:
self._start_rusage = resource.getrusage(resource.RUSAGE_SELF)
return super().process_request(request)
def generate_stats(self, request, response):
stats = {}
if hasattr(self, "_start_time"):
stats["total_time"] = (perf_counter() - self._start_time) * 1000
if hasattr(self, "_start_rusage"):
self._end_rusage = resource.getrusage(resource.RUSAGE_SELF)
stats["utime"] = 1000 * self._elapsed_ru("ru_utime")
stats["stime"] = 1000 * self._elapsed_ru("ru_stime")
stats["total"] = stats["utime"] + stats["stime"]
stats["vcsw"] = self._elapsed_ru("ru_nvcsw")
stats["ivcsw"] = self._elapsed_ru("ru_nivcsw")
stats["minflt"] = self._elapsed_ru("ru_minflt")
stats["majflt"] = self._elapsed_ru("ru_majflt")
# these are documented as not meaningful under Linux. If you're
# running BSD feel free to enable them, and add any others that I
# hadn't gotten to before I noticed that I was getting nothing but
# zeroes and that the docs agreed. :-(
#
# stats['blkin'] = self._elapsed_ru('ru_inblock')
# stats['blkout'] = self._elapsed_ru('ru_oublock')
# stats['swap'] = self._elapsed_ru('ru_nswap')
# stats['rss'] = self._end_rusage.ru_maxrss
# stats['srss'] = self._end_rusage.ru_ixrss
# stats['urss'] = self._end_rusage.ru_idrss
# stats['usrss'] = self._end_rusage.ru_isrss
self.record_stats(stats)
def generate_server_timing(self, request, response):
stats = self.get_stats()
self.record_server_timing("utime", "User CPU time", stats.get("utime", 0))
self.record_server_timing("stime", "System CPU time", stats.get("stime", 0))
self.record_server_timing("total", "Total CPU time", stats.get("total", 0))
self.record_server_timing(
"total_time", "Elapsed time", stats.get("total_time", 0)
)
def _elapsed_ru(self, name):
return getattr(self._end_rusage, name) - getattr(self._start_rusage, name)