Skip to content

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

Merged
nicohrubec merged 29 commits into
developfrom
nh/array-attribute-support
May 13, 2026
Merged

feat(core): Support array attributes for spans, logs and metrics#20427
nicohrubec merged 29 commits into
developfrom
nh/array-attribute-support

Conversation

@nicohrubec

@nicohrubecnicohrubec commented Apr 21, 2026

Copy link
Copy Markdown
Member

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. After discussion with product teams we also decided not to drop empty arrays.

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) <noreply@anthropic.com>
@github-actions

github-actionsBot commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser26.88 kB+0.05%+12 B 🔺
@sentry/browser - with treeshaking flags25.32 kB+0.06%+15 B 🔺
@sentry/browser (incl. Tracing)44.78 kB+0.04%+14 B 🔺
@sentry/browser (incl. Tracing + Span Streaming)46.75 kB+0.03%+13 B 🔺
@sentry/browser (incl. Tracing, Profiling)49.77 kB+0.03%+13 B 🔺
@sentry/browser (incl. Tracing, Replay)84.41 kB+0.02%+13 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags73.84 kB+0.03%+15 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas)89.11 kB+0.02%+13 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback)101.75 kB+0.02%+12 B 🔺
@sentry/browser (incl. Feedback)44.06 kB+0.03%+10 B 🔺
@sentry/browser (incl. sendFeedback)31.69 kB+0.04%+11 B 🔺
@sentry/browser (incl. FeedbackAsync)36.8 kB+0.03%+11 B 🔺
@sentry/browser (incl. Metrics)27.97 kB+0.05%+13 B 🔺
@sentry/browser (incl. Logs)28.11 kB+0.05%+14 B 🔺
@sentry/browser (incl. Metrics & Logs)28.8 kB+0.06%+17 B 🔺
@sentry/react28.63 kB+0.04%+9 B 🔺
@sentry/react (incl. Tracing)47.05 kB+0.05%+19 B 🔺
@sentry/vue31.8 kB+0.04%+12 B 🔺
@sentry/vue (incl. Tracing)46.65 kB+0.04%+14 B 🔺
@sentry/svelte26.9 kB+0.05%+12 B 🔺
CDN Bundle29.26 kB+0.05%+14 B 🔺
CDN Bundle (incl. Tracing)47.17 kB+0.03%+10 B 🔺
CDN Bundle (incl. Logs, Metrics)30.64 kB+0.05%+13 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics)48.29 kB+0.02%+9 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics)69.97 kB+0.03%+14 B 🔺
CDN Bundle (incl. Tracing, Replay)84.56 kB+0.02%+12 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics)85.63 kB+0.02%+10 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback)90.37 kB+0.01%+9 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)91.47 kB+0.01%+8 B 🔺
CDN Bundle - uncompressed86.08 kB+0.07%+54 B 🔺
CDN Bundle (incl. Tracing) - uncompressed141.53 kB+0.04%+54 B 🔺
CDN Bundle (incl. Logs, Metrics) - uncompressed90.28 kB+0.06%+54 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed145 kB+0.04%+54 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed215.1 kB+0.03%+54 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed260.24 kB+0.03%+54 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed263.69 kB+0.03%+54 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed273.94 kB+0.02%+54 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed277.38 kB+0.02%+54 B 🔺
@sentry/nextjs (client)49.56 kB+0.04%+17 B 🔺
@sentry/sveltekit (client)45.27 kB+0.04%+16 B 🔺
@sentry/node-core60.84 kB+0.05%+27 B 🔺
@sentry/node165.98 kB+0.02%+28 B 🔺
@sentry/node - without tracing73.97 kB+0.04%+24 B 🔺
@sentry/aws-serverless108.07 kB+0.02%+20 B 🔺
@sentry/cloudflare (withSentry) - minified170.68 kB+0.03%+49 B 🔺
@sentry/cloudflare (withSentry)430.48 kB+0.02%+71 B 🔺

View base workflow run

nicohrubecand 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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
@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
@nicohrubecnicohrubec changed the title feat(core): Support homogeneous primitive arrays as span attributesfeat(core): Support homogeneous primitive arrays as span/metric/log attributesApr 28, 2026
Comment threadpackages/core/src/attributes.ts Outdated
…72 KB
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment threadpackages/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
MemberAuthor

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
MemberAuthor

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
MemberAuthor

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 threadpackages/core/src/attributes.ts Outdated
Comment threadpackages/core/src/attributes.ts Outdated
@nicohrubec
nicohrubec marked this pull request as ready for review May 4, 2026 12:48
@nicohrubec
nicohrubec requested review from a team as code ownersMay 4, 2026 12:48
@nicohrubecnicohrubec changed the title feat(core): Support homogeneous primitive arrays as span/metric/log attributesfeat(core): Support array attributes for spans, logs and metricsMay 4, 2026
Comment threadpackages/core/src/attributes.ts Outdated

@cursorcursorBot left a comment

Copy link
Copy Markdown

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 CursorFix in Web

Reviewed by Cursor Bugbot for commit f896f3a. Configure here.

Copy link
Copy Markdown
MemberAuthor

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 threadpackages/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
MemberAuthor

Choose a reason for hiding this comment

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

Narrowed it down again

@chargomechargome left a comment

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.

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.

'integer[]': Array<number>;
'double[]': Array<number>;
'boolean[]': Array<boolean>;
array: 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: Would be BigInt supported as well? I think this is a broader question actually

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Mhm not sure. I assume relay enforces some number maximum but no idea what that is.

@logaretmlogaretm left a comment

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.

@nicohrubec Do u think it is worth warning in debug if we detect non-homogenous attributes in the array?

Just to ease detecting this for the end user.

Comment threadpackages/core/src/attributes.ts Outdated
* https://github.com/getsentry/sentry-javascript/pull/18165
*/
function getTypedAttributeValue(value: unknown): TypedAttributeValue | void {
if (Array.isArray(value) && value.length !== 0) {

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.

@nicohrubec q: what happens in empty arrays? are they still stringified?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

as discussed I'll switch that logic to early return for empty arrays so they get dropped for both fallback/non-fallback paths. the way it is right now if fallback is enabled we send a stringified empty array if the fallback is on

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

actually after further discussion we won't be dropping empty arrays (independent of fallback on/off)

nicohrubecand others added 3 commits May 7, 2026 10:51
Now that array attributes are serialized, `device.archs` is no longer
dropped — uncomment and enable the assertions in integration tests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@nicohrubec
nicohrubec marked this pull request as draft May 7, 2026 17:32
@nicohrubec
nicohrubec marked this pull request as ready for review May 12, 2026 14:25
@nicohrubec
nicohrubec merged commit 16eab59 into developMay 13, 2026
521 of 524 checks passed
@nicohrubec
nicohrubec deleted the nh/array-attribute-support branch May 13, 2026 07:45
Sign up for freeto 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

5 participants

@nicohrubec@logaretm@JPeer264@chargome@andreiborza