Skip to content

Commit d83bd21

Browse files
committed
fix(webapp): report full route path on Remix request spans
The @sentry/remix OpenTelemetry instrumentation sets each request span's name and http.route from only the matched leaf route's own path segment. For nested routes that made distinct pages collapse to one ambiguous segment (e.g. ":runParam"), so traces could not tell which route served a request. Reconstruct the full matched path by joining every segment in the match chain, falling back to the leaf path. Flat routes such as "api/v1/tasks/:taskId/trigger" are unchanged; nested routes now carry their full URL pattern. Applied to both the CJS and ESM builds via the existing pnpm patch.
1 parent a7c734c commit d83bd21

2 files changed

Lines changed: 42 additions & 6 deletions

File tree

patches/@sentry__remix@9.46.0.patch

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
11
diff --git a/build/cjs/vendor/instrumentation.js b/build/cjs/vendor/instrumentation.js
2-
index 84e18d1051f57d5807e65c8b8ce858ceee7d4557..640a5253d565650338fe33e0ea52c8dffc63e4e7 100644
2+
index 84e18d1051f57d5807e65c8b8ce858ceee7d4557..098a18992044ff4e52de986782bfb52761e50ab7 100644
33
--- a/build/cjs/vendor/instrumentation.js
44
+++ b/build/cjs/vendor/instrumentation.js
5-
@@ -238,7 +238,7 @@ class RemixInstrumentation extends instrumentation.InstrumentationBase {
5+
@@ -140,7 +140,14 @@ class RemixInstrumentation extends instrumentation.InstrumentationBase {
6+
7+
const route = (result || []).slice(-1)[0]?.route;
8+
9+
- const routePath = route?.path;
10+
+ // Join every matched route segment so nested routes report their
11+
+ // full URL pattern on http.route (and the span name), not just the
12+
+ // leaf route's own path segment.
13+
+ const routePath =
14+
+ (result || [])
15+
+ .map((match) => match?.route?.path)
16+
+ .filter((segment) => typeof segment === 'string' && segment.length > 0)
17+
+ .join('/') || route?.path;
18+
if (span && routePath) {
19+
span.setAttribute(semanticConventions.SemanticAttributes.HTTP_ROUTE, routePath);
20+
span.updateName(`remix.request ${routePath}`);
21+
@@ -238,7 +245,7 @@ class RemixInstrumentation extends instrumentation.InstrumentationBase {
622
return function callRouteAction(original) {
723
return async function patchCallRouteAction( ...args) {
824
const [params] = args;
@@ -11,7 +27,7 @@ index 84e18d1051f57d5807e65c8b8ce858ceee7d4557..640a5253d565650338fe33e0ea52c8df
1127
const span = plugin.tracer.startSpan(
1228
`ACTION ${params.routeId}`,
1329
{ attributes: { [semanticConventions.SemanticAttributes.CODE_FUNCTION]: 'action' } },
14-
@@ -257,25 +257,6 @@ class RemixInstrumentation extends instrumentation.InstrumentationBase {
30+
@@ -257,25 +264,6 @@ class RemixInstrumentation extends instrumentation.InstrumentationBase {
1531
.then(async response => {
1632
addResponseAttributesToSpan(span, response);
1733

@@ -37,3 +53,23 @@ index 84e18d1051f57d5807e65c8b8ce858ceee7d4557..640a5253d565650338fe33e0ea52c8df
3753
return response;
3854
})
3955
.catch(async error => {
56+
diff --git a/build/esm/vendor/instrumentation.js b/build/esm/vendor/instrumentation.js
57+
index e33b84eecdffe3b10a5e50f13bafaf90775747c5..652a89c9194ea1d0bb0d748fb8f7f060ca2cf5ba 100644
58+
--- a/build/esm/vendor/instrumentation.js
59+
+++ b/build/esm/vendor/instrumentation.js
60+
@@ -138,7 +138,14 @@ class RemixInstrumentation extends InstrumentationBase {
61+
62+
const route = (result || []).slice(-1)[0]?.route;
63+
64+
- const routePath = route?.path;
65+
+ // Join every matched route segment so nested routes report their
66+
+ // full URL pattern on http.route (and the span name), not just the
67+
+ // leaf route's own path segment.
68+
+ const routePath =
69+
+ (result || [])
70+
+ .map((match) => match?.route?.path)
71+
+ .filter((segment) => typeof segment === 'string' && segment.length > 0)
72+
+ .join('/') || route?.path;
73+
if (span && routePath) {
74+
span.setAttribute(SemanticAttributes.HTTP_ROUTE, routePath);
75+
span.updateName(`remix.request ${routePath}`);

pnpm-lock.yaml

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)