Skip to content

feat(core): Support array attributes for spans, logs and metrics#20427

Open
nicohrubec wants to merge 24 commits intodevelopfrom
nh/array-attribute-support
Open

feat(core): Support array attributes for spans, logs and metrics#20427
nicohrubec wants to merge 24 commits intodevelopfrom
nh/array-attribute-support

Conversation

@nicohrubec
Copy link
Copy Markdown
Member

@nicohrubec nicohrubec commented Apr 21, 2026

Adds array attribute support for spans, logs, and metrics. Relay only supports primitive homogeneous arrays (all elements have the same primitive type). However, any attributes with non-conforming arrays will be dropped by Relay, so there is no need for runtime validation on the SDK end.

This change as is comes with a behavioral change for user-defined logs and metrics. If users previously set array attributes for logs/metrics then these were previously sent to Sentry stringified, now these will be sent as arrays. I noted this in the changelog. I am aware that this could technically be interpreted as breaking, so if someone feels strongly we should keep this behavior for now then we can definitely find a way to work around this.

Note: the Sentry frontend doesn't render array attributes correctly yet, but that's expected to land soon.

Blocks #20428
Closes #20651
Closes #20438

Relay's wire contract (AttributeType enum in relay-event-schema) defines
exactly five `type:` tags: boolean, integer, double, string, array.
The SDK's AttributeTypeMap previously declared typed array variants
(`string[]`, `integer[]`, etc.) that Relay does not recognize - these
were never actually emitted because the runtime serializer only handled
primitives, so array-valued attributes silently dropped.

This change:
- Collapses the four `x[]` variants in AttributeTypeMap into a single
  `array` variant whose value is `Array<string> | Array<number> | Array<boolean>`.
- Extends getTypedAttributeValue to auto-detect homogeneous primitive
  arrays and emit `{type: 'array', value: [...]}`.
- Adds an isHomogeneousPrimitiveArray guard so mixed-type and nested
  arrays remain unsupported (dropped by default, stringified under
  the fallback path).
- Updates tests to cover the new typed-array path (including empty
  arrays, unit preservation, and mixed-type drop/stringify).

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 21, 2026

size-limit report 📦

Path Size % Change Change
@sentry/browser 26.31 kB - -
@sentry/browser - with treeshaking flags 24.8 kB - -
@sentry/browser (incl. Tracing) 44.2 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 46.44 kB +0.05% +21 B 🔺
@sentry/browser (incl. Tracing, Profiling) 49.16 kB - -
@sentry/browser (incl. Tracing, Replay) 83.58 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 73.04 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 88.26 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 100.87 kB - -
@sentry/browser (incl. Feedback) 43.47 kB - -
@sentry/browser (incl. sendFeedback) 31.12 kB - -
@sentry/browser (incl. FeedbackAsync) 36.21 kB - -
@sentry/browser (incl. Metrics) 27.64 kB +0.07% +18 B 🔺
@sentry/browser (incl. Logs) 27.77 kB +0.08% +21 B 🔺
@sentry/browser (incl. Metrics & Logs) 28.47 kB +0.09% +23 B 🔺
@sentry/react 28.05 kB - -
@sentry/react (incl. Tracing) 46.42 kB - -
@sentry/vue 31.18 kB - -
@sentry/vue (incl. Tracing) 46.04 kB - -
@sentry/svelte 26.34 kB - -
CDN Bundle 28.93 kB +0.07% +18 B 🔺
CDN Bundle (incl. Tracing) 46.97 kB +0.03% +14 B 🔺
CDN Bundle (incl. Logs, Metrics) 30.36 kB +0.06% +16 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) 48.09 kB +0.05% +21 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) 69.43 kB +0.03% +19 B 🔺
CDN Bundle (incl. Tracing, Replay) 84.12 kB +0.02% +15 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 85.17 kB +0.02% +16 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 89.92 kB +0.02% +15 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 91.03 kB +0.02% +14 B 🔺
CDN Bundle - uncompressed 84.79 kB +0.09% +68 B 🔺
CDN Bundle (incl. Tracing) - uncompressed 140.38 kB +0.05% +68 B 🔺
CDN Bundle (incl. Logs, Metrics) - uncompressed 88.98 kB +0.08% +68 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 143.84 kB +0.05% +68 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 212.93 kB +0.04% +68 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 258.18 kB +0.03% +68 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 261.63 kB +0.03% +68 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 271.88 kB +0.03% +68 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 275.31 kB +0.03% +68 B 🔺
@sentry/nextjs (client) 48.92 kB - -
@sentry/sveltekit (client) 44.67 kB - -
@sentry/node-core 59.15 kB +0.05% +29 B 🔺
@sentry/node 170.59 kB +0.02% +32 B 🔺
@sentry/node - without tracing 97.19 kB +0.03% +26 B 🔺
@sentry/aws-serverless 114.02 kB +0.05% +53 B 🔺
@sentry/cloudflare (withSentry) - minified 165.26 kB +0.04% +63 B 🔺
@sentry/cloudflare (withSentry) 417.8 kB +0.03% +93 B 🔺

View base workflow run

nicohrubec and others added 8 commits April 21, 2026 19:28
Arrays that were previously dropped by the serializer now ship as
native array attributes (`type: 'array'`). Update the affected
integration test expectations and bump size-limit thresholds for
the five bundle scenarios whose gzipped/uncompressed sizes grew
from the new serializer logic.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Drop the size-limit increases for the five bundle scenarios that grew
from adding homogeneous primitive array support. Test expectation
updates from the previous commit stay.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Re-apply the size-limit bumps needed to account for the new
homogeneous-primitive-array detection logic. Five scenarios grew
past their thresholds:

- @sentry/browser (incl. Metrics & Logs): 28 → 29 KB
- CDN Bundle (incl. Logs, Metrics): 30 → 31 KB
- CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed: 258.5 → 259 KB
- CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed: 268 → 269 KB
- CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed: 271.5 → 272 KB

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@nicohrubec nicohrubec marked this pull request as ready for review April 28, 2026 11:16
@nicohrubec nicohrubec marked this pull request as draft April 28, 2026 11:16
@nicohrubec nicohrubec changed the title feat(core): Support homogeneous primitive arrays as span attributes feat(core): Support homogeneous primitive arrays as span/metric/log attributes Apr 28, 2026
Comment thread packages/core/src/attributes.ts Outdated
Comment thread packages/core/src/attributes.ts Outdated
}
}

function isHomogeneousPrimitiveArray(arr: unknown): arr is Array<string> | Array<number> | Array<boolean> {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

q: Was it previously decided that SDKs have to guarantee homogeneity? Just wondering if we really have to iterate over the entire array for every array.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Jap fair question, we are still discussing that one 😅

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Talked to ingest: We don't need any SDK-side runtime validation.

@nicohrubec
Copy link
Copy Markdown
Member Author

Converting back to draft until we have a definitive answer for SDK validation.

@nicohrubec nicohrubec marked this pull request as draft April 29, 2026 07:46
Comment thread packages/core/src/attributes.ts Outdated
Comment thread packages/core/src/attributes.ts Outdated
@nicohrubec
Copy link
Copy Markdown
Member Author

nicohrubec commented May 4, 2026

@chargome @mydea I talked to Ingest last week and the outcome was that we don't need any SDK-side runtime validation for user-set arrays on attributes. Relay will just drop any attributes with non-conforming arrays set as values. Based on that I simplified the PR, should be good for another look. The frontend still doesn't display these properly yet though. I will make sure to properly test this e2e before merging after the FE is ready.

@nicohrubec nicohrubec requested a review from chargome May 4, 2026 12:48
@nicohrubec nicohrubec marked this pull request as ready for review May 4, 2026 12:48
@nicohrubec nicohrubec requested review from a team as code owners May 4, 2026 12:48
@nicohrubec nicohrubec changed the title feat(core): Support homogeneous primitive arrays as span/metric/log attributes feat(core): Support array attributes for spans, logs and metrics May 4, 2026
Comment thread packages/core/src/attributes.ts Outdated
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit f896f3a. Configure here.

*/
function getTypedAttributeValue(value: unknown): TypedAttributeValue | void {
if (Array.isArray(value) && value.length !== 0) {
return { value, type: 'array' };
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Mixed-type array console parameters silently dropped by Relay

Medium Severity

The getTypedAttributeValue function now converts all non-empty arrays to { type: 'array' } before the stringify fallback path is reached. This means SDK-internal sentry.message.parameter.X attributes created by createConsoleTemplateAttributes from mixed-type console args (e.g. console.log('Array:', [1, 2, 3, 'string'])) are now sent as array attributes instead of being stringified. Since Relay drops non-homogeneous arrays, these template parameters will be silently lost — a regression from the previous behavior where they were preserved as stringified values. The body text is unaffected, but structured template parameter data is lost for mixed-type arrays.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit f896f3a. Configure here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

this is basically what I described in the PR description, we can discuss it but I think this is a tradeoff we have to make. don't think we can really solve this unless we do runtime inspection of the types of elements in arrays

Comment thread packages/core/src/attributes.ts Outdated
export type Attributes = Record<string, TypedAttributeValue>;

export type AttributeValueType = string | number | boolean | Array<string> | Array<number> | Array<boolean>;
export type AttributeValueType = string | number | boolean | Array<unknown>;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

h: Do we really want Array<unknown>? Every change that follows would be breaking from here on.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Narrowed it down again

Copy link
Copy Markdown
Member

@chargome chargome left a comment

Choose a reason for hiding this comment

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

value: expect.any(Number),
},
// TODO: 'device.archs' is set but arrays are not yet serialized in span attributes
'device.archs': {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for pulling this one in.

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.

Add assertion for 'device.archs' once array attributes are supported Enable array attribute support in the SDK

3 participants