Skip to content

Inconsistent normalization of Transaction/Span data #2646

@rhcarvalho

Description

@rhcarvalho

Summary

  • Transaction.data is too easily truncated
  • Span.data is never normalized

image

Details

Introduction

The JS SDKs have a feature to normalize events before serialization that prevents serializing very deeply nested objects.

/**
* 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:

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:

  1. Seeing [Object] where the expect some data; fix the frustration with JSON.stringify and then
  2. Having a string instead of proper JSON means we cannot pretty print the value in the UI:

Manually stringified object
image

Regular JSON object
image

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 to contexts as a whole; and
  • Instead, 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions