Skip to content

Commit eec0687

Browse files
authored
feat(node): Ensure Hapi spans have better data (#12140)
Ensure we have an op and origin for hapi spans.
1 parent 7e59832 commit eec0687

File tree

3 files changed

+60
-4
lines changed
  • dev-packages
  • packages/node/src/integrations/tracing/hapi

3 files changed

+60
-4
lines changed

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

+24
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,30 @@ test('Sends successful transaction', async ({ baseURL }) => {
5656
},
5757
}),
5858
);
59+
60+
const spans = transactionEvent.spans || [];
61+
62+
expect(spans).toEqual([
63+
{
64+
data: {
65+
'hapi.type': 'router',
66+
'http.method': 'GET',
67+
'http.route': '/test-success',
68+
'otel.kind': 'INTERNAL',
69+
'sentry.op': 'router.hapi',
70+
'sentry.origin': 'auto.http.otel.hapi',
71+
},
72+
description: 'GET /test-success',
73+
op: 'router.hapi',
74+
origin: 'auto.http.otel.hapi',
75+
parent_span_id: expect.any(String),
76+
span_id: expect.any(String),
77+
start_timestamp: expect.any(Number),
78+
status: 'ok',
79+
timestamp: expect.any(Number),
80+
trace_id: expect.any(String),
81+
},
82+
]);
5983
});
6084

6185
test('Sends parameterized transactions to Sentry', async ({ baseURL }) => {

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ describe('hapi auto-instrumentation', () => {
1515
'http.route': '/',
1616
'http.method': 'GET',
1717
'hapi.type': 'router',
18-
'sentry.origin': 'manual',
19-
'sentry.op': 'http',
18+
'sentry.origin': 'auto.http.otel.hapi',
19+
'sentry.op': 'router.hapi',
2020
}),
2121
description: 'GET /',
22-
op: 'http',
22+
op: 'router.hapi',
23+
origin: 'auto.http.otel.hapi',
2324
status: 'ok',
2425
}),
2526
]),

packages/node/src/integrations/tracing/hapi/index.ts

+32-1
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,21 @@ import { isWrapped } from '@opentelemetry/core';
22
import { HapiInstrumentation } from '@opentelemetry/instrumentation-hapi';
33
import {
44
SDK_VERSION,
5+
SEMANTIC_ATTRIBUTE_SENTRY_OP,
6+
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
57
SPAN_STATUS_ERROR,
68
captureException,
79
defineIntegration,
810
getActiveSpan,
11+
getClient,
912
getDefaultIsolationScope,
1013
getIsolationScope,
1114
getRootSpan,
1215
isEnabled,
16+
spanToJSON,
1317
} from '@sentry/core';
1418
import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry';
15-
import type { IntegrationFn } from '@sentry/types';
19+
import type { IntegrationFn, Span } from '@sentry/types';
1620
import { consoleSandbox, logger } from '@sentry/utils';
1721
import { DEBUG_BUILD } from '../../../debug-build';
1822
import type { Boom, RequestEvent, ResponseObject, Server } from './types';
@@ -95,6 +99,16 @@ export const hapiErrorPlugin = {
9599
export async function setupHapiErrorHandler(server: Server): Promise<void> {
96100
await server.register(hapiErrorPlugin);
97101

102+
// Sadly, middleware spans do not go through `requestHook`, so we handle those here
103+
// We register this hook in this method, because if we register it in the integration `setup`,
104+
// it would always run even for users that are not even using hapi
105+
const client = getClient();
106+
if (client) {
107+
client.on('spanStart', span => {
108+
addHapiSpanAttributes(span);
109+
});
110+
}
111+
98112
// eslint-disable-next-line @typescript-eslint/unbound-method
99113
if (!isWrapped(server.register) && isEnabled()) {
100114
consoleSandbox(() => {
@@ -105,3 +119,20 @@ export async function setupHapiErrorHandler(server: Server): Promise<void> {
105119
});
106120
}
107121
}
122+
123+
function addHapiSpanAttributes(span: Span): void {
124+
const attributes = spanToJSON(span).data || {};
125+
126+
// this is one of: router, plugin, server.ext
127+
const type = attributes['hapi.type'];
128+
129+
// If this is already set, or we have no Hapi span, no need to process again...
130+
if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] || !type) {
131+
return;
132+
}
133+
134+
span.setAttributes({
135+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.otel.hapi',
136+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: `${type}.hapi`,
137+
});
138+
}

0 commit comments

Comments
 (0)