@@ -2,17 +2,21 @@ import { isWrapped } from '@opentelemetry/core';
22import { HapiInstrumentation } from '@opentelemetry/instrumentation-hapi' ;
33import {
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' ;
1418import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry' ;
15- import type { IntegrationFn } from '@sentry/types' ;
19+ import type { IntegrationFn , Span } from '@sentry/types' ;
1620import { consoleSandbox , logger } from '@sentry/utils' ;
1721import { DEBUG_BUILD } from '../../../debug-build' ;
1822import type { Boom , RequestEvent , ResponseObject , Server } from './types' ;
@@ -95,6 +99,16 @@ export const hapiErrorPlugin = {
9599export 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