@@ -2,17 +2,21 @@ import { isWrapped } from '@opentelemetry/core';
2
2
import { HapiInstrumentation } from '@opentelemetry/instrumentation-hapi' ;
3
3
import {
4
4
SDK_VERSION ,
5
+ SEMANTIC_ATTRIBUTE_SENTRY_OP ,
6
+ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ,
5
7
SPAN_STATUS_ERROR ,
6
8
captureException ,
7
9
defineIntegration ,
8
10
getActiveSpan ,
11
+ getClient ,
9
12
getDefaultIsolationScope ,
10
13
getIsolationScope ,
11
14
getRootSpan ,
12
15
isEnabled ,
16
+ spanToJSON ,
13
17
} from '@sentry/core' ;
14
18
import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry' ;
15
- import type { IntegrationFn } from '@sentry/types' ;
19
+ import type { IntegrationFn , Span } from '@sentry/types' ;
16
20
import { consoleSandbox , logger } from '@sentry/utils' ;
17
21
import { DEBUG_BUILD } from '../../../debug-build' ;
18
22
import type { Boom , RequestEvent , ResponseObject , Server } from './types' ;
@@ -95,6 +99,16 @@ export const hapiErrorPlugin = {
95
99
export async function setupHapiErrorHandler ( server : Server ) : Promise < void > {
96
100
await server . register ( hapiErrorPlugin ) ;
97
101
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
+
98
112
// eslint-disable-next-line @typescript-eslint/unbound-method
99
113
if ( ! isWrapped ( server . register ) && isEnabled ( ) ) {
100
114
consoleSandbox ( ( ) => {
@@ -105,3 +119,20 @@ export async function setupHapiErrorHandler(server: Server): Promise<void> {
105
119
} ) ;
106
120
}
107
121
}
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