Skip to content

[Span-First] Audit with OSS App #3543

@buenaflor

Description

@buenaflor

Instrument OSS Flutter App for Span-First Validation

Background

We originally planned to dog food the Sentry Dart Plugin internally, but there's a version mismatch between the Sentry library and the Dart plugin that makes them incompatible without a major bump to the plugin's minimum supported Dart version.

Instead we'll instrument an open-source Flutter app: openfoodfacts/smooth-app. This follows the same process we used for the replay audit.


Goals

  • Validate SDK behavior against a realistic, production-like Flutter codebase
  • Exercise auto-instrumentation and manual span APIs end-to-end
  • Surface gaps or ergonomic issues

Tasks

Instrumentation

Use the Sentry Flutter branch: #3534
This is not merged yet but contains the final App Start instrumentation port which is important (otherwise there are no span-first app start spans)

Instrument the app as you realistically would in a production Flutter project. Use the internal Sentry SDKs project or a personal Sentry project and lean on auto-instrumentation wherever supported. For this app, that includes:

  • TTID / TTFD
  • App Starts (automatic)
  • Hive
  • HTTP

Testing

Verify the instrumentation works correctly on both iOS and Android.

Automation

Where possible, use Maestro to automate click-through flows so we can run multiple iterations efficiently.

  • Automate all major flows that trigger as many spans as possible
  • Android should be tested on a physical device in release mode
  • iOS should be tested on simulator in debug mode (because Maestro only works in simulator for iOS and profile/release builds aren't supported on simulators)

Assertions to Validate / Tasks

Work through the following assertions and document findings:

  • ignoreSpans and beforeSendSpan behave correctly
  • No spans are unexpectedly dropped by ingest
  • Span hierarchies are correct and reflect the expected parent-child relationships
  • configureScope in startSpan callback delegates attributes to only children in that callback context
  • Use startInactiveSpan and document where it is most useful
  • The API is ergonomic — see open question below

APIs Under Test

API Notes
Sentry.startSpan Primary span API. Note: span ends automatically when the callback completes — there is no manual end(). See open question below.
Sentry.configureScope You can call Sentry.configureScope inside a span's callback and it will delegate its attributes to all child spans inside that callback.
Sentry.currentHub.startInactiveSpan Still internal but should be promoted to be a public API (Sentry.startInactiveSpan). Useful for recording spans across async or callback boundaries that are hard to model with startSpan.
options.ignoreSpans Filter spans by name/pattern.
options.beforeSendSpan Mutate before they're sent.

Open Questions

1. startSpan — manual ending

startSpan currently ends the span automatically when its callback completes. This works well for straightforward cases, but there are likely gaps where you want an active span that needs to outlive the callback (e.g. spans that start depends on some external completer to end).

Action: Note any cases where automatic span ending is insufficient. JavaScript addresses this with a separate Sentry.startSpanManually that behaves identically to startSpan but does not auto-close when the callback finishes. We should evaluate whether we need an equivalent.

2. startSpan API split

We're considering splitting the current startSpan into two functions to be more Dart-idiomatic:

  • startSpan — callback-based, for Future-returning operations
  • startSpanSync — synchronous variant, consistent with other Dart SDK patterns

Action: Note whether the current single API feels natural during instrumentation, or if the split would improve clarity.

E.g dart:io makes use of this

File.readAsString() / File.readAsStringSync()
File.writeAsBytes() / File.writeAsBytesSync()
Directory.list() / Directory.listSync()
Process.run() / Process.runSync()

Report

Please write the complete report in this issue

Metadata

Metadata

Assignees

Labels

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions