-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
In #17852 we currently handle the necessary API change in beforeSendSpan by exporting a wrapper function that users can use to get the new SerializedSpan span and process that instead of the previous SpanJSON which represented the old, transaction-based child span format.
This is a functional strategy but it doesn't solve a fundamental problem:
While anywhere else in their code, users interact with the Span class instance, they have to adapt to a different format (SerializedSpan) in beforeSendSpan. Especially with the move to attributes now having a different serialized format than key<->value, it's quite cumbersome to correctly set an attribute. Also there's room for error (e.g. users assigning an incorrect data type).
Sentry.init({
beforeSendSpan: Sentry.withStreamSpan(serializedSpan => { // naming still sucks :(
if (serializedSpan.name === 'GET /api/v0') {
span.attributes = {
...span.attributes;
'using_old_api': {
type: 'string' // X user error (not detected in vanilla JS)
value: true
}
}
}
})
})The problem with passing in just the span instance always was, that JS spans are not readable and they don't expose getters (thanks OTel). So it's again cumbersome for users to first have to convert that span instance to a JSON object in which they then can read properties from.
Instead, we can do somthing like we do in beforeSend: Provide a hint object that's a reduced, selected JSON object of the span in its state when it was passed to beforeSendSpan:
Sentry.init({
beforeSendSpan: Sentry.withStreamSpan((span, hint) => {
if (hint.name === 'GET /api/v0') {
span.setAttribute('using_old_api', true);
}
if (hint.attributes['sentry.op'] === 'navigation') {
span.addLink(...);
}
console.log(
hint.name,
hint.attributes, // serialized key-value pairs of attributes. Type not exposed.
hint.status,
hint.links // serialized links array
);
})
})hint can be a data bag of context we can extend over time. The name makes it already quite clear that it's only readable but we could even proxy the object to detect writes and warn about them that they have no effect.