You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(angular): Add URL Parameterization of Transaction Names (#5416)
Introduce URL Parameterization to our Angular SDK. With this change, the SDK will update transaction names coming from a URL with a paramterized version of the URL (e.g `GET /users/1235/details` will be parameterized to `GET /users/:userId/details/`).
This is done by listening to the `ResolveEnd` routing event in `TraceService`. When this event is fired, the Angular router has finished resolving the new URL and found the correct route. Besides the url, the event contains a snapshot of the resolved and soon-to-be activated route. This `ActivatedRouteSnapshot` instance is the root instance of the activated route. If the resolved route is something other than `''` or `'/'`, it will also points to its first child. This instance might again point to its (a possibly existing) child but it also holds its part of the resolved and parameterized route path (URL).
By recursively concatenating the paths, we get a fully parameterized URL.
The main advantage of this approach vs. a previously tried URL<->parameter interpolation approach is that we do not run into the danger of making interpolation mistakes or leaving parts of the route unparameterized. We now simply take what the Angular router has already resolved.
The potential disadvantage is that we rely on the assumption that there is only one child per route snapshot. While testing, I didn't come across a situation where a parent snapshot had more than one child. I believe that this is because the `ResolveEnd` event contains a snapshot of the newly activated route and not the complete router state. However, if we get reports of incorrect transaction names, we might want to revisit this parameterization approach.
It should be noted that because there is a gap between transaction creation (where we initially set the unparameterized name) and URL parameterization, it is possible that parameterization might happen after an outgoing Http request is made. In that case, the dynamic sampling context will be populated and frozen without the `transaction` field because at this point the transaction name's source is still `url`. This means that we have a potential timing problem, similar to other routing instrumentations.
At this point we're not yet sure how often such a timing problem would occur but it seems pretty unlikely for normal usage. For instance, DSC population will happen correctly (with the `transaction` field) when the first outgoing Http request is fired in the constructor of the component that is associated with the new route. This also means that hooks like `ngOnInit` which are frequently used for making requests (e.g. via Service calls) are called long after the `ResolveEnd` routing event.
Additionally, this add a few unit tests to test this new behaviour. However, these tests are really unit tests, meaning they only test our `TraceService` implementation. We currently simply mock the Angular router and fire the routing events manually. A more "wholesome" approach (e.g. calling `router.navigate` instead of manually firing events) would be better but for this we'd need to inject an actual Angular Router into `TraceService`. This is done best with Angular's `TestBed` feature but it currently doesn't work with our testing setup for the Angular SDK. Changing the setup is out of scope for this PR but we'll revisit this and make the necessary changes to improve the testing setup of our Angular SDK.
0 commit comments