make elasticsearch indy-ready (#14672)
This commit is contained in:
		
							parent
							
								
									626c296066
								
							
						
					
					
						commit
						75a342995c
					
				|  | @ -42,4 +42,9 @@ public class ElasticsearchApiClientInstrumentationModule extends Instrumentation | |||
|     return asList( | ||||
|         new RestClientTransportInstrumentation(), new RestClientHttpClientInstrumentation()); | ||||
|   } | ||||
| 
 | ||||
|   @Override | ||||
|   public boolean isIndyReady() { | ||||
|     return true; | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,18 @@ | |||
| /* | ||||
|  * Copyright The OpenTelemetry Authors | ||||
|  * SPDX-License-Identifier: Apache-2.0 | ||||
|  */ | ||||
| 
 | ||||
| package io.opentelemetry.javaagent.instrumentation.elasticsearch.apiclient; | ||||
| 
 | ||||
| import io.opentelemetry.instrumentation.api.util.VirtualField; | ||||
| import io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal.ElasticsearchEndpointDefinition; | ||||
| import org.elasticsearch.client.Request; | ||||
| 
 | ||||
| public class ElasticsearchApiClientSingletons { | ||||
| 
 | ||||
|   public static final VirtualField<Request, ElasticsearchEndpointDefinition> ENDPOINT_DEFINITION = | ||||
|       VirtualField.find(Request.class, ElasticsearchEndpointDefinition.class); | ||||
| 
 | ||||
|   private ElasticsearchApiClientSingletons() {} | ||||
| } | ||||
|  | @ -5,6 +5,7 @@ | |||
| 
 | ||||
| package io.opentelemetry.javaagent.instrumentation.elasticsearch.apiclient; | ||||
| 
 | ||||
| import static io.opentelemetry.javaagent.instrumentation.elasticsearch.apiclient.ElasticsearchApiClientSingletons.ENDPOINT_DEFINITION; | ||||
| import static net.bytebuddy.matcher.ElementMatchers.isMethod; | ||||
| import static net.bytebuddy.matcher.ElementMatchers.named; | ||||
| import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; | ||||
|  | @ -13,8 +14,6 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument; | |||
| 
 | ||||
| import io.opentelemetry.context.Context; | ||||
| import io.opentelemetry.context.Scope; | ||||
| import io.opentelemetry.instrumentation.api.util.VirtualField; | ||||
| import io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal.ElasticsearchEndpointDefinition; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; | ||||
| import net.bytebuddy.asm.Advice; | ||||
|  | @ -72,8 +71,7 @@ public class RestClientHttpClientInstrumentation implements TypeInstrumentation | |||
|       if (endpointId.startsWith("es/") && endpointId.length() > 3) { | ||||
|         endpointId = endpointId.substring(3); | ||||
|       } | ||||
|       VirtualField.find(Request.class, ElasticsearchEndpointDefinition.class) | ||||
|           .set(request, ElasticsearchEndpointMap.get(endpointId)); | ||||
|       ENDPOINT_DEFINITION.set(request, ElasticsearchEndpointMap.get(endpointId)); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -5,14 +5,13 @@ | |||
| 
 | ||||
| package io.opentelemetry.javaagent.instrumentation.elasticsearch.apiclient; | ||||
| 
 | ||||
| import static io.opentelemetry.javaagent.instrumentation.elasticsearch.apiclient.ElasticsearchApiClientSingletons.ENDPOINT_DEFINITION; | ||||
| import static net.bytebuddy.matcher.ElementMatchers.isMethod; | ||||
| import static net.bytebuddy.matcher.ElementMatchers.named; | ||||
| import static net.bytebuddy.matcher.ElementMatchers.returns; | ||||
| import static net.bytebuddy.matcher.ElementMatchers.takesArgument; | ||||
| 
 | ||||
| import co.elastic.clients.transport.Endpoint; | ||||
| import io.opentelemetry.instrumentation.api.util.VirtualField; | ||||
| import io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal.ElasticsearchEndpointDefinition; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; | ||||
| import net.bytebuddy.asm.Advice; | ||||
|  | @ -44,13 +43,11 @@ public class RestClientTransportInstrumentation implements TypeInstrumentation { | |||
|     @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) | ||||
|     public static void onPrepareLowLevelRequest( | ||||
|         @Advice.Argument(1) Endpoint<?, ?, ?> endpoint, @Advice.Return Request request) { | ||||
|       VirtualField<Request, ElasticsearchEndpointDefinition> virtualField = | ||||
|           VirtualField.find(Request.class, ElasticsearchEndpointDefinition.class); | ||||
|       String endpointId = endpoint.id(); | ||||
|       if (endpointId.startsWith("es/") && endpointId.length() > 3) { | ||||
|         endpointId = endpointId.substring(3); | ||||
|       } | ||||
|       virtualField.set(request, ElasticsearchEndpointMap.get(endpointId)); | ||||
|       ENDPOINT_DEFINITION.set(request, ElasticsearchEndpointMap.get(endpointId)); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -10,10 +10,12 @@ import static java.util.Collections.singletonList; | |||
| import com.google.auto.service.AutoService; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; | ||||
| import java.util.List; | ||||
| 
 | ||||
| @AutoService(InstrumentationModule.class) | ||||
| public class ElasticsearchRest5InstrumentationModule extends InstrumentationModule { | ||||
| public class ElasticsearchRest5InstrumentationModule extends InstrumentationModule | ||||
|     implements ExperimentalInstrumentationModule { | ||||
|   public ElasticsearchRest5InstrumentationModule() { | ||||
|     super("elasticsearch-rest", "elasticsearch-rest-5.0", "elasticsearch"); | ||||
|   } | ||||
|  | @ -22,4 +24,9 @@ public class ElasticsearchRest5InstrumentationModule extends InstrumentationModu | |||
|   public List<TypeInstrumentation> typeInstrumentations() { | ||||
|     return singletonList(new RestClientInstrumentation()); | ||||
|   } | ||||
| 
 | ||||
|   @Override | ||||
|   public boolean isIndyReady() { | ||||
|     return true; | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -19,7 +19,10 @@ import io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal. | |||
| import io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal.RestResponseListener; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; | ||||
| import javax.annotation.Nullable; | ||||
| import net.bytebuddy.asm.Advice; | ||||
| import net.bytebuddy.asm.Advice.AssignReturned; | ||||
| import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; | ||||
| import net.bytebuddy.description.type.TypeDescription; | ||||
| import net.bytebuddy.matcher.ElementMatcher; | ||||
| import org.elasticsearch.client.ResponseListener; | ||||
|  | @ -45,45 +48,67 @@ public class RestClientInstrumentation implements TypeInstrumentation { | |||
|   @SuppressWarnings("unused") | ||||
|   public static class PerformRequestAsyncAdvice { | ||||
| 
 | ||||
|     @Advice.OnMethodEnter(suppress = Throwable.class) | ||||
|     public static void onEnter( | ||||
|         @Advice.Argument(0) String method, | ||||
|         @Advice.Argument(1) String endpoint, | ||||
|         @Advice.Local("otelRequest") ElasticsearchRestRequest request, | ||||
|         @Advice.Local("otelContext") Context context, | ||||
|         @Advice.Local("otelScope") Scope scope, | ||||
|         @Advice.Argument(value = 5, readOnly = false) ResponseListener responseListener) { | ||||
|     public static class AdviceScope { | ||||
|       private final ElasticsearchRestRequest request; | ||||
|       private final Context parentContext; | ||||
|       private final Context context; | ||||
|       private final Scope scope; | ||||
| 
 | ||||
|       Context parentContext = currentContext(); | ||||
|       request = ElasticsearchRestRequest.create(method, endpoint); | ||||
|       if (!instrumenter().shouldStart(parentContext, request)) { | ||||
|         return; | ||||
|       private AdviceScope( | ||||
|           ElasticsearchRestRequest request, Context parentContext, Context context, Scope scope) { | ||||
|         this.request = request; | ||||
|         this.parentContext = parentContext; | ||||
|         this.context = context; | ||||
|         this.scope = scope; | ||||
|       } | ||||
| 
 | ||||
|       context = instrumenter().start(parentContext, request); | ||||
|       scope = context.makeCurrent(); | ||||
|       @Nullable | ||||
|       public static AdviceScope start(ElasticsearchRestRequest request) { | ||||
|         Context parentContext = currentContext(); | ||||
|         if (!instrumenter().shouldStart(parentContext, request)) { | ||||
|           return null; | ||||
|         } | ||||
|         Context context = instrumenter().start(parentContext, request); | ||||
|         return new AdviceScope(request, parentContext, context, context.makeCurrent()); | ||||
|       } | ||||
| 
 | ||||
|       responseListener = | ||||
|           new RestResponseListener( | ||||
|               responseListener, parentContext, instrumenter(), context, request); | ||||
|       public RestResponseListener wrapListener(ResponseListener listener) { | ||||
|         return new RestResponseListener(listener, parentContext, instrumenter(), context, request); | ||||
|       } | ||||
| 
 | ||||
|       public void end(@Nullable Throwable throwable) { | ||||
|         scope.close(); | ||||
|         if (throwable != null) { | ||||
|           instrumenter().end(context, request, null, throwable); | ||||
|         } | ||||
|         // span ended in RestResponseListener | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     @AssignReturned.ToArguments(@ToArgument(value = 5, index = 1)) | ||||
|     @Advice.OnMethodEnter(suppress = Throwable.class) | ||||
|     public static Object[] onEnter( | ||||
|         @Advice.Argument(0) String method, | ||||
|         @Advice.Argument(1) String endpoint, | ||||
|         @Advice.Argument(5) ResponseListener originalResponseListener) { | ||||
|       ResponseListener responseListener = originalResponseListener; | ||||
| 
 | ||||
|       ElasticsearchRestRequest request = ElasticsearchRestRequest.create(method, endpoint); | ||||
|       AdviceScope adviceScope = AdviceScope.start(request); | ||||
|       if (adviceScope == null) { | ||||
|         return new Object[] {null, responseListener}; | ||||
|       } | ||||
|       responseListener = adviceScope.wrapListener(responseListener); | ||||
|       return new Object[] {adviceScope, responseListener}; | ||||
|     } | ||||
| 
 | ||||
|     @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) | ||||
|     public static void stopSpan( | ||||
|         @Advice.Thrown Throwable throwable, | ||||
|         @Advice.Local("otelRequest") ElasticsearchRestRequest request, | ||||
|         @Advice.Local("otelContext") Context context, | ||||
|         @Advice.Local("otelScope") Scope scope) { | ||||
| 
 | ||||
|       if (scope == null) { | ||||
|         return; | ||||
|         @Advice.Thrown Throwable throwable, @Advice.Enter Object[] enterResult) { | ||||
|       AdviceScope adviceScope = (AdviceScope) enterResult[0]; | ||||
|       if (adviceScope != null) { | ||||
|         adviceScope.end(throwable); | ||||
|       } | ||||
|       scope.close(); | ||||
| 
 | ||||
|       if (throwable != null) { | ||||
|         instrumenter().end(context, request, null, throwable); | ||||
|       } | ||||
|       // span ended in RestResponseListener | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -12,11 +12,13 @@ import static net.bytebuddy.matcher.ElementMatchers.not; | |||
| import com.google.auto.service.AutoService; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; | ||||
| import java.util.List; | ||||
| import net.bytebuddy.matcher.ElementMatcher; | ||||
| 
 | ||||
| @AutoService(InstrumentationModule.class) | ||||
| public class ElasticsearchRest6InstrumentationModule extends InstrumentationModule { | ||||
| public class ElasticsearchRest6InstrumentationModule extends InstrumentationModule | ||||
|     implements ExperimentalInstrumentationModule { | ||||
|   public ElasticsearchRest6InstrumentationModule() { | ||||
|     super("elasticsearch-rest", "elasticsearch-rest-6.4", "elasticsearch"); | ||||
|   } | ||||
|  | @ -31,4 +33,9 @@ public class ElasticsearchRest6InstrumentationModule extends InstrumentationModu | |||
|   public List<TypeInstrumentation> typeInstrumentations() { | ||||
|     return singletonList(new RestClientInstrumentation()); | ||||
|   } | ||||
| 
 | ||||
|   @Override | ||||
|   public boolean isIndyReady() { | ||||
|     return true; | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -18,7 +18,10 @@ import io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal. | |||
| import io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal.RestResponseListener; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; | ||||
| import javax.annotation.Nullable; | ||||
| import net.bytebuddy.asm.Advice; | ||||
| import net.bytebuddy.asm.Advice.AssignReturned; | ||||
| import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; | ||||
| import net.bytebuddy.description.type.TypeDescription; | ||||
| import net.bytebuddy.matcher.ElementMatcher; | ||||
| import org.elasticsearch.client.Request; | ||||
|  | @ -44,44 +47,67 @@ public class RestClientInstrumentation implements TypeInstrumentation { | |||
|   @SuppressWarnings("unused") | ||||
|   public static class PerformRequestAsyncAdvice { | ||||
| 
 | ||||
|     @Advice.OnMethodEnter(suppress = Throwable.class) | ||||
|     public static void onEnter( | ||||
|         @Advice.Argument(0) Request request, | ||||
|         @Advice.Argument(value = 1, readOnly = false) ResponseListener responseListener, | ||||
|         @Advice.Local("otelRequest") ElasticsearchRestRequest otelRequest, | ||||
|         @Advice.Local("otelContext") Context context, | ||||
|         @Advice.Local("otelScope") Scope scope) { | ||||
|     public static class AdviceScope { | ||||
|       private final ElasticsearchRestRequest request; | ||||
|       private final Context parentContext; | ||||
|       private final Context context; | ||||
|       private final Scope scope; | ||||
| 
 | ||||
|       Context parentContext = currentContext(); | ||||
|       otelRequest = ElasticsearchRestRequest.create(request.getMethod(), request.getEndpoint()); | ||||
|       if (!instrumenter().shouldStart(parentContext, otelRequest)) { | ||||
|         return; | ||||
|       private AdviceScope( | ||||
|           ElasticsearchRestRequest request, Context parentContext, Context context, Scope scope) { | ||||
|         this.request = request; | ||||
|         this.parentContext = parentContext; | ||||
|         this.context = context; | ||||
|         this.scope = scope; | ||||
|       } | ||||
| 
 | ||||
|       context = instrumenter().start(parentContext, otelRequest); | ||||
|       scope = context.makeCurrent(); | ||||
|       @Nullable | ||||
|       public static AdviceScope start(ElasticsearchRestRequest request) { | ||||
|         Context parentContext = currentContext(); | ||||
|         if (!instrumenter().shouldStart(parentContext, request)) { | ||||
|           return null; | ||||
|         } | ||||
|         Context context = instrumenter().start(parentContext, request); | ||||
|         return new AdviceScope(request, parentContext, context, context.makeCurrent()); | ||||
|       } | ||||
| 
 | ||||
|       responseListener = | ||||
|           new RestResponseListener( | ||||
|               responseListener, parentContext, instrumenter(), context, otelRequest); | ||||
|       public RestResponseListener wrapListener(ResponseListener listener) { | ||||
|         return new RestResponseListener(listener, parentContext, instrumenter(), context, request); | ||||
|       } | ||||
| 
 | ||||
|       public void end(@Nullable Throwable throwable) { | ||||
|         scope.close(); | ||||
|         if (throwable != null) { | ||||
|           instrumenter().end(context, request, null, throwable); | ||||
|         } | ||||
|         // span ended in RestResponseListener | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     @AssignReturned.ToArguments(@ToArgument(value = 1, index = 1)) | ||||
|     @Advice.OnMethodEnter(suppress = Throwable.class) | ||||
|     public static Object[] onEnter( | ||||
|         @Advice.Argument(0) Request request, | ||||
|         @Advice.Argument(1) ResponseListener originalResponseListener) { | ||||
|       ResponseListener responseListener = originalResponseListener; | ||||
| 
 | ||||
|       ElasticsearchRestRequest otelRequest = | ||||
|           ElasticsearchRestRequest.create(request.getMethod(), request.getEndpoint()); | ||||
|       AdviceScope adviceScope = AdviceScope.start(otelRequest); | ||||
|       if (adviceScope == null) { | ||||
|         return new Object[] {null, responseListener}; | ||||
|       } | ||||
|       responseListener = adviceScope.wrapListener(responseListener); | ||||
|       return new Object[] {adviceScope, responseListener}; | ||||
|     } | ||||
| 
 | ||||
|     @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) | ||||
|     public static void stopSpan( | ||||
|         @Advice.Thrown Throwable throwable, | ||||
|         @Advice.Local("otelRequest") ElasticsearchRestRequest otelRequest, | ||||
|         @Advice.Local("otelContext") Context context, | ||||
|         @Advice.Local("otelScope") Scope scope) { | ||||
| 
 | ||||
|       if (scope == null) { | ||||
|         return; | ||||
|         @Advice.Thrown @Nullable Throwable throwable, @Advice.Enter Object[] enterResult) { | ||||
|       AdviceScope adviceScope = (AdviceScope) enterResult[0]; | ||||
|       if (adviceScope != null) { | ||||
|         adviceScope.end(throwable); | ||||
|       } | ||||
|       scope.close(); | ||||
| 
 | ||||
|       if (throwable != null) { | ||||
|         instrumenter().end(context, otelRequest, null, throwable); | ||||
|       } | ||||
|       // span ended in RestResponseListener | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -43,4 +43,9 @@ public class ElasticsearchRest7InstrumentationModule extends InstrumentationModu | |||
|   public List<TypeInstrumentation> typeInstrumentations() { | ||||
|     return singletonList(new RestClientInstrumentation()); | ||||
|   } | ||||
| 
 | ||||
|   @Override | ||||
|   public boolean isIndyReady() { | ||||
|     return true; | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -6,8 +6,11 @@ | |||
| package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.v7_0; | ||||
| 
 | ||||
| import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; | ||||
| import io.opentelemetry.instrumentation.api.util.VirtualField; | ||||
| import io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal.ElasticsearchEndpointDefinition; | ||||
| import io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal.ElasticsearchRestRequest; | ||||
| import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.ElasticsearchRestJavaagentInstrumenterFactory; | ||||
| import org.elasticsearch.client.Request; | ||||
| import org.elasticsearch.client.Response; | ||||
| 
 | ||||
| public final class ElasticsearchRest7Singletons { | ||||
|  | @ -20,5 +23,8 @@ public final class ElasticsearchRest7Singletons { | |||
|     return INSTRUMENTER; | ||||
|   } | ||||
| 
 | ||||
|   public static final VirtualField<Request, ElasticsearchEndpointDefinition> ENDPOINT_DEFINITION = | ||||
|       VirtualField.find(Request.class, ElasticsearchEndpointDefinition.class); | ||||
| 
 | ||||
|   private ElasticsearchRest7Singletons() {} | ||||
| } | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ | |||
| package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.v7_0; | ||||
| 
 | ||||
| import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext; | ||||
| import static io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.v7_0.ElasticsearchRest7Singletons.ENDPOINT_DEFINITION; | ||||
| import static io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.v7_0.ElasticsearchRest7Singletons.instrumenter; | ||||
| import static net.bytebuddy.matcher.ElementMatchers.isMethod; | ||||
| import static net.bytebuddy.matcher.ElementMatchers.named; | ||||
|  | @ -14,13 +15,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; | |||
| 
 | ||||
| import io.opentelemetry.context.Context; | ||||
| import io.opentelemetry.context.Scope; | ||||
| import io.opentelemetry.instrumentation.api.util.VirtualField; | ||||
| import io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal.ElasticsearchEndpointDefinition; | ||||
| import io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal.ElasticsearchRestRequest; | ||||
| import io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal.RestResponseListener; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; | ||||
| import javax.annotation.Nullable; | ||||
| import net.bytebuddy.asm.Advice; | ||||
| import net.bytebuddy.asm.Advice.AssignReturned; | ||||
| import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; | ||||
| import net.bytebuddy.description.type.TypeDescription; | ||||
| import net.bytebuddy.matcher.ElementMatcher; | ||||
| import org.elasticsearch.client.Request; | ||||
|  | @ -50,101 +52,107 @@ public class RestClientInstrumentation implements TypeInstrumentation { | |||
|         this.getClass().getName() + "$PerformRequestAsyncAdvice"); | ||||
|   } | ||||
| 
 | ||||
|   public static class AdviceScope { | ||||
|     private final ElasticsearchRestRequest request; | ||||
|     private final Context context; | ||||
|     private final Context parentContext; | ||||
|     private final Scope scope; | ||||
| 
 | ||||
|     private AdviceScope( | ||||
|         ElasticsearchRestRequest request, Context parentContext, Context context, Scope scope) { | ||||
|       this.request = request; | ||||
|       this.parentContext = parentContext; | ||||
|       this.context = context; | ||||
|       this.scope = scope; | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     public static AdviceScope start(ElasticsearchRestRequest request) { | ||||
|       Context parentContext = currentContext(); | ||||
|       if (!instrumenter().shouldStart(parentContext, request)) { | ||||
|         return null; | ||||
|       } | ||||
|       Context context = instrumenter().start(parentContext, request); | ||||
|       return new AdviceScope(request, parentContext, context, context.makeCurrent()); | ||||
|     } | ||||
| 
 | ||||
|     public ResponseListener wrapListener(ResponseListener responseListener) { | ||||
|       return new RestResponseListener( | ||||
|           responseListener, parentContext, instrumenter(), context, request); | ||||
|     } | ||||
| 
 | ||||
|     public void endWithListener(@Nullable Throwable throwable) { | ||||
|       scope.close(); | ||||
|       if (throwable != null) { | ||||
|         instrumenter().end(context, request, null, throwable); | ||||
|       } | ||||
|       // span ended in RestResponseListener | ||||
|     } | ||||
| 
 | ||||
|     public void endWithResponse(@Nullable Throwable throwable, @Nullable Response response) { | ||||
|       scope.close(); | ||||
|       instrumenter().end(context, request, response, throwable); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @SuppressWarnings("unused") | ||||
|   public static class PerformRequestAdvice { | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Advice.OnMethodEnter(suppress = Throwable.class) | ||||
|     public static void onEnter( | ||||
|         @Advice.Argument(0) Request request, | ||||
|         @Advice.Local("otelRequest") ElasticsearchRestRequest otelRequest, | ||||
|         @Advice.Local("otelContext") Context context, | ||||
|         @Advice.Local("otelScope") Scope scope) { | ||||
| 
 | ||||
|       Context parentContext = currentContext(); | ||||
|       VirtualField<Request, ElasticsearchEndpointDefinition> virtualField = | ||||
|           VirtualField.find(Request.class, ElasticsearchEndpointDefinition.class); | ||||
|       otelRequest = | ||||
|     public static AdviceScope onEnter(@Advice.Argument(0) Request request) { | ||||
|       ElasticsearchRestRequest otelRequest = | ||||
|           ElasticsearchRestRequest.create( | ||||
|               request.getMethod(), | ||||
|               request.getEndpoint(), | ||||
|               // set by elasticsearch-api-client instrumentation | ||||
|               virtualField.get(request), | ||||
|               ENDPOINT_DEFINITION.get(request), | ||||
|               request.getEntity()); | ||||
|       if (!instrumenter().shouldStart(parentContext, otelRequest)) { | ||||
|         return; | ||||
|       } | ||||
| 
 | ||||
|       context = instrumenter().start(parentContext, otelRequest); | ||||
|       scope = context.makeCurrent(); | ||||
|       return AdviceScope.start(otelRequest); | ||||
|     } | ||||
| 
 | ||||
|     @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) | ||||
|     public static void stopSpan( | ||||
|         @Advice.Return Response response, | ||||
|         @Advice.Thrown Throwable throwable, | ||||
|         @Advice.Local("otelRequest") ElasticsearchRestRequest otelRequest, | ||||
|         @Advice.Local("otelContext") Context context, | ||||
|         @Advice.Local("otelScope") Scope scope) { | ||||
| 
 | ||||
|       if (scope == null) { | ||||
|         return; | ||||
|         @Advice.Return @Nullable Response response, | ||||
|         @Advice.Thrown @Nullable Throwable throwable, | ||||
|         @Advice.Enter @Nullable AdviceScope adviceScope) { | ||||
|       if (adviceScope != null) { | ||||
|         adviceScope.endWithResponse(throwable, response); | ||||
|       } | ||||
|       scope.close(); | ||||
| 
 | ||||
|       instrumenter().end(context, otelRequest, response, throwable); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @SuppressWarnings("unused") | ||||
|   public static class PerformRequestAsyncAdvice { | ||||
| 
 | ||||
|     @AssignReturned.ToArguments(@ToArgument(value = 1, index = 1)) | ||||
|     @Advice.OnMethodEnter(suppress = Throwable.class) | ||||
|     public static void onEnter( | ||||
|     public static Object[] onEnter( | ||||
|         @Advice.Argument(0) Request request, | ||||
|         @Advice.Argument(value = 1, readOnly = false) ResponseListener responseListener, | ||||
|         @Advice.Local("otelRequest") ElasticsearchRestRequest otelRequest, | ||||
|         @Advice.Local("otelContext") Context context, | ||||
|         @Advice.Local("otelScope") Scope scope) { | ||||
| 
 | ||||
|       Context parentContext = currentContext(); | ||||
|       VirtualField<Request, ElasticsearchEndpointDefinition> virtualField = | ||||
|           VirtualField.find(Request.class, ElasticsearchEndpointDefinition.class); | ||||
| 
 | ||||
|       otelRequest = | ||||
|         @Advice.Argument(1) ResponseListener originalResponseListener) { | ||||
|       ResponseListener responseListener = originalResponseListener; | ||||
|       ElasticsearchRestRequest otelRequest = | ||||
|           ElasticsearchRestRequest.create( | ||||
|               request.getMethod(), | ||||
|               request.getEndpoint(), | ||||
|               // set by elasticsearch-api-client instrumentation | ||||
|               virtualField.get(request), | ||||
|               ENDPOINT_DEFINITION.get(request), | ||||
|               request.getEntity()); | ||||
|       if (!instrumenter().shouldStart(parentContext, otelRequest)) { | ||||
|         return; | ||||
|       AdviceScope adviceScope = AdviceScope.start(otelRequest); | ||||
|       if (adviceScope == null) { | ||||
|         return new Object[] {null, responseListener}; | ||||
|       } | ||||
| 
 | ||||
|       context = instrumenter().start(parentContext, otelRequest); | ||||
|       scope = context.makeCurrent(); | ||||
| 
 | ||||
|       responseListener = | ||||
|           new RestResponseListener( | ||||
|               responseListener, parentContext, instrumenter(), context, otelRequest); | ||||
|       responseListener = adviceScope.wrapListener(responseListener); | ||||
|       return new Object[] {adviceScope, responseListener}; | ||||
|     } | ||||
| 
 | ||||
|     @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) | ||||
|     public static void stopSpan( | ||||
|         @Advice.Thrown Throwable throwable, | ||||
|         @Advice.Local("otelRequest") ElasticsearchRestRequest otelRequest, | ||||
|         @Advice.Local("otelContext") Context context, | ||||
|         @Advice.Local("otelScope") Scope scope) { | ||||
| 
 | ||||
|       if (scope == null) { | ||||
|         return; | ||||
|         @Advice.Thrown @Nullable Throwable throwable, @Advice.Enter Object[] enterResult) { | ||||
|       AdviceScope adviceScope = (AdviceScope) enterResult[0]; | ||||
|       if (adviceScope != null) { | ||||
|         adviceScope.endWithListener(throwable); | ||||
|       } | ||||
|       scope.close(); | ||||
| 
 | ||||
|       if (throwable != null) { | ||||
|         instrumenter().end(context, otelRequest, null, throwable); | ||||
|       } | ||||
|       // span ended in RestResponseListener | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -17,7 +17,10 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | |||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; | ||||
| import io.opentelemetry.javaagent.instrumentation.elasticsearch.transport.ElasticTransportRequest; | ||||
| import io.opentelemetry.javaagent.instrumentation.elasticsearch.transport.TransportActionListener; | ||||
| import javax.annotation.Nullable; | ||||
| import net.bytebuddy.asm.Advice; | ||||
| import net.bytebuddy.asm.Advice.AssignReturned; | ||||
| import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; | ||||
| import net.bytebuddy.description.type.TypeDescription; | ||||
| import net.bytebuddy.matcher.ElementMatcher; | ||||
| import org.elasticsearch.action.Action; | ||||
|  | @ -47,44 +50,68 @@ public class AbstractClientInstrumentation implements TypeInstrumentation { | |||
|   @SuppressWarnings("unused") | ||||
|   public static class ExecuteAdvice { | ||||
| 
 | ||||
|     @Advice.OnMethodEnter(suppress = Throwable.class) | ||||
|     public static void onEnter( | ||||
|         @Advice.Argument(0) Action<?, ?, ?> action, | ||||
|         @Advice.Argument(1) ActionRequest<?> actionRequest, | ||||
|         @Advice.Local("otelContext") Context context, | ||||
|         @Advice.Local("otelScope") Scope scope, | ||||
|         @Advice.Local("otelRequest") ElasticTransportRequest transportRequest, | ||||
|         @Advice.Argument(value = 2, readOnly = false) | ||||
|             ActionListener<ActionResponse> actionListener) { | ||||
|     public static class AdviceScope { | ||||
|       private final ElasticTransportRequest request; | ||||
|       private final Context parentContext; | ||||
|       private final Context context; | ||||
|       private final Scope scope; | ||||
| 
 | ||||
|       transportRequest = ElasticTransportRequest.create(action, actionRequest); | ||||
|       Context parentContext = currentContext(); | ||||
|       if (!instrumenter().shouldStart(parentContext, transportRequest)) { | ||||
|         return; | ||||
|       private AdviceScope( | ||||
|           ElasticTransportRequest request, Context parentContext, Context context, Scope scope) { | ||||
|         this.request = request; | ||||
|         this.parentContext = parentContext; | ||||
|         this.context = context; | ||||
|         this.scope = scope; | ||||
|       } | ||||
| 
 | ||||
|       context = instrumenter().start(parentContext, transportRequest); | ||||
|       scope = context.makeCurrent(); | ||||
|       @Nullable | ||||
|       public static AdviceScope start(ElasticTransportRequest request) { | ||||
|         Context parentContext = currentContext(); | ||||
|         if (!instrumenter().shouldStart(parentContext, request)) { | ||||
|           return null; | ||||
|         } | ||||
|         Context context = instrumenter().start(parentContext, request); | ||||
|         return new AdviceScope(request, parentContext, context, context.makeCurrent()); | ||||
|       } | ||||
| 
 | ||||
|       actionListener = | ||||
|           new TransportActionListener<>( | ||||
|               instrumenter(), transportRequest, actionListener, context, parentContext); | ||||
|       public ActionListener<ActionResponse> wrapListener( | ||||
|           ActionListener<ActionResponse> actionListener) { | ||||
|         return new TransportActionListener<>( | ||||
|             instrumenter(), request, actionListener, context, parentContext); | ||||
|       } | ||||
| 
 | ||||
|       public void end(@Nullable Throwable throwable) { | ||||
|         scope.close(); | ||||
|         if (throwable != null) { | ||||
|           instrumenter().end(context, request, null, throwable); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     @AssignReturned.ToArguments(@ToArgument(value = 2, index = 1)) | ||||
|     @Advice.OnMethodEnter(suppress = Throwable.class) | ||||
|     public static Object[] onEnter( | ||||
|         @Advice.Argument(0) Action<?, ?, ?> action, | ||||
|         @Advice.Argument(1) ActionRequest<?> actionRequest, | ||||
|         @Advice.Argument(2) ActionListener<ActionResponse> originalActionListener) { | ||||
|       ActionListener<ActionResponse> actionListener = originalActionListener; | ||||
| 
 | ||||
|       ElasticTransportRequest request = ElasticTransportRequest.create(action, actionRequest); | ||||
|       AdviceScope adviceScope = AdviceScope.start(request); | ||||
|       if (adviceScope == null) { | ||||
|         return new Object[] {null, actionListener}; | ||||
|       } | ||||
| 
 | ||||
|       actionListener = adviceScope.wrapListener(actionListener); | ||||
|       return new Object[] {adviceScope, actionListener}; | ||||
|     } | ||||
| 
 | ||||
|     @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) | ||||
|     public static void stopSpan( | ||||
|         @Advice.Thrown Throwable throwable, | ||||
|         @Advice.Local("otelContext") Context context, | ||||
|         @Advice.Local("otelScope") Scope scope, | ||||
|         @Advice.Local("otelRequest") ElasticTransportRequest transportRequest) { | ||||
|       if (scope == null) { | ||||
|         return; | ||||
|       } | ||||
| 
 | ||||
|       scope.close(); | ||||
| 
 | ||||
|       if (throwable != null) { | ||||
|         instrumenter().end(context, transportRequest, null, throwable); | ||||
|         @Advice.Thrown @Nullable Throwable throwable, @Advice.Enter Object[] enterResult) { | ||||
|       AdviceScope adviceScope = (AdviceScope) enterResult[0]; | ||||
|       if (adviceScope != null) { | ||||
|         adviceScope.end(throwable); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  |  | |||
|  | @ -10,10 +10,12 @@ import static java.util.Collections.singletonList; | |||
| import com.google.auto.service.AutoService; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; | ||||
| import java.util.List; | ||||
| 
 | ||||
| @AutoService(InstrumentationModule.class) | ||||
| public class Elasticsearch5TransportClientInstrumentationModule extends InstrumentationModule { | ||||
| public class Elasticsearch5TransportClientInstrumentationModule extends InstrumentationModule | ||||
|     implements ExperimentalInstrumentationModule { | ||||
|   public Elasticsearch5TransportClientInstrumentationModule() { | ||||
|     super("elasticsearch-transport", "elasticsearch-transport-5.0", "elasticsearch"); | ||||
|   } | ||||
|  | @ -22,4 +24,9 @@ public class Elasticsearch5TransportClientInstrumentationModule extends Instrume | |||
|   public List<TypeInstrumentation> typeInstrumentations() { | ||||
|     return singletonList(new AbstractClientInstrumentation()); | ||||
|   } | ||||
| 
 | ||||
|   @Override | ||||
|   public boolean isIndyReady() { | ||||
|     return true; | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -17,7 +17,10 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | |||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; | ||||
| import io.opentelemetry.javaagent.instrumentation.elasticsearch.transport.ElasticTransportRequest; | ||||
| import io.opentelemetry.javaagent.instrumentation.elasticsearch.transport.TransportActionListener; | ||||
| import javax.annotation.Nullable; | ||||
| import net.bytebuddy.asm.Advice; | ||||
| import net.bytebuddy.asm.Advice.AssignReturned; | ||||
| import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; | ||||
| import net.bytebuddy.description.type.TypeDescription; | ||||
| import net.bytebuddy.matcher.ElementMatcher; | ||||
| import org.elasticsearch.action.Action; | ||||
|  | @ -47,44 +50,68 @@ public class AbstractClientInstrumentation implements TypeInstrumentation { | |||
|   @SuppressWarnings("unused") | ||||
|   public static class ExecuteAdvice { | ||||
| 
 | ||||
|     @Advice.OnMethodEnter(suppress = Throwable.class) | ||||
|     public static void onEnter( | ||||
|         @Advice.Argument(0) Action<?, ?, ?> action, | ||||
|         @Advice.Argument(1) ActionRequest actionRequest, | ||||
|         @Advice.Local("otelContext") Context context, | ||||
|         @Advice.Local("otelScope") Scope scope, | ||||
|         @Advice.Local("otelRequest") ElasticTransportRequest transportRequest, | ||||
|         @Advice.Argument(value = 2, readOnly = false) | ||||
|             ActionListener<ActionResponse> actionListener) { | ||||
|     public static class AdviceScope { | ||||
|       private final ElasticTransportRequest request; | ||||
|       private final Context parentContext; | ||||
|       private final Context context; | ||||
|       private final Scope scope; | ||||
| 
 | ||||
|       transportRequest = ElasticTransportRequest.create(action, actionRequest); | ||||
|       Context parentContext = currentContext(); | ||||
|       if (!instrumenter().shouldStart(parentContext, transportRequest)) { | ||||
|         return; | ||||
|       private AdviceScope( | ||||
|           ElasticTransportRequest request, Context parentContext, Context context, Scope scope) { | ||||
|         this.request = request; | ||||
|         this.parentContext = parentContext; | ||||
|         this.context = context; | ||||
|         this.scope = scope; | ||||
|       } | ||||
| 
 | ||||
|       context = instrumenter().start(parentContext, transportRequest); | ||||
|       scope = context.makeCurrent(); | ||||
|       @Nullable | ||||
|       public static AdviceScope start(ElasticTransportRequest request) { | ||||
|         Context parentContext = currentContext(); | ||||
|         if (!instrumenter().shouldStart(parentContext, request)) { | ||||
|           return null; | ||||
|         } | ||||
|         Context context = instrumenter().start(parentContext, request); | ||||
|         return new AdviceScope(request, parentContext, context, context.makeCurrent()); | ||||
|       } | ||||
| 
 | ||||
|       actionListener = | ||||
|           new TransportActionListener<>( | ||||
|               instrumenter(), transportRequest, actionListener, context, parentContext); | ||||
|       public ActionListener<ActionResponse> wrapListener( | ||||
|           ActionListener<ActionResponse> actionListener) { | ||||
|         return new TransportActionListener<>( | ||||
|             instrumenter(), request, actionListener, context, parentContext); | ||||
|       } | ||||
| 
 | ||||
|       public void end(@Nullable Throwable throwable) { | ||||
|         scope.close(); | ||||
|         if (throwable != null) { | ||||
|           instrumenter().end(context, request, null, throwable); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     @AssignReturned.ToArguments(@ToArgument(value = 2, index = 1)) | ||||
|     @Advice.OnMethodEnter(suppress = Throwable.class) | ||||
|     public static Object[] onEnter( | ||||
|         @Advice.Argument(0) Action<?, ?, ?> action, | ||||
|         @Advice.Argument(1) ActionRequest actionRequest, | ||||
|         @Advice.Argument(2) ActionListener<ActionResponse> originalActionListener) { | ||||
|       ActionListener<ActionResponse> actionListener = originalActionListener; | ||||
| 
 | ||||
|       ElasticTransportRequest request = ElasticTransportRequest.create(action, actionRequest); | ||||
|       AdviceScope adviceScope = AdviceScope.start(request); | ||||
|       if (adviceScope == null) { | ||||
|         return new Object[] {null, actionListener}; | ||||
|       } | ||||
| 
 | ||||
|       actionListener = adviceScope.wrapListener(actionListener); | ||||
|       return new Object[] {adviceScope, actionListener}; | ||||
|     } | ||||
| 
 | ||||
|     @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) | ||||
|     public static void stopSpan( | ||||
|         @Advice.Thrown Throwable throwable, | ||||
|         @Advice.Local("otelContext") Context context, | ||||
|         @Advice.Local("otelScope") Scope scope, | ||||
|         @Advice.Local("otelRequest") ElasticTransportRequest transportRequest) { | ||||
|       if (scope == null) { | ||||
|         return; | ||||
|       } | ||||
| 
 | ||||
|       scope.close(); | ||||
| 
 | ||||
|       if (throwable != null) { | ||||
|         instrumenter().end(context, transportRequest, null, throwable); | ||||
|         @Advice.Thrown @Nullable Throwable throwable, @Advice.Enter Object[] enterResult) { | ||||
|       AdviceScope adviceScope = (AdviceScope) enterResult[0]; | ||||
|       if (adviceScope != null) { | ||||
|         adviceScope.end(throwable); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  |  | |||
|  | @ -10,11 +10,13 @@ import static java.util.Collections.singletonList; | |||
| import com.google.auto.service.AutoService; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; | ||||
| import java.util.List; | ||||
| 
 | ||||
| /** Beginning in version 5.3.0, DocumentRequest was renamed to DocWriteRequest. */ | ||||
| @AutoService(InstrumentationModule.class) | ||||
| public class Elasticsearch53TransportClientInstrumentationModule extends InstrumentationModule { | ||||
| public class Elasticsearch53TransportClientInstrumentationModule extends InstrumentationModule | ||||
|     implements ExperimentalInstrumentationModule { | ||||
|   public Elasticsearch53TransportClientInstrumentationModule() { | ||||
|     super("elasticsearch-transport", "elasticsearch-transport-5.3", "elasticsearch"); | ||||
|   } | ||||
|  | @ -23,4 +25,9 @@ public class Elasticsearch53TransportClientInstrumentationModule extends Instrum | |||
|   public List<TypeInstrumentation> typeInstrumentations() { | ||||
|     return singletonList(new AbstractClientInstrumentation()); | ||||
|   } | ||||
| 
 | ||||
|   @Override | ||||
|   public boolean isIndyReady() { | ||||
|     return true; | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -18,7 +18,10 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | |||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; | ||||
| import io.opentelemetry.javaagent.instrumentation.elasticsearch.transport.ElasticTransportRequest; | ||||
| import io.opentelemetry.javaagent.instrumentation.elasticsearch.transport.TransportActionListener; | ||||
| import javax.annotation.Nullable; | ||||
| import net.bytebuddy.asm.Advice; | ||||
| import net.bytebuddy.asm.Advice.AssignReturned; | ||||
| import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; | ||||
| import net.bytebuddy.description.type.TypeDescription; | ||||
| import net.bytebuddy.matcher.ElementMatcher; | ||||
| import org.elasticsearch.action.ActionListener; | ||||
|  | @ -51,44 +54,68 @@ public class AbstractClientInstrumentation implements TypeInstrumentation { | |||
|   @SuppressWarnings("unused") | ||||
|   public static class ExecuteAdvice { | ||||
| 
 | ||||
|     @Advice.OnMethodEnter(suppress = Throwable.class) | ||||
|     public static void onEnter( | ||||
|         @Advice.Argument(0) Object action, | ||||
|         @Advice.Argument(1) ActionRequest actionRequest, | ||||
|         @Advice.Local("otelContext") Context context, | ||||
|         @Advice.Local("otelScope") Scope scope, | ||||
|         @Advice.Local("otelRequest") ElasticTransportRequest transportRequest, | ||||
|         @Advice.Argument(value = 2, readOnly = false) | ||||
|             ActionListener<ActionResponse> actionListener) { | ||||
|     public static class AdviceScope { | ||||
|       private final ElasticTransportRequest request; | ||||
|       private final Context parentContext; | ||||
|       private final Context context; | ||||
|       private final Scope scope; | ||||
| 
 | ||||
|       transportRequest = ElasticTransportRequest.create(action, actionRequest); | ||||
|       Context parentContext = currentContext(); | ||||
|       if (!instrumenter().shouldStart(parentContext, transportRequest)) { | ||||
|         return; | ||||
|       private AdviceScope( | ||||
|           ElasticTransportRequest request, Context parentContext, Context context, Scope scope) { | ||||
|         this.request = request; | ||||
|         this.parentContext = parentContext; | ||||
|         this.context = context; | ||||
|         this.scope = scope; | ||||
|       } | ||||
| 
 | ||||
|       context = instrumenter().start(parentContext, transportRequest); | ||||
|       scope = context.makeCurrent(); | ||||
|       @Nullable | ||||
|       public static AdviceScope start(ElasticTransportRequest request) { | ||||
|         Context parentContext = currentContext(); | ||||
|         if (!instrumenter().shouldStart(parentContext, request)) { | ||||
|           return null; | ||||
|         } | ||||
|         Context context = instrumenter().start(parentContext, request); | ||||
|         return new AdviceScope(request, parentContext, context, context.makeCurrent()); | ||||
|       } | ||||
| 
 | ||||
|       actionListener = | ||||
|           new TransportActionListener<>( | ||||
|               instrumenter(), transportRequest, actionListener, context, parentContext); | ||||
|       public ActionListener<ActionResponse> wrapListener( | ||||
|           ActionListener<ActionResponse> actionListener) { | ||||
|         return new TransportActionListener<>( | ||||
|             instrumenter(), request, actionListener, context, parentContext); | ||||
|       } | ||||
| 
 | ||||
|       public void end(@Nullable Throwable throwable) { | ||||
|         scope.close(); | ||||
|         if (throwable != null) { | ||||
|           instrumenter().end(context, request, null, throwable); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     @AssignReturned.ToArguments(@ToArgument(value = 2, index = 1)) | ||||
|     @Advice.OnMethodEnter(suppress = Throwable.class) | ||||
|     public static Object[] onEnter( | ||||
|         @Advice.Argument(0) Object action, | ||||
|         @Advice.Argument(1) ActionRequest actionRequest, | ||||
|         @Advice.Argument(2) ActionListener<ActionResponse> originalActionListener) { | ||||
|       ActionListener<ActionResponse> actionListener = originalActionListener; | ||||
| 
 | ||||
|       ElasticTransportRequest request = ElasticTransportRequest.create(action, actionRequest); | ||||
|       AdviceScope adviceScope = AdviceScope.start(request); | ||||
|       if (adviceScope == null) { | ||||
|         return new Object[] {null, actionListener}; | ||||
|       } | ||||
| 
 | ||||
|       actionListener = adviceScope.wrapListener(actionListener); | ||||
|       return new Object[] {adviceScope, actionListener}; | ||||
|     } | ||||
| 
 | ||||
|     @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) | ||||
|     public static void stopSpan( | ||||
|         @Advice.Thrown Throwable throwable, | ||||
|         @Advice.Local("otelContext") Context context, | ||||
|         @Advice.Local("otelScope") Scope scope, | ||||
|         @Advice.Local("otelRequest") ElasticTransportRequest transportRequest) { | ||||
|       if (scope == null) { | ||||
|         return; | ||||
|       } | ||||
| 
 | ||||
|       scope.close(); | ||||
| 
 | ||||
|       if (throwable != null) { | ||||
|         instrumenter().end(context, transportRequest, null, throwable); | ||||
|         @Advice.Thrown @Nullable Throwable throwable, @Advice.Enter Object[] enterResult) { | ||||
|       AdviceScope adviceScope = (AdviceScope) enterResult[0]; | ||||
|       if (adviceScope != null) { | ||||
|         adviceScope.end(throwable); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ import static java.util.Collections.singletonList; | |||
| import com.google.auto.service.AutoService; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | ||||
| import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; | ||||
| import java.util.List; | ||||
| 
 | ||||
| /** | ||||
|  | @ -17,7 +18,8 @@ import java.util.List; | |||
|  * an abstract class, so the bytecode isn't directly compatible. | ||||
|  */ | ||||
| @AutoService(InstrumentationModule.class) | ||||
| public class Elasticsearch6TransportClientInstrumentationModule extends InstrumentationModule { | ||||
| public class Elasticsearch6TransportClientInstrumentationModule extends InstrumentationModule | ||||
|     implements ExperimentalInstrumentationModule { | ||||
|   public Elasticsearch6TransportClientInstrumentationModule() { | ||||
|     super("elasticsearch-transport", "elasticsearch-transport-6.0", "elasticsearch"); | ||||
|   } | ||||
|  | @ -26,4 +28,9 @@ public class Elasticsearch6TransportClientInstrumentationModule extends Instrume | |||
|   public List<TypeInstrumentation> typeInstrumentations() { | ||||
|     return singletonList(new AbstractClientInstrumentation()); | ||||
|   } | ||||
| 
 | ||||
|   @Override | ||||
|   public boolean isIndyReady() { | ||||
|     return true; | ||||
|   } | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue