0
0
Fork 0
mirror of https://github.com/healthchecks/healthchecks.git synced 2025-04-05 05:15:26 +00:00

Improve performance of loading ping body previews

Defer loading body_raw, instead load its first 150 bytes
as "body_raw_preview". This reduces both network I/O to database,
and disk I/O on the database host if the database contains large
request bodies.

cc: 
This commit is contained in:
Pēteris Caune 2024-07-11 17:38:25 +03:00
parent 3e5080d9eb
commit 1b695c6970
No known key found for this signature in database
GPG key ID: E28D7679E9A9EDE2
4 changed files with 15 additions and 1 deletions
CHANGELOG.md
hc/front
templates/front

View file

@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file.
## v3.5-dev - Unreleased
### Improvements
- Improve performance of loading ping body previews (#1023)
### Bug Fixes
- Fix Check.ping() to lock the check before updating (#1023)

View file

@ -282,3 +282,8 @@ def fix_asterisks(s: str) -> str:
@register.filter
def pct(v: float) -> str:
return str(int(v * 10000) / 100)
@register.filter
def decode(v: bytes) -> str:
return bytes(v).decode(errors="replace")

View file

@ -26,6 +26,7 @@ from django.contrib.auth.models import User
from django.core import signing
from django.core.exceptions import PermissionDenied
from django.db.models import Case, Count, F, Q, QuerySet, When
from django.db.models.functions import Substr
from django.http import (
Http404,
HttpRequest,
@ -867,6 +868,11 @@ def _get_events(
kinds_filter = kinds_filter | Q(kind__isnull=True) | Q(kind="")
pq = pq.filter(kinds_filter)
# Optimization: defer loading body_raw, instead load its first 150 bytes
# as "body_raw_preview". This reduces both network I/O to database, and disk I/O
# on the database host if the database contains large request bodies.
pq = pq.defer("body_raw")
pq = pq.annotate(body_raw_preview=Substr("body_raw", 1, 151))
pings = list(pq[:page_limit])
# Optimization: the template will access Ping.duration, which would generate a

View file

@ -17,7 +17,7 @@
{% if event.rid %}<span class="label rid">{{ event.rid|first5 }}</span> {% endif %}
{% if event.scheme == "email" %}{{ event.ua }}{% else %}
{{ event.scheme|upper }} {{ event.method }}{% if event.remote_addr %} from {{ event.remote_addr }}{% endif %}
<code>{% if event.body_raw %}- {{ event.get_body|truncatechars:150 }}{% elif event.object_size %}- {{ event.object_size }} byte body{% endif %}{% if event.ua %} - {{ event.ua|truncatechars:80 }}{% endif %}</code>
<code>{% if event.body_raw_preview %}- {{ event.body_raw_preview|decode }}{% elif event.object_size %}- {{ event.object_size }} byte body{% endif %}{% if event.ua %} - {{ event.ua|truncatechars:80 }}{% endif %}</code>
{% endif %}
</td>
</tr>