1
1
/*
2
- * Copyright 2020-2022 the original author or authors.
2
+ * Copyright 2020-2023 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
19
19
import java .util .concurrent .CompletionStage ;
20
20
21
21
import graphql .ExecutionResult ;
22
+ import graphql .GraphQLContext ;
22
23
import graphql .execution .instrumentation .InstrumentationContext ;
23
24
import graphql .execution .instrumentation .InstrumentationState ;
24
25
import graphql .execution .instrumentation .SimpleInstrumentationContext ;
@@ -100,20 +101,21 @@ public InstrumentationContext<ExecutionResult> beginExecution(InstrumentationExe
100
101
InstrumentationState state ) {
101
102
if (state instanceof RequestObservationInstrumentationState instrumentationState ) {
102
103
ExecutionRequestObservationContext observationContext = new ExecutionRequestObservationContext (parameters .getExecutionInput ());
104
+ Observation parentObservation = parameters .getGraphQLContext ().get (OBSERVATION_KEY );
103
105
Observation requestObservation = instrumentationState .createRequestObservation (this .requestObservationConvention ,
104
106
observationContext , this .observationRegistry );
107
+ requestObservation .parentObservation (parentObservation );
108
+ parameters .getGraphQLContext ().put (OBSERVATION_KEY , requestObservation );
105
109
requestObservation .start ();
106
110
return new SimpleInstrumentationContext <>() {
107
111
@ Override
108
112
public void onCompleted (ExecutionResult result , Throwable exc ) {
109
113
observationContext .setResponse (result );
110
114
if (exc != null ) {
111
- observationContext .setError (exc );
112
115
requestObservation .error (exc );
113
116
}
114
- else {
115
- requestObservation .stop ();
116
- }
117
+ requestObservation .stop ();
118
+ instrumentationState .restoreParentObservation (parameters .getGraphQLContext (), parentObservation );
117
119
}
118
120
};
119
121
}
@@ -126,58 +128,66 @@ public DataFetcher<?> instrumentDataFetcher(DataFetcher<?> dataFetcher,
126
128
if (!parameters .isTrivialDataFetcher ()
127
129
&& state instanceof RequestObservationInstrumentationState instrumentationState ) {
128
130
return (environment ) -> {
131
+ GraphQLContext graphQLContext = parameters .getExecutionContext ().getGraphQLContext ();
132
+ Observation parentObservation = graphQLContext .get (OBSERVATION_KEY );
129
133
DataFetcherObservationContext observationContext = new DataFetcherObservationContext (parameters .getEnvironment ());
130
134
Observation dataFetcherObservation = instrumentationState .createDataFetcherObservation (
131
135
this .dataFetcherObservationConvention , observationContext , this .observationRegistry );
132
- parameters .getExecutionContext ().getGraphQLContext ().put (OBSERVATION_KEY , dataFetcherObservation );
136
+ dataFetcherObservation .parentObservation (parentObservation );
137
+ graphQLContext .put (OBSERVATION_KEY , dataFetcherObservation );
133
138
dataFetcherObservation .start ();
134
139
try {
135
140
Object value = dataFetcher .get (environment );
136
141
if (value instanceof CompletionStage <?> completion ) {
137
142
return completion .whenComplete ((result , error ) -> {
143
+ observationContext .setValue (result );
138
144
if (error != null ) {
139
145
dataFetcherObservation .error (error );
140
146
}
141
- observationContext .setValue (result );
142
147
dataFetcherObservation .stop ();
148
+ instrumentationState .restoreParentObservation (graphQLContext , parentObservation );
143
149
});
144
150
}
145
151
else {
146
152
observationContext .setValue (value );
147
153
dataFetcherObservation .stop ();
154
+ instrumentationState .restoreParentObservation (graphQLContext , parentObservation );
148
155
return value ;
149
156
}
150
157
}
151
158
catch (Throwable throwable ) {
152
159
dataFetcherObservation .error (throwable );
153
160
dataFetcherObservation .stop ();
161
+ instrumentationState .restoreParentObservation (graphQLContext , parentObservation );
154
162
throw throwable ;
155
163
}
156
164
};
157
165
}
158
- return super . instrumentDataFetcher ( dataFetcher , parameters , state ) ;
166
+ return dataFetcher ;
159
167
}
160
168
161
169
162
170
static class RequestObservationInstrumentationState implements InstrumentationState {
163
171
164
- private Observation requestObservation ;
165
-
166
-
167
172
Observation createRequestObservation (ExecutionRequestObservationConvention convention ,
168
173
ExecutionRequestObservationContext context , ObservationRegistry registry ) {
169
- Observation observation = GraphQlObservationDocumentation .EXECUTION_REQUEST .observation (convention ,
174
+ return GraphQlObservationDocumentation .EXECUTION_REQUEST .observation (convention ,
170
175
DEFAULT_REQUEST_CONVENTION , () -> context , registry );
171
- this .requestObservation = observation ;
172
- return observation ;
173
176
}
174
177
175
178
Observation createDataFetcherObservation (DataFetcherObservationConvention convention ,
176
179
DataFetcherObservationContext context , ObservationRegistry registry ) {
177
- Observation dataFetcherObservation = GraphQlObservationDocumentation .DATA_FETCHER .observation (convention ,
180
+ return GraphQlObservationDocumentation .DATA_FETCHER .observation (convention ,
178
181
DEFAULT_DATA_FETCHER_CONVENTION , () -> context , registry );
179
- dataFetcherObservation .parentObservation (requestObservation );
180
- return dataFetcherObservation ;
182
+ }
183
+
184
+ void restoreParentObservation (GraphQLContext context , Observation parentObservation ) {
185
+ if (parentObservation != null ) {
186
+ context .put (OBSERVATION_KEY , parentObservation );
187
+ }
188
+ else {
189
+ context .delete (OBSERVATION_KEY );
190
+ }
181
191
}
182
192
183
193
}
0 commit comments