getsentry / sentry-react-native

Official Sentry SDK for React Native
https://sentry.io
MIT License
1.57k stars 337 forks source link

Decorator function for making something a Performance Transaction #3804

Closed thinkocapo closed 4 months ago

thinkocapo commented 6 months ago
@makeTransaction
MyReactComponent extends React {
    initialize(){}
    render() {}
 }

@makeTransaction
MySomethingFunction extends Unknown {
    // does stuff, may be Modals,Widgets, Tooltips, or something else
    // same stuff we auto-instrument (http, database) will keep getting captured as spans
 }}

and then MyReactComponent and MySomethingFunction should appear here as dedicated items in the Peformance Dashboard along with 'Home' 'Cart' 'Checkout' in the below screenshot.

Maybe decorate an entire Class so you don't have to do this per function. Hmm maybe this is not any different than instrumenting a Custom Span? Not sure.

If moving away from transactions towards a 'span based' approach then call it @makeSpan. Do not require user to then instrument every sub-span, that'd be an incredible amount of work. UI.load, user-interactions, file i/o, db, http, async, all these things shoould just appear if the decorator was used.

image

Problem: not everything falls under 'ui.load' or 'navigation' or 'ui.action.touch'. Sometimes the UI they care about is one single ui component out of 10 ui components rendered in a single HomeScreen, but they wanted it treated as more of a first-class entity. Currently they just see 'HomeScreen' as the transaction but they'd rather see the sub-component, maybe it's called 'FoodItems' and then there's 'Restaurants' and 'Delivery' components too all in the home screen but it's too over-aggressive to have it grouped into a single HomeScreen.

krystofwoldrich commented 5 months ago

Thanks for the message, I agree that in some apps grouping per screen is too general and the respective code owners are only interested in ComponentA and ComponentB.

I don't think any new API or decorator is need to solve this. When Sentry operates only based on spans, developer will be able to look up the appropriate spans which can be created by Sentry.startSpan or Sentry.withProfiler.

Until then forceTransaction can be used to capture the wanted data. This ensures the created span shows up in Sentry UI as transaction. The auto instrumented span won't be attached to this transaction. This is not possible because we can have only one active span on the scope, and the case of multiple components on one screen would require multiple active spans.

const transaction = Sentry.startInactiveSpan({ name: 'transaction', forceTransaction: true });
thinkocapo commented 4 months ago

I like the idea of forceTransaction for making it appear as a row on the Performance Dashboard. Or I'm not sure if someone would suggest that you should be querying for this span in existing Sentry UI in order to find it, and not have to annotate this from the SDK level. forceTransaction, or could call it something else if we really want to get rid of mentions of 'transaction'. primarySpan thought that may indicate it's a root-span of a span tree. highlightSpan

krystofwoldrich commented 4 months ago

Yeah the name still mentions transaction, but that is because it forces the span to be individual transaction event in Sentry.

The forceTransaction is already implemented for a while in JS and RN. User can use it now.

https://github.com/getsentry/sentry-javascript/blob/874df8e5b28e2f0f530b0e651067cdd2aa3e5cf7/docs/v8-new-performance-apis.md#creating-a-transaction