Skip to content

feat: payload compression, tracing, and DLQ observability - #743

Merged
DokaIzk merged 5 commits into
SoroScan:mainfrom
OtowoSamuel:main
Jun 25, 2026
Merged

feat: payload compression, tracing, and DLQ observability#743
DokaIzk merged 5 commits into
SoroScan:mainfrom
OtowoSamuel:main

Conversation

@OtowoSamuel

@OtowoSamuel OtowoSamuel commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

This PR implements the requested backend improvements.
Closes #507
Closes #496
Closes #511
Closes #510

Copilot AI review requested due to automatic review settings June 24, 2026 16:32
@drips-wave

drips-wave Bot commented Jun 24, 2026

Copy link
Copy Markdown

@OtowoSamuel Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds backend performance and observability improvements to SoroScan’s ingest/webhook pipeline by enabling payload compression (DB + HTTP), adding custom OpenTelemetry tracing helpers/spans, and improving dead-letter queue (DLQ) visibility via Prometheus metrics.

Changes:

  • Enabled response compression via Django GZipMiddleware and added a migration to enable Postgres TOAST compression on event payload columns.
  • Introduced a small ingest telemetry module and instrumented key ingest/webhook paths with custom OpenTelemetry spans + outbound trace header injection.
  • Added new Prometheus metrics (payload compression ratio, webhook DLQ depth) and tests covering the new helpers/trace header propagation.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
django-backend/soroscan/settings.py Adds GZipMiddleware for HTTP response compression.
django-backend/soroscan/ingest/telemetry.py New helper module for trace header injection and compression ratio observation.
django-backend/soroscan/ingest/tasks.py Instruments ingest + webhook dispatch with spans, injects trace headers, records compression ratio, updates DLQ depth metric on enqueue.
django-backend/soroscan/ingest/cache_utils.py Wraps contract cache lookups in a tracing span.
django-backend/soroscan/ingest/metrics.py Adds new metrics and extends metric factory to support histogram kwargs (e.g., buckets).
django-backend/soroscan/ingest/migrations/0044_contractevent_payload_compression.py Enables Postgres column compression for payload storage with fallback behavior.
django-backend/soroscan/ingest/tests/test_tasks.py Adds tests for compression ratio metric emission and trace header propagation in webhook requests.
django-backend/requirements.txt Adds OpenTelemetry API/SDK dependencies.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 118 to 121
"soroscan.middleware.ApiDeprecationMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.gzip.GZipMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
Comment on lines +9 to +17
from opentelemetry import propagate, trace
from opentelemetry.sdk.trace import TracerProvider

from .metrics import event_payload_compression_ratio

if trace.get_tracer_provider().__class__.__name__ == "ProxyTracerProvider":
trace.set_tracer_provider(TracerProvider())

tracer = trace.get_tracer("soroscan.ingest")
Comment on lines +290 to +295
event_payload_compression_ratio = _get_or_create(
Histogram,
"soroscan_event_payload_compression_ratio",
"Observed compressed-to-raw size ratio for stored event payloads",
buckets=(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.25, 1.5),
)
Comment on lines +18 to +23
with schema_editor.connection.cursor() as cursor:
for statement in statements:
try:
cursor.execute(statement)
except Exception:
cursor.execute(statement.replace("lz4", "pglz"))
Comment on lines +626 to +630
return (None, False)

raw_xdr = str(_event_attr(event, "xdr", "raw_xdr", default="") or "")
signature_status = resolve_signature_status(contract, event, payload)
payload_compression_ratio(payload)

timestamp = _event_attr(event, "timestamp", default=timezone.now())
if isinstance(timestamp, datetime) and timezone.is_naive(timestamp):
timestamp = timezone.make_aware(timestamp, dt_timezone.utc)
if not isinstance(timestamp, datetime):
timestamp = timezone.now()
raw_xdr = str(_event_attr(event, "xdr", "raw_xdr", default="") or "")
Comment on lines 1458 to +1463
error=error[:2000],
retries_exhausted=retries_exhausted,
)
_get_metrics().webhook_dead_letter_depth.set(
WebhookDeadLetter.objects.filter(resolved=False).count()
)
@DokaIzk
DokaIzk merged commit 3e050ca into SoroScan:main Jun 25, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Event Ingestion Dead Letter Queue Contract Event Schema Validation Event Payload Compression Custom OpenTelemetry Instrumentation

3 participants