Skip to content

Phase 2: Session (release health) envelope parsing + dashboard #232

Description

@ajianaz

Goal

Parse Sentry session and sessions envelope items to track release health — crash rates, error rates per release and environment.

Context

Sentry Rust SDK automatically sends session data via the release-health feature (enabled by default). In request mode (default for web servers), sessions are aggregated and batched every 60s by a background thread (sentry-session-flusher). Each flush produces a sessions envelope item containing aggregated counts.

There are two envelope item types to handle:

  • session — Individual session update (app mode)
  • sessions — Aggregated session counts (request mode)

Depends on: Phase 1 (ParsedEnvelope return type must exist first)

Session Payload (individual)

{
  "sid": "uuid",
  "did": "user-123",
  "init": true,
  "started": "2026-06-26T10:00:00Z",
  "duration": 323.5,
  "status": "exited",
  "errors": 2,
  "attrs": {
    "release": "rungu@0.2.0",
    "environment": "production"
  }
}

Session Aggregates Payload (request mode)

{
  "attrs": {
    "release": "rungu@0.2.0",
    "environment": "production"
  },
  "aggregates": [
    {
      "started": "2026-06-26T10:00:00Z",
      "did": null,
      "exited": 150,
      "errored": 5,
      "abnormal": 0,
      "crashed": 1
    }
  ]
}

Tasks

2a. trapfall-proto — Wire types

  • Add SessionStatus enum: ok, exited, crashed, abnormal
  • Add SessionAttributes struct: release, environment, ip_address, user_agent
  • Add SessionUpdate struct: session_id, distinct_id, init, started, duration, status, errors, attributes
  • Add SessionAggregateItem struct: started, distinct_id, exited, errored, abnormal, crashed
  • Add SessionAggregates struct: aggregates: Vec<SessionAggregateItem>, attributes
  • Extend ParsedEnvelope with session_updates: Vec<SessionUpdate>, session_aggregates: Vec<SessionAggregates>

2b. trapfall-ingest — Parser

  • Add branch: if item_type == "session" { parse SessionUpdate }
  • Add branch: if item_type == "sessions" { parse SessionAggregates }
  • Add tests: envelope with session + event (should send together per Sentry spec)
  • Add tests: aggregated sessions envelope

2c. trapfall-db — Schema + queries

  • SQLite migration: release_health table (aggregated counters)
  • Postgres migration: same
  • Optional: session_updates table for raw individual sessions
  • Add queries: get_crash_rate(release, env, window), list_release_health(project_id)

2d. Dashboard — Release Health UI

  • Add "Release Health" tab
  • Crash rate per release: crashed / (exited + errored + abnormal + crashed) × 100%
  • Crash rate comparison: production vs development
  • Timeline chart: crash rate trend over time
  • Session breakdown: exited/errored/abnormal/crashed counts

SDK Client Effort

Zero code changes needed in Rungu/CIRA — just ensure release is set in ClientOptions:

sentry::init(("https://key@trapfall:9090/proj_id", sentry::ClientOptions {
    release: Some(concat!(env!("CARGO_PKG_VERSION")).into()),
    ..Default::default()  // release-health is default
}));

Dependencies

Effort

~1-2 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