Skip to content

Commit 77ff5d9

Browse files
authored
feat(node): Ensure connect spans have better data (#12130)
Ensuring connect spans have correct op & origin. Also streamlining E2E test app for this.
1 parent 85db0de commit 77ff5d9

File tree

5 files changed

+55
-11
lines changed

5 files changed

+55
-11
lines changed

dev-packages/e2e-tests/test-applications/node-connect/playwright.config.ts renamed to dev-packages/e2e-tests/test-applications/node-connect/playwright.config.mjs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import type { PlaywrightTestConfig } from '@playwright/test';
21
import { devices } from '@playwright/test';
32

43
const connectPort = 3030;
@@ -7,7 +6,7 @@ const eventProxyPort = 3031;
76
/**
87
* See https://playwright.dev/docs/test-configuration.
98
*/
10-
const config: PlaywrightTestConfig = {
9+
const config = {
1110
testDir: './tests',
1211
/* Maximum time one test can run for. */
1312
timeout: 150_000,

dev-packages/e2e-tests/test-applications/node-connect/tests/transactions.test.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,20 +72,22 @@ test('Sends an API route transaction', async ({ baseURL }) => {
7272
},
7373
{
7474
data: {
75-
'sentry.origin': 'manual',
75+
'sentry.origin': 'auto.http.otel.connect',
76+
'sentry.op': 'request_handler.connect',
7677
'http.route': '/test-transaction',
7778
'connect.type': 'request_handler',
7879
'connect.name': '/test-transaction',
7980
'otel.kind': 'INTERNAL',
8081
},
81-
description: 'request handler - /test-transaction',
82+
op: 'request_handler.connect',
83+
description: '/test-transaction',
8284
parent_span_id: expect.any(String),
8385
span_id: expect.any(String),
8486
start_timestamp: expect.any(Number),
8587
status: 'ok',
8688
timestamp: expect.any(Number),
8789
trace_id: expect.any(String),
88-
origin: 'manual',
90+
origin: 'auto.http.otel.connect',
8991
},
9092
],
9193
transaction: 'GET /test-transaction',

dev-packages/e2e-tests/test-applications/node-connect/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
"strict": true,
77
"noEmit": true
88
},
9-
"include": ["*.ts"]
9+
"include": ["src/*.ts"]
1010
}

dev-packages/node-integration-tests/suites/tracing/connect/test.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ describe('connect auto-instrumentation', () => {
1616
'connect.type': 'request_handler',
1717
'http.route': '/',
1818
'otel.kind': 'INTERNAL',
19-
'sentry.origin': 'manual',
19+
'sentry.origin': 'auto.http.otel.connect',
20+
'sentry.op': 'request_handler.connect',
2021
}),
21-
description: 'request handler - /',
22-
origin: 'manual',
22+
description: '/',
23+
origin: 'auto.http.otel.connect',
24+
op: 'request_handler.connect',
2325
status: 'ok',
2426
}),
2527
]),

packages/node/src/integrations/tracing/connect.ts

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
import { isWrapped } from '@opentelemetry/core';
22
import { ConnectInstrumentation } from '@opentelemetry/instrumentation-connect';
3-
import { captureException, defineIntegration, isEnabled } from '@sentry/core';
3+
import {
4+
SEMANTIC_ATTRIBUTE_SENTRY_OP,
5+
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
6+
captureException,
7+
defineIntegration,
8+
getClient,
9+
isEnabled,
10+
spanToJSON,
11+
} from '@sentry/core';
412
import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry';
5-
import type { IntegrationFn } from '@sentry/types';
13+
import type { IntegrationFn, Span } from '@sentry/types';
614
import { consoleSandbox } from '@sentry/utils';
715

816
type ConnectApp = {
@@ -30,6 +38,16 @@ function connectErrorMiddleware(err: any, req: any, res: any, next: any): void {
3038
export const setupConnectErrorHandler = (app: ConnectApp): void => {
3139
app.use(connectErrorMiddleware);
3240

41+
// Sadly, ConnectInstrumentation has no requestHook, so we need to add the attributes here
42+
// We register this hook in this method, because if we register it in the integration `setup`,
43+
// it would always run even for users that are not even using fastify
44+
const client = getClient();
45+
if (client) {
46+
client.on('spanStart', span => {
47+
addConnectSpanAttributes(span);
48+
});
49+
}
50+
3351
if (!isWrapped(app.use) && isEnabled()) {
3452
consoleSandbox(() => {
3553
// eslint-disable-next-line no-console
@@ -39,3 +57,26 @@ export const setupConnectErrorHandler = (app: ConnectApp): void => {
3957
});
4058
}
4159
};
60+
61+
function addConnectSpanAttributes(span: Span): void {
62+
const attributes = spanToJSON(span).data || {};
63+
64+
// this is one of: middleware, request_handler
65+
const type = attributes['connect.type'];
66+
67+
// If this is already set, or we have no connect span, no need to process again...
68+
if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] || !type) {
69+
return;
70+
}
71+
72+
span.setAttributes({
73+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.otel.connect',
74+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: `${type}.connect`,
75+
});
76+
77+
// Also update the name, we don't need to "middleware - " prefix
78+
const name = attributes['connect.name'];
79+
if (typeof name === 'string') {
80+
span.updateName(name);
81+
}
82+
}

0 commit comments

Comments
 (0)