Skip to content

Commit 2088d86

Browse files
committed
elasticsearch-rest-7.0
1 parent e850b65 commit 2088d86

File tree

3 files changed

+59
-49
lines changed

3 files changed

+59
-49
lines changed

instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/ElasticsearchRest7InstrumentationModule.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,9 @@ public String getModuleGroup() {
4343
public List<TypeInstrumentation> typeInstrumentations() {
4444
return singletonList(new RestClientInstrumentation());
4545
}
46+
47+
@Override
48+
public boolean isIndyReady() {
49+
return true;
50+
}
4651
}

instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/ElasticsearchRest7Singletons.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66
package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.v7_0;
77

88
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
9+
import io.opentelemetry.instrumentation.api.util.VirtualField;
10+
import io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal.ElasticsearchEndpointDefinition;
911
import io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal.ElasticsearchRestRequest;
1012
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.ElasticsearchRestJavaagentInstrumenterFactory;
13+
import org.elasticsearch.client.Request;
1114
import org.elasticsearch.client.Response;
1215

1316
public final class ElasticsearchRest7Singletons {
@@ -20,5 +23,8 @@ public static Instrumenter<ElasticsearchRestRequest, Response> instrumenter() {
2023
return INSTRUMENTER;
2124
}
2225

26+
public static final VirtualField<Request, ElasticsearchEndpointDefinition> ENDPOINT_DEFINITION =
27+
VirtualField.find(Request.class, ElasticsearchEndpointDefinition.class);
28+
2329
private ElasticsearchRest7Singletons() {}
2430
}

instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/RestClientInstrumentation.java

Lines changed: 48 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.v7_0;
77

88
import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext;
9+
import static io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.v7_0.ElasticsearchRest7Singletons.ENDPOINT_DEFINITION;
910
import static io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.v7_0.ElasticsearchRest7Singletons.instrumenter;
1011
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
1112
import static net.bytebuddy.matcher.ElementMatchers.named;
@@ -14,13 +15,14 @@
1415

1516
import io.opentelemetry.context.Context;
1617
import io.opentelemetry.context.Scope;
17-
import io.opentelemetry.instrumentation.api.util.VirtualField;
18-
import io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal.ElasticsearchEndpointDefinition;
1918
import io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal.ElasticsearchRestRequest;
2019
import io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal.RestResponseListener;
2120
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
2221
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
22+
import javax.annotation.Nullable;
2323
import net.bytebuddy.asm.Advice;
24+
import net.bytebuddy.asm.Advice.AssignReturned;
25+
import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument;
2426
import net.bytebuddy.description.type.TypeDescription;
2527
import net.bytebuddy.matcher.ElementMatcher;
2628
import org.elasticsearch.client.Request;
@@ -50,101 +52,98 @@ public void transform(TypeTransformer transformer) {
5052
this.getClass().getName() + "$PerformRequestAsyncAdvice");
5153
}
5254

55+
public static class AdviceScope {
56+
private final ElasticsearchRestRequest request;
57+
private final Context context;
58+
private final Scope scope;
59+
60+
public AdviceScope(ElasticsearchRestRequest request, Context context, Scope scope) {
61+
this.request = request;
62+
this.context = context;
63+
this.scope = scope;
64+
}
65+
66+
public void end(@Nullable Throwable throwable) {
67+
scope.close();
68+
if (throwable != null) {
69+
instrumenter().end(context, request, null, throwable);
70+
}
71+
// span ended in RestResponseListener
72+
}
73+
}
74+
5375
@SuppressWarnings("unused")
5476
public static class PerformRequestAdvice {
5577

78+
@Nullable
5679
@Advice.OnMethodEnter(suppress = Throwable.class)
57-
public static void onEnter(
58-
@Advice.Argument(0) Request request,
59-
@Advice.Local("otelRequest") ElasticsearchRestRequest otelRequest,
60-
@Advice.Local("otelContext") Context context,
61-
@Advice.Local("otelScope") Scope scope) {
80+
public static AdviceScope onEnter(@Advice.Argument(0) Request request) {
6281

6382
Context parentContext = currentContext();
64-
VirtualField<Request, ElasticsearchEndpointDefinition> virtualField =
65-
VirtualField.find(Request.class, ElasticsearchEndpointDefinition.class);
66-
otelRequest =
83+
ElasticsearchRestRequest otelRequest =
6784
ElasticsearchRestRequest.create(
6885
request.getMethod(),
6986
request.getEndpoint(),
7087
// set by elasticsearch-api-client instrumentation
71-
virtualField.get(request),
88+
ENDPOINT_DEFINITION.get(request),
7289
request.getEntity());
7390
if (!instrumenter().shouldStart(parentContext, otelRequest)) {
74-
return;
91+
return null;
7592
}
7693

77-
context = instrumenter().start(parentContext, otelRequest);
78-
scope = context.makeCurrent();
94+
Context context = instrumenter().start(parentContext, otelRequest);
95+
return new AdviceScope(otelRequest, context, context.makeCurrent());
7996
}
8097

8198
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
8299
public static void stopSpan(
83100
@Advice.Return Response response,
84101
@Advice.Thrown Throwable throwable,
85-
@Advice.Local("otelRequest") ElasticsearchRestRequest otelRequest,
86-
@Advice.Local("otelContext") Context context,
87-
@Advice.Local("otelScope") Scope scope) {
102+
@Advice.Enter @Nullable AdviceScope adviceScope) {
88103

89-
if (scope == null) {
90-
return;
104+
if (adviceScope != null) {
105+
adviceScope.end(throwable);
91106
}
92-
scope.close();
93-
94-
instrumenter().end(context, otelRequest, response, throwable);
95107
}
96108
}
97109

98110
@SuppressWarnings("unused")
99111
public static class PerformRequestAsyncAdvice {
100112

113+
@AssignReturned.ToArguments(@ToArgument(value = 1, index = 1))
101114
@Advice.OnMethodEnter(suppress = Throwable.class)
102-
public static void onEnter(
115+
public static Object[] onEnter(
103116
@Advice.Argument(0) Request request,
104-
@Advice.Argument(value = 1, readOnly = false) ResponseListener responseListener,
105-
@Advice.Local("otelRequest") ElasticsearchRestRequest otelRequest,
106-
@Advice.Local("otelContext") Context context,
107-
@Advice.Local("otelScope") Scope scope) {
117+
@Advice.Argument(1) ResponseListener originalResponseListener) {
108118

119+
ResponseListener responseListener = originalResponseListener;
109120
Context parentContext = currentContext();
110-
VirtualField<Request, ElasticsearchEndpointDefinition> virtualField =
111-
VirtualField.find(Request.class, ElasticsearchEndpointDefinition.class);
112-
113-
otelRequest =
121+
ElasticsearchRestRequest otelRequest =
114122
ElasticsearchRestRequest.create(
115123
request.getMethod(),
116124
request.getEndpoint(),
117125
// set by elasticsearch-api-client instrumentation
118-
virtualField.get(request),
126+
ENDPOINT_DEFINITION.get(request),
119127
request.getEntity());
120128
if (!instrumenter().shouldStart(parentContext, otelRequest)) {
121-
return;
129+
return new Object[] {null, responseListener};
122130
}
123131

124-
context = instrumenter().start(parentContext, otelRequest);
125-
scope = context.makeCurrent();
126-
132+
Context context = instrumenter().start(parentContext, otelRequest);
133+
AdviceScope adviceScope = new AdviceScope(otelRequest, context, context.makeCurrent());
127134
responseListener =
128135
new RestResponseListener(
129136
responseListener, parentContext, instrumenter(), context, otelRequest);
137+
return new Object[] {adviceScope, responseListener};
130138
}
131139

132140
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
133141
public static void stopSpan(
134-
@Advice.Thrown Throwable throwable,
135-
@Advice.Local("otelRequest") ElasticsearchRestRequest otelRequest,
136-
@Advice.Local("otelContext") Context context,
137-
@Advice.Local("otelScope") Scope scope) {
138-
139-
if (scope == null) {
140-
return;
142+
@Advice.Thrown @Nullable Throwable throwable, @Advice.Enter Object[] enterResult) {
143+
AdviceScope adviceScope = (AdviceScope) enterResult[0];
144+
if (adviceScope != null) {
145+
adviceScope.end(throwable);
141146
}
142-
scope.close();
143-
144-
if (throwable != null) {
145-
instrumenter().end(context, otelRequest, null, throwable);
146-
}
147-
// span ended in RestResponseListener
148147
}
149148
}
150149
}

0 commit comments

Comments
 (0)