Skip to content

Commit 15fface

Browse files
committed
fix incorrect getTraceData usage as well as fix a bug in propagator
1 parent 3fdd111 commit 15fface

File tree

4 files changed

+44
-38
lines changed

4 files changed

+44
-38
lines changed

dev-packages/e2e-tests/test-applications/remix-server-timing/app/entry.client.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ declare global {
1414
}
1515
}
1616

17-
import { RemixBrowser, useLocation, useMatches } from '@remix-run/react';
18-
import * as Sentry from '@sentry/remix';
19-
import { StrictMode, startTransition, useEffect } from 'react';
20-
import { hydrateRoot } from 'react-dom/client';
17+
import { RemixBrowser, useLocation, useMatches } from "@remix-run/react";
18+
import * as Sentry from "@sentry/remix";
19+
import { StrictMode, startTransition, useEffect } from "react";
20+
import { hydrateRoot } from "react-dom/client";
2121

2222
Sentry.init({
23-
environment: 'qa', // dynamic sampling bias to keep transactions
23+
environment: "qa", // dynamic sampling bias to keep transactions
2424
dsn: window.ENV.SENTRY_DSN,
2525
integrations: [
2626
Sentry.browserTracingIntegration({
@@ -31,7 +31,7 @@ Sentry.init({
3131
],
3232
// Performance Monitoring
3333
tracesSampleRate: 1.0, // Capture 100% of the transactions
34-
tunnel: 'http://localhost:3031/', // proxy server
34+
tunnel: "http://localhost:3031/", // proxy server
3535
});
3636

3737
startTransition(() => {

dev-packages/e2e-tests/test-applications/remix-server-timing/tests/server-timing-trace-propagation.test.ts

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ test('propagates trace context from server-timing header to client pageload', as
1212
return transactionEvent.contexts?.trace?.op === 'pageload' && transactionEvent.tags?.['sentry_test'] === testTag;
1313
});
1414

15+
const httpServerTransactionPromise = waitForTransaction('remix-server-timing', transactionEvent => {
16+
return transactionEvent.contexts?.trace?.op === 'http.server';
17+
});
18+
1519
await page.goto(`/?tag=${testTag}`);
1620

1721
const response = await responsePromise;
@@ -30,25 +34,46 @@ test('propagates trace context from server-timing header to client pageload', as
3034
expect(headerSampled).toBe('1');
3135

3236
const pageloadTransaction = await pageLoadTransactionPromise;
37+
const httpServerTransaction = await httpServerTransactionPromise;
3338

3439
expect(pageloadTransaction).toBeDefined();
3540
expect(pageloadTransaction.transaction).toBe('/');
3641

42+
expect(httpServerTransaction.transaction).toMatch(/^GET http:\/\/localhost:\d+\/$/);
43+
3744
expect(pageloadTransaction.contexts?.trace?.trace_id).toEqual(headerTraceId);
3845
expect(pageloadTransaction.contexts?.trace?.parent_span_id).toEqual(headerSpanId);
46+
47+
expect(httpServerTransaction.contexts?.trace?.trace_id).toEqual(headerTraceId);
48+
expect(httpServerTransaction.contexts?.trace?.span_id).toEqual(headerSpanId);
3949
});
4050

4151
test('includes server-timing header on redirect responses', async ({ page }) => {
4252
const redirectResponsePromise = page.waitForResponse(response => response.url().includes('/redirect-test'));
53+
const redirectedPageloadResponsePromise = page.waitForResponse(response =>
54+
response.url().includes('/user/redirected'),
55+
);
56+
57+
const pageLoadTransactionPromise = waitForTransaction('remix-server-timing', transactionEvent => {
58+
return transactionEvent.contexts?.trace?.op === 'pageload';
59+
});
4360

4461
await page.goto('/redirect-test');
4562

4663
const redirectResponse = await redirectResponsePromise;
47-
const serverTimingHeader = redirectResponse.headers()['server-timing'];
64+
const redirectServerTimingHeader = redirectResponse.headers()['server-timing'];
4865

49-
expect(serverTimingHeader).toBeDefined();
50-
expect(serverTimingHeader).toContain('sentry-trace');
66+
expect(redirectServerTimingHeader).toBeDefined();
67+
expect(redirectServerTimingHeader).toContain('sentry-trace');
68+
expect(redirectServerTimingHeader).toContain('baggage');
5169

70+
const redirectSentryTraceMatch = redirectServerTimingHeader?.match(/sentry-trace;desc="([^"]+)"/);
71+
expect(redirectSentryTraceMatch).toBeTruthy();
72+
expect(redirectSentryTraceMatch![1]).toMatch(/[a-f0-9]{32}-[a-f0-9]{16}-1/);
73+
74+
const redirectedPageloadResponse = await redirectedPageloadResponsePromise;
75+
76+
const serverTimingHeader = redirectedPageloadResponse.headers()['server-timing'];
5277
const sentryTraceMatch = serverTimingHeader?.match(/sentry-trace;desc="([^"]+)"/);
5378
expect(sentryTraceMatch).toBeTruthy();
5479
const [traceId, spanId] = sentryTraceMatch![1].split('-');
@@ -57,6 +82,11 @@ test('includes server-timing header on redirect responses', async ({ page }) =>
5782

5883
await page.waitForURL(/\/user\/redirected/);
5984
await expect(page.locator('h1')).toContainText('User redirected');
85+
86+
const pageLoadTransaction = await pageLoadTransactionPromise;
87+
expect(pageLoadTransaction.transaction).toBe('/user/:id');
88+
expect(pageLoadTransaction.contexts?.trace?.trace_id).toEqual(traceId);
89+
expect(pageLoadTransaction.contexts?.trace?.parent_span_id).toEqual(spanId);
6090
});
6191

6292
test('excludes server-timing header from client-side navigation data fetches', async ({ page }) => {

packages/opentelemetry/src/utils/getTraceData.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export function getTraceData({
2424
if (span) {
2525
const { scope } = getCapturedScopesOnSpan(span);
2626
// fall back to current context if for whatever reason we can't find the one of the span
27-
ctx = (scope && getContextFromScope(scope)) || api.trace.setSpan(api.context.active(), span);
27+
ctx = api.trace.setSpan(api.context.active(), span) || (scope && getContextFromScope(scope));
2828
}
2929

3030
const { traceId, spanId, sampled, dynamicSamplingContext } = getInjectionData(ctx, { scope, client });

packages/remix/src/server/serverTimingTracePropagation.ts

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
11
import type { Span } from '@sentry/core';
2-
import {
3-
debug,
4-
getActiveSpan,
5-
getRootSpan,
6-
getTraceData,
7-
isNodeEnv,
8-
spanToBaggageHeader,
9-
spanToTraceHeader,
10-
} from '@sentry/core';
2+
import { debug, getTraceData, isNodeEnv } from '@sentry/core';
113
import { DEBUG_BUILD } from '../utils/debug-build';
124
import { isCloudflareEnv } from '../utils/utils';
135

@@ -18,25 +10,9 @@ export function generateSentryServerTimingHeader(span?: Span): string | null {
1810
}
1911

2012
try {
21-
let resolvedSpan = span;
22-
if (!resolvedSpan) {
23-
const activeSpan = getActiveSpan();
24-
if (activeSpan) {
25-
resolvedSpan = getRootSpan(activeSpan);
26-
}
27-
}
28-
29-
let sentryTrace: string | undefined;
30-
let baggage: string | undefined;
31-
32-
if (resolvedSpan) {
33-
sentryTrace = spanToTraceHeader(resolvedSpan);
34-
baggage = spanToBaggageHeader(resolvedSpan);
35-
} else {
36-
const traceData = getTraceData();
37-
sentryTrace = traceData['sentry-trace'];
38-
baggage = traceData.baggage;
39-
}
13+
const traceData = getTraceData({ span });
14+
const sentryTrace = traceData['sentry-trace'];
15+
const baggage = traceData.baggage;
4016

4117
if (!sentryTrace) {
4218
return null;

0 commit comments

Comments
 (0)