Skip to content

Commit fa5721f

Browse files
msonnbclaude
andcommitted
feat(node)!: Use function span op for hapi plugin route handlers
A plugin-registered hapi route runs the user's request handler, so it is a terminal handler like the express/fastify/hono routes in this migration. Map `plugin.hapi` to the cross-framework `function` op; `router.hapi` and `server.ext.hapi` (framework routing/extension lifecycle) keep their ops. Op is set via the `sentry.op` attribute only; `hapi.type` is unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent acfa7d0 commit fa5721f

3 files changed

Lines changed: 10 additions & 5 deletions

File tree

dev-packages/node-integration-tests/suites/tracing/hapi/scenario.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ const run = async () => {
5151
},
5252
});
5353

54-
// Route registered via a plugin produces a `plugin.hapi` span.
54+
// Route registered via a plugin produces a `function` op span.
5555
await server.register({
5656
name: 'testPlugin',
5757
version: '1.0.0',

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@ describe('hapi auto-instrumentation', () => {
5858
spans: expect.arrayContaining([
5959
expect.objectContaining({
6060
description: 'GET /plugin-route',
61-
op: 'plugin.hapi',
61+
op: 'function',
6262
origin,
6363
data: expect.objectContaining({
6464
'http.route': '/plugin-route',
6565
'hapi.type': 'plugin',
6666
'hapi.plugin.name': 'testPlugin',
67-
'sentry.op': 'plugin.hapi',
67+
'sentry.op': 'function',
6868
'sentry.origin': origin,
6969
}),
7070
}),

packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22
* OTel-free, `@hapi/*`-free port of the span-building helpers and handler/ext
33
* wrap logic from the vendored `@opentelemetry/instrumentation-hapi`
44
* (upstream @opentelemetry/instrumentation-hapi@0.64.0). Span output (names,
5-
* ops, origins, attributes) is kept byte-identical to that instrumentation;
5+
* origins, attributes) is kept close to that instrumentation — except the
6+
* plugin-route op, which is normalized to the cross-framework `function` op;
67
* span creation goes through the `@sentry/core` API and the OTel active-span
78
* guard is replaced with `getActiveSpan()`.
89
*/
910

1011
import { getActiveSpan, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startSpan } from '@sentry/core';
12+
import { SENTRY_OP } from '@sentry/conventions/attributes';
13+
import { WEB_SERVER_FUNCTION_SPAN_OP } from '@sentry/conventions/op';
1114
import type {
1215
LifecycleMethod,
1316
PatchableExtMethod,
@@ -104,12 +107,14 @@ export const getExtMetadata = (
104107
};
105108

106109
function startMetadataSpan(metadata: SpanMetadata, original: () => unknown): unknown {
110+
const hapiType = metadata.attributes[AttributeNames.HAPI_TYPE];
111+
const op = hapiType === HapiLayerType.PLUGIN ? WEB_SERVER_FUNCTION_SPAN_OP : `${hapiType}.hapi`;
107112
return startSpan(
108113
{
109114
name: metadata.name,
110-
op: `${metadata.attributes[AttributeNames.HAPI_TYPE]}.hapi`,
111115
attributes: {
112116
...metadata.attributes,
117+
[SENTRY_OP]: op,
113118
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.hapi',
114119
},
115120
},

0 commit comments

Comments
 (0)