1818
1919import graphql .ExecutionResult ;
2020import graphql .GraphQLContext ;
21- import graphql .execution .DataFetcherResult ;
2221import graphql .execution .instrumentation .InstrumentationContext ;
2322import graphql .execution .instrumentation .InstrumentationState ;
2423import graphql .execution .instrumentation .SimpleInstrumentation ;
2827import graphql .execution .instrumentation .parameters .InstrumentationFieldFetchParameters ;
2928import graphql .schema .DataFetcher ;
3029import graphql .schema .DataFetchingEnvironment ;
30+ import graphql .schema .DataFetchingEnvironmentImpl ;
3131import io .micrometer .observation .Observation ;
3232import io .micrometer .observation .ObservationRegistry ;
3333import io .micrometer .observation .contextpropagation .ObservationThreadLocalAccessor ;
34- import org .apache .commons .logging .Log ;
35- import org .apache .commons .logging .LogFactory ;
3634import org .springframework .lang .Nullable ;
3735
3836import java .util .concurrent .CompletionException ;
5755 */
5856public class GraphQlObservationInstrumentation extends SimpleInstrumentation {
5957
60- private static final Log logger = LogFactory .getLog (GraphQlObservationInstrumentation .class );
61-
6258 private static final ExecutionRequestObservationConvention DEFAULT_REQUEST_CONVENTION =
6359 new DefaultExecutionRequestObservationConvention ();
6460
@@ -106,13 +102,11 @@ public InstrumentationState createState(InstrumentationCreateStateParameters par
106102 @ Override
107103 public InstrumentationContext <ExecutionResult > beginExecution (InstrumentationExecutionParameters parameters ,
108104 InstrumentationState state ) {
109- if (state instanceof RequestObservationInstrumentationState instrumentationState ) {
105+ if (state == RequestObservationInstrumentationState . INSTANCE ) {
110106 ExecutionRequestObservationContext observationContext = new ExecutionRequestObservationContext (parameters .getExecutionInput ());
111107 Observation requestObservation = GraphQlObservationDocumentation .EXECUTION_REQUEST .observation (this .requestObservationConvention ,
112108 DEFAULT_REQUEST_CONVENTION , () -> observationContext , this .observationRegistry );
113- requestObservation .parentObservation (getCurrentObservation (parameters .getGraphQLContext ()));
114- GraphQLContext graphQLContext = parameters .getGraphQLContext ();
115- graphQLContext .put (ObservationThreadLocalAccessor .KEY , requestObservation );
109+ setCurrentObservation (requestObservation , parameters .getGraphQLContext ());
116110 requestObservation .start ();
117111 return new SimpleInstrumentationContext <>() {
118112 @ Override
@@ -128,24 +122,27 @@ public void onCompleted(ExecutionResult result, Throwable exc) {
128122 return super .beginExecution (parameters , state );
129123 }
130124
131- @ Nullable
132- private static Observation getCurrentObservation (GraphQLContext graphQLContext ) {
133- return graphQLContext .get (ObservationThreadLocalAccessor .KEY );
125+ private static void setCurrentObservation (Observation currentObservation , GraphQLContext graphQlContext ) {
126+ Observation parentObservation = graphQlContext .get (ObservationThreadLocalAccessor .KEY );
127+ currentObservation .parentObservation (parentObservation );
128+ graphQlContext .put (ObservationThreadLocalAccessor .KEY , currentObservation );
134129 }
135130
136131 @ Override
137132 public DataFetcher <?> instrumentDataFetcher (DataFetcher <?> dataFetcher ,
138133 InstrumentationFieldFetchParameters parameters , InstrumentationState state ) {
139134 if (!parameters .isTrivialDataFetcher ()
140- && state instanceof RequestObservationInstrumentationState instrumentationState ) {
135+ && state == RequestObservationInstrumentationState . INSTANCE ) {
141136 return (environment ) -> {
142- DataFetcherObservationContext observationContext = new DataFetcherObservationContext (parameters . getEnvironment () );
137+ DataFetcherObservationContext observationContext = new DataFetcherObservationContext (environment );
143138 Observation dataFetcherObservation = GraphQlObservationDocumentation .DATA_FETCHER .observation (this .dataFetcherObservationConvention ,
144139 DEFAULT_DATA_FETCHER_CONVENTION , () -> observationContext , this .observationRegistry );
145140 dataFetcherObservation .parentObservation (getCurrentObservation (environment ));
146141 dataFetcherObservation .start ();
142+
143+ DataFetchingEnvironment dataFetchingEnvironment = wrapDataFetchingEnvironment (environment , dataFetcherObservation );
147144 try {
148- Object value = dataFetcher .get (environment );
145+ Object value = dataFetcher .get (dataFetchingEnvironment );
149146 if (value instanceof CompletionStage <?> completion ) {
150147 return completion .handle ((result , error ) -> {
151148 observationContext .setValue (result );
@@ -155,13 +152,13 @@ public DataFetcher<?> instrumentDataFetcher(DataFetcher<?> dataFetcher,
155152 throw new CompletionException (error );
156153 }
157154 dataFetcherObservation .stop ();
158- return wrapAsDataFetcherResult ( result , dataFetcherObservation , environment . getLocalContext ()) ;
155+ return result ;
159156 });
160157 }
161158 else {
162159 observationContext .setValue (value );
163160 dataFetcherObservation .stop ();
164- return wrapAsDataFetcherResult ( value , dataFetcherObservation , environment . getLocalContext ()) ;
161+ return value ;
165162 }
166163 }
167164 catch (Throwable throwable ) {
@@ -177,39 +174,25 @@ public DataFetcher<?> instrumentDataFetcher(DataFetcher<?> dataFetcher,
177174 @ Nullable
178175 private static Observation getCurrentObservation (DataFetchingEnvironment environment ) {
179176 Observation currentObservation = null ;
180- if (environment .getLocalContext () != null && environment .getLocalContext () instanceof GraphQLContext ) {
181- GraphQLContext localContext = environment .getLocalContext ();
177+ if (environment .getLocalContext () instanceof GraphQLContext localContext ) {
182178 currentObservation = localContext .get (ObservationThreadLocalAccessor .KEY );
183179 }
184180 if (currentObservation == null ) {
185- return environment .getGraphQlContext ().get (ObservationThreadLocalAccessor .KEY );
181+ currentObservation = environment .getGraphQlContext ().get (ObservationThreadLocalAccessor .KEY );
186182 }
187183 return currentObservation ;
188184 }
189185
190- private static DataFetcherResult <?> wrapAsDataFetcherResult (Object value , Observation dataFetcherObservation ,
191- @ Nullable GraphQLContext dataFetcherLocalContext ) {
192- if (value instanceof DataFetcherResult <?> result ) {
193- if (result .getLocalContext () == null ) {
194- return result .transform (builder -> builder .localContext (GraphQLContext .newContext ().of (ObservationThreadLocalAccessor .KEY , dataFetcherObservation ).build ()));
195- }
196- else if (result .getLocalContext () instanceof GraphQLContext ) {
197- ((GraphQLContext ) result .getLocalContext ()).put (ObservationThreadLocalAccessor .KEY , dataFetcherObservation );
198- } else {
199- logger .debug ("Cannot add observation to localContext as it is not a GraphQLContext but a "
200- + result .getLocalContext ().getClass ().toString ());
201- }
202- return result ;
186+ private static DataFetchingEnvironment wrapDataFetchingEnvironment (DataFetchingEnvironment environment , Observation dataFetcherObservation ) {
187+ GraphQLContext .Builder localContextBuilder = GraphQLContext .newContext ();
188+ if (environment .getLocalContext () instanceof GraphQLContext localContext ) {
189+ localContextBuilder .of (localContext );
203190 }
204- else {
205- GraphQLContext localContext = dataFetcherLocalContext == null ?
206- GraphQLContext .newContext ().build () : GraphQLContext .newContext ().of (dataFetcherLocalContext ).build ();
207- return DataFetcherResult .newResult ()
208- .data (value )
209- .localContext (localContext .put (ObservationThreadLocalAccessor .KEY , dataFetcherObservation ))
210- .build ();
211- }
212-
191+ localContextBuilder .of (ObservationThreadLocalAccessor .KEY , dataFetcherObservation );
192+ return DataFetchingEnvironmentImpl
193+ .newDataFetchingEnvironment (environment )
194+ .localContext (localContextBuilder .build ())
195+ .build ();
213196 }
214197
215198
0 commit comments