Skip to content

Phase 1: Transaction envelope parsing + DB + dashboard #231

Description

@ajianaz

Goal

Parse Sentry transaction envelope items in TrapFall so performance data (latency, spans, DB queries) is captured, stored, and displayed in the dashboard.

Context

TrapFall currently only parses event envelope items (errors). All other item types — including transaction — are silently dropped in envelope.rs:83. The Sentry Rust SDK emits transaction items when SentryHttpLayer::new().enable_transaction() is used with the tower feature.

License: 100% safe. Sentry SDK = MIT. Envelope protocol = unlicensed wire format. TrapFall uses clean-room implementation.

Transaction Payload (from SDK)

{
  "event_id": "uuid",
  "transaction": "POST /api/feedback",
  "start_timestamp": 1703894474.296,
  "timestamp": 1703894474.891,
  "release": "rungu@0.2.0",
  "environment": "production",
  "spans": [
    {
      "span_id": "...",
      "trace_id": "...",
      "op": "db.sql.select",
      "description": "SELECT * FROM feedback WHERE ...",
      "start_timestamp": 1703894474.300,
      "timestamp": 1703894474.450,
      "status": "ok"
    }
  ]
}

Tasks

1a. trapfall-proto — Wire types

  • Add Transaction struct: event_id, transaction (name), start_timestamp, timestamp, release, environment, spans: Vec<Span>, contexts, request, tags, extra
  • Add Span struct: span_id, trace_id, parent_span_id, op, description, start_timestamp, timestamp, status, tags, data
  • Add SpanStatus enum: ok, deadline_exceeded, cancelled, unknown_error, internal_error, resource_exhausted, etc.
  • Add ParsedEnvelope return type (replaces Vec<Event>)
    pub struct ParsedEnvelope {
        pub events: Vec<Event>,
        pub transactions: Vec<Transaction>,
        // future: sessions, attachments
    }

1b. trapfall-ingest — Parser

  • Change parse_envelope() return type: Result<Vec<Event>>Result<ParsedEnvelope>
  • Add branch in parse_envelope_text(): if item_type == "transaction" { parse Transaction }
  • Update all downstream consumers of parse_envelope() to use ParsedEnvelope
  • Add tests: multi-item envelope with event + transaction
  • Add tests: envelope with only transaction (no event)

1c. trapfall-db — Schema + queries

  • SQLite migration: add transactions and transaction_spans tables
  • Postgres migration: same schema in Postgres dialect
  • Add insert_transaction(), list_transactions(), get_transaction() queries
  • Add get_slowest_transactions() — top N by duration (for dashboard)

1d. trapfalld — Handler + WebSocket

  • Add transaction handling in digest loop
  • Add WebSocket broadcast for new transactions
  • Update ServerMessage enum with TransactionReceived variant

1e. Dashboard — Performance UI

  • Add "Performance" tab in project dashboard
  • Transaction list: name, duration, status, timestamp
  • Transaction detail: waterfall chart of child spans
  • Slowest transactions widget

Dependencies

  • No new crate dependencies (serde already available)
  • Breaks existing parse_envelope() return type — all consumers must update

Effort

~2-3 days


Sub-issues:

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpriority:highP1 - Fix soonscope:dashboardSvelteKit dashboard UIscope:dbDatabase schema / migrationscope:ingestEnvelope ingest / parser changesscope:prototrapfall-proto wire typestype:envelopeSentry envelope item type expansion

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions