Skip to content

Commit 299fba7

Browse files
committed
use fastify hook instead of reading from span name
1 parent 1945fbf commit 299fba7

File tree

2 files changed

+46
-21
lines changed

2 files changed

+46
-21
lines changed

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,23 @@ test('Sends an API route transaction', async ({ baseURL }) => {
5656
expect(transactionEvent).toEqual(
5757
expect.objectContaining({
5858
spans: [
59+
{
60+
data: {
61+
'plugin.name': 'fastify -> sentry-fastify-error-handler',
62+
'fastify.type': 'middleware',
63+
'hook.name': 'onRequest',
64+
'otel.kind': 'INTERNAL',
65+
'sentry.origin': 'manual',
66+
},
67+
description: 'middleware - fastify -> sentry-fastify-error-handler',
68+
parent_span_id: expect.any(String),
69+
span_id: expect.any(String),
70+
start_timestamp: expect.any(Number),
71+
status: 'ok',
72+
timestamp: expect.any(Number),
73+
trace_id: expect.any(String),
74+
origin: 'manual',
75+
},
5976
{
6077
data: {
6178
'plugin.name': 'fastify -> sentry-fastify-error-handler',

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

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import { registerInstrumentations } from '@opentelemetry/instrumentation';
2-
import type { FastifyRequestInfo } from '@opentelemetry/instrumentation-fastify';
32
import { FastifyInstrumentation } from '@opentelemetry/instrumentation-fastify';
4-
import { captureException, defineIntegration, getIsolationScope, spanToJSON } from '@sentry/core';
3+
import { captureException, defineIntegration, getCurrentScope, getIsolationScope } from '@sentry/core';
54
import type { IntegrationFn } from '@sentry/types';
65

7-
import type { Span } from '@opentelemetry/api';
86
import { addOriginToSpan } from '../../utils/addOriginToSpan';
97

108
const _fastifyIntegration = (() => {
@@ -14,9 +12,8 @@ const _fastifyIntegration = (() => {
1412
registerInstrumentations({
1513
instrumentations: [
1614
new FastifyInstrumentation({
17-
requestHook(span, info) {
15+
requestHook(span) {
1816
addOriginToSpan(span, 'auto.http.otel.fastify');
19-
updateScopeTransactionName(span, info);
2017
},
2118
}),
2219
],
@@ -25,22 +22,6 @@ const _fastifyIntegration = (() => {
2522
};
2623
}) satisfies IntegrationFn;
2724

28-
function updateScopeTransactionName(span: Span, info: FastifyRequestInfo): void {
29-
if (!span.isRecording()) {
30-
return;
31-
}
32-
33-
const attributes = spanToJSON(span).data;
34-
if (!attributes || !attributes['http.route']) {
35-
return;
36-
}
37-
38-
const req = info.request as { method?: string };
39-
const method = req.method?.toUpperCase() || 'GET';
40-
const route = String(attributes['http.route']);
41-
getIsolationScope().setTransactionName(`${method} ${route}`);
42-
}
43-
4425
/**
4526
* Express integration
4627
*
@@ -54,6 +35,19 @@ interface Fastify {
5435
addHook: (hook: string, handler: (request: unknown, reply: unknown, error: Error) => void) => void;
5536
}
5637

38+
/**
39+
* Minimal request type containing properties around route information.
40+
* Works for Fastify 3, 4 and presumably 5.
41+
*/
42+
interface FastifyRequestRouteInfo {
43+
44+
routeOptions?: {
45+
url?: string;
46+
method?: string;
47+
};
48+
routerPath?: string;
49+
}
50+
5751
/**
5852
* Setup an error handler for Fastify.
5953
*/
@@ -64,6 +58,20 @@ export function setupFastifyErrorHandler(fastify: Fastify): void {
6458
captureException(error);
6559
});
6660

61+
// registering `onRequest` hook here instead of using Otel `onRequest` callback b/c `onRequest` hook
62+
// is ironically called in the fastify `preHandler` hook which is called later in the lifecycle:
63+
// https://fastify.dev/docs/latest/Reference/Lifecycle/
64+
fastify.addHook('onRequest', async (request, _reply) => {
65+
const reqWithRouteInfo = request as FastifyRequestRouteInfo;
66+
67+
// Taken from Otel Fastify instrumentation:
68+
// https://github.com/open-telemetry/opentelemetry-js-contrib/blob/main/plugins/node/opentelemetry-instrumentation-fastify/src/instrumentation.ts#L94-L96
69+
const routeName = reqWithRouteInfo.routeOptions?.url || reqWithRouteInfo.routerPath;
70+
const method = reqWithRouteInfo.routeOptions?.method || 'GET';
71+
72+
getIsolationScope().setTransactionName(`${method} ${routeName}`);
73+
});
74+
6775
done();
6876
},
6977
{

0 commit comments

Comments
 (0)