-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Summary
Transaction.data
is too easily truncatedSpan.data
is never normalized
Details
Introduction
The JS SDKs have a feature to normalize events before serialization that prevents serializing very deeply nested objects.
sentry-javascript/packages/types/src/options.ts
Lines 97 to 106 in 4e552ec
/** | |
* Maximum number of levels that normalization algorithm will traverse in objects and arrays. | |
* Used when normalizing an event before sending, on all of the listed attributes: | |
* - `breadcrumbs.data` | |
* - `user` | |
* - `contexts` | |
* - `extra` | |
* Defaults to `3`. Set to `0` to disable. | |
*/ | |
normalizeDepth?: number; |
This is a great feature, however it does not apply consistently to Transaction/Span data.
Problem
- Transaction data is stored in
Event.contexts.trace.data
. - Span data is stored in
Event.spans[].data
.
Unlike for breadcrumbs that normalization applies only to the .data
property of each breadcrumb, normalization is applied to Event.contexts
as a whole:
sentry-javascript/packages/core/src/baseclient.ts
Lines 303 to 323 in 4e552ec
return { | |
...event, | |
...(event.breadcrumbs && { | |
breadcrumbs: event.breadcrumbs.map(b => ({ | |
...b, | |
...(b.data && { | |
data: normalize(b.data, depth), | |
}), | |
})), | |
}), | |
...(event.user && { | |
user: normalize(event.user, depth), | |
}), | |
...(event.contexts && { | |
contexts: normalize(event.contexts, depth), | |
}), | |
...(event.extra && { | |
extra: normalize(event.extra, depth), | |
}), | |
}; | |
} |
What that means in practice is that, without changes to normalizeDepth
, it is impossible to store objects in Transaction.data
and have them sent to Sentry. Transaction.data
is indirectly forced to be a flat object.
Users unaware of normalizeDepth
can hack it and JSON.stringify
the values they send, but that gives worse user experience 2 times:
- Seeing
[Object]
where the expect some data; fix the frustration withJSON.stringify
and then - Having a string instead of proper JSON means we cannot pretty print the value in the UI:
Possible solutions
Considering that all documented context types are flat objects, it is possible that we could relax the way how normalization applies to Event.contexts
.
The new contexts.trace
is the only key under contexts that may have nested objects under contexts.trace.data
.
Option 1: liberal
An obvious option to consistently handle Transaction/Span data is to remove normalization from contexts
altogether.
Option 2: restrictive
Alternatively, normalization should:
- not apply to
contexts
as a whole; and - apply only to
contexts.trace.data
; and - apply to
spans[].data
.
Option 3: Improve Contexts normalization
not apply tocontexts
as a whole; andInstead, walk through all the keys in contexts and apply it to that values of the key
edit: this is not an option to fix the inconsistency, it would still treat Transaction.data
and Span.data
differently.