feat(dart): Add array attributes to telemetry#3778
Conversation
Add stringArray, intArray, doubleArray, and boolArray factories to
SentryAttribute for creating homogeneous scalar array attributes.
Wire format: {value: [...], type: 'array'} where the element type is
inferred by the server from the array contents.
Test coverage: 5 new tests covering each array type and empty arrays.
Co-Authored-By: Claude Haiku 4.5 <[email protected]>
Add tests to verify that array attributes (stringArray, intArray, doubleArray, boolArray) are correctly serialized in SentryLog and SentryMetric objects. These array factories were added in a prior task and now have test coverage to lock in the behavior. - SentryLog serializes array attributes with type 'array' - SentryMetric serializes array attributes with type 'array' Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add List<String>, List<int>, List<double>, List<bool> branches to StreamingInstrumentationSpan.setData, mapping them to the typed SentryAttribute array factories. Heterogeneous and nullable lists fall through to the existing else/ignore branch unchanged. Also adds test/tracing/instrumentation/instrumentation_span_test.dart with 6 tests covering all four typed-list cases plus the mixed-list and nullable-list rejection cases. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- Remove dead traceLifecycle cascade from Fixture options - Change late final recordingSpan to final with initializer list - Replace internal .type/.value assertions with public toJson() contract Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Add tests for the SentryAttributeFormatting.toFormattedString() method to verify that array attributes are correctly formatted as bracketed lists in debug output. The tests confirm that: - Non-empty arrays format as '[a, b]' - Empty arrays format as '[]' The implementation already handles arrays correctly via the default branch which calls value.toString() on List objects. Co-Authored-By: Claude Haiku <[email protected]>
Task 5 added a package:sentry/sentry.dart import which made the pre-existing direct src imports redundant (unnecessary_import). Pull SentryAttribute from its src path to match the file's existing direct-import style and restore a clean analyze. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Semver Impact of This PR🟡 Minor (new features) 📋 Changelog PreviewThis is how your changes will appear in the changelog. FeaturesDart
Other
Fixes
Enhancements
DependenciesDeps
Internal Changes
🤖 This preview updates automatically when you update the PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3778 +/- ##
==========================================
+ Coverage 86.83% 87.09% +0.25%
==========================================
Files 336 336
Lines 12064 12080 +16
==========================================
+ Hits 10476 10521 +45
+ Misses 1588 1559 -29
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. |
iOS Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| d0371bb | 1258.85 ms | 1259.44 ms | 0.60 ms |
| dc53d48 | 1252.06 ms | 1255.61 ms | 3.55 ms |
| c26ed0a | 1244.11 ms | 1263.85 ms | 19.75 ms |
| 81f83eb | 1259.53 ms | 1273.39 ms | 13.86 ms |
| 40c8f93 | 1234.27 ms | 1261.98 ms | 27.71 ms |
| dbd526b | 1244.78 ms | 1259.02 ms | 14.24 ms |
| 73dca78 | 1246.65 ms | 1265.42 ms | 18.76 ms |
| 737ef5d | 1255.65 ms | 1252.24 ms | -3.41 ms |
| 3801d52 | 1267.76 ms | 1266.10 ms | -1.65 ms |
| 5367726 | 1211.00 ms | 1216.73 ms | 5.73 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| d0371bb | 5.73 MiB | 6.18 MiB | 464.41 KiB |
| dc53d48 | 5.65 MiB | 6.09 MiB | 446.96 KiB |
| c26ed0a | 5.53 MiB | 5.97 MiB | 453.76 KiB |
| 81f83eb | 7.86 MiB | 9.44 MiB | 1.58 MiB |
| 40c8f93 | 5.53 MiB | 6.00 MiB | 479.94 KiB |
| dbd526b | 7.86 MiB | 9.44 MiB | 1.58 MiB |
| 73dca78 | 7.86 MiB | 9.44 MiB | 1.58 MiB |
| 737ef5d | 5.73 MiB | 6.18 MiB | 466.16 KiB |
| 3801d52 | 5.73 MiB | 6.17 MiB | 455.54 KiB |
| 5367726 | 5.73 MiB | 6.17 MiB | 455.87 KiB |
Previous results on branch: feat/array-attributes-streaming-telemetry
Startup times
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 2b5d315 | 1249.02 ms | 1258.79 ms | 9.77 ms |
| fbbc7a9 | 1234.21 ms | 1249.87 ms | 15.67 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 2b5d315 | 5.83 MiB | 6.28 MiB | 459.38 KiB |
| fbbc7a9 | 5.83 MiB | 6.28 MiB | 459.39 KiB |
Restructure sentry_attribute_test.dart to follow the test-guidelines: single top-level group, sentence-reading nested groups, and plain verb-phrase behaviors. Use $SentryAttribute interpolation for the group name in utils_test.dart. Drop the manual CHANGELOG entry since craft generates entries from PR titles automatically. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
There was a problem hiding this comment.
Pull request overview
Adds support in the core Sentry Dart SDK for homogeneous scalar array attributes in streaming telemetry, enabling users to attach List<String|int|double|bool> values to spans/logs/metrics using the attribute wire format { "value": [...], "type": "array" }.
Changes:
- Added typed
SentryAttributefactories forstringArray,intArray,doubleArray, andboolArray. - Extended
StreamingInstrumentationSpan.setDatato mapList<String|int|double|bool>to the new array attributes. - Added/updated unit and pipeline tests to validate serialization, dispatch behavior, and debug formatting.
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 |
|---|---|
| packages/dart/lib/src/protocol/sentry_attribute.dart | Adds array-typed SentryAttribute factories. |
| packages/dart/lib/src/tracing/instrumentation/instrumentation_span.dart | Maps supported primitive lists passed to setData into array attributes. |
| packages/dart/test/protocol/sentry_attribute_test.dart | Expands JSON serialization tests to cover array attributes. |
| packages/dart/test/tracing/instrumentation/instrumentation_span_test.dart | Adds dispatch tests for setData list handling (including rejection cases). |
| packages/dart/test/telemetry/span/span_capture_pipeline_test.dart | Ensures span capture pipeline preserves array attributes. |
| packages/dart/test/telemetry/metric/metric_test.dart | Verifies metrics serialize array attributes correctly. |
| packages/dart/test/telemetry/log/log_test.dart | Verifies logs serialize array attributes correctly. |
| packages/dart/test/utils_test.dart | Adds debug-formatting assertions for array attributes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Android Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| e2d675d | 457.92 ms | 529.17 ms | 71.25 ms |
| 5367726 | 380.04 ms | 361.33 ms | -18.71 ms |
| e200a70 | 433.06 ms | 437.00 ms | 3.94 ms |
| c97f488 | 502.43 ms | 492.47 ms | -9.97 ms |
| 5a95d04 | 378.92 ms | 364.33 ms | -14.59 ms |
| 8af916c | 367.83 ms | 379.60 ms | 11.77 ms |
| 73a3c38 | 478.18 ms | 526.62 ms | 48.44 ms |
| 40751bf | 421.09 ms | 424.82 ms | 3.73 ms |
| f872f8e | 402.38 ms | 416.20 ms | 13.82 ms |
| 1fff351 | 423.68 ms | 408.96 ms | -14.72 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| e2d675d | 6.54 MiB | 7.69 MiB | 1.15 MiB |
| 5367726 | 14.31 MiB | 15.49 MiB | 1.19 MiB |
| e200a70 | 13.93 MiB | 15.18 MiB | 1.25 MiB |
| c97f488 | 14.31 MiB | 15.49 MiB | 1.19 MiB |
| 5a95d04 | 13.93 MiB | 15.06 MiB | 1.13 MiB |
| 8af916c | 14.31 MiB | 15.56 MiB | 1.25 MiB |
| 73a3c38 | 6.54 MiB | 7.69 MiB | 1.15 MiB |
| 40751bf | 14.31 MiB | 15.49 MiB | 1.19 MiB |
| f872f8e | 13.93 MiB | 15.18 MiB | 1.25 MiB |
| 1fff351 | 14.31 MiB | 15.49 MiB | 1.19 MiB |
Remove the redundant 'when serializing to JSON' and 'with array values' wrapper groups in sentry_attribute_test.dart: the context applied to every sibling test and was already carried by each behavior name, so the nesting added depth without discriminating. Document the underlying conventions in the test-guidelines skill: use $ interpolation for class/enum subject groups, and drop groups whose context is true of every sibling test. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Array factories stored the caller-provided List directly. Since List is mutable, later caller mutations could change what gets serialized and sent. Wrap each list in List.unmodifiable so the attribute holds an independent, immutable copy. Also reorder the array factories to match the scalar factory order (string, bool, int, double). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
📜 Description
Adds support for homogeneous scalar array attributes on streaming telemetry — usable on spans, logs, and metrics. Four typed factories are added to
SentryAttribute:Each serializes to the wire format
{"value": [...], "type": "array"}.StreamingInstrumentationSpan.setDataalso now mapsList<String|int|double|bool>values to these factories; heterogeneous, nullable, and untyped lists fall through to the existing ignore path and are not sent.The factories are intentionally typed (rather than a single inferring
array(List)): the element type is the constraint, so homogeneity is enforced at compile time andList<dynamic>/mixed lists can't be constructed. Logs and metrics required no production change — both already acceptMap<String, SentryAttribute>and serialize attributes via the samevalue.toJson()passthrough as spans, so arrays flow through unchanged.💡 Motivation and Context
Sentry's attribute protocol ingests homogeneous arrays of primitive types using the
arraytype. This brings the Dart SDK in line so users can attach list-valued dimensions to spans, logs, and metrics. Note: array attributes are ingested but not yet visible in the Sentry UI (server-side limitation). Objects and mixed/nested arrays are not yet supported by the protocol and are intentionally out of scope; the design is additive, so they can be layered on later without breaking changes.Closes #3665
💚 How did you test it?
{value, type: 'array'}serialization, including the empty-list case.setDatacovering all four list types plus rejection of mixed-element and null-containing lists.The full core SDK suite and analyzer pass green.
📝 Checklist
sendDefaultPiiis enabled🔮 Next steps
Array attributes are ingested but not yet surfaced in the Sentry UI. Support for object and mixed/nested array attribute values can be added additively (a general
array/objectfactory + matchingsetDatabranches) once the protocol and UI support them.