Skip to content

Commit b0ec59e

Browse files
committed
apache httpclient indy-ready
1 parent 0c91939 commit b0ec59e

File tree

7 files changed

+262
-252
lines changed

7 files changed

+262
-252
lines changed

instrumentation/apache-httpclient/apache-httpclient-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v2_0/ApacheHttpClientInstrumentation.java

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import io.opentelemetry.context.Scope;
1919
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
2020
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
21+
import javax.annotation.Nullable;
2122
import net.bytebuddy.asm.Advice;
2223
import net.bytebuddy.description.type.TypeDescription;
2324
import net.bytebuddy.matcher.ElementMatcher;
@@ -47,32 +48,45 @@ public void transform(TypeTransformer transformer) {
4748
@SuppressWarnings("unused")
4849
public static class ExecuteMethodAdvice {
4950

50-
@Advice.OnMethodEnter(suppress = Throwable.class)
51-
public static void methodEnter(
52-
@Advice.Argument(1) HttpMethod httpMethod,
53-
@Advice.Local("otelContext") Context context,
54-
@Advice.Local("otelScope") Scope scope) {
55-
Context parentContext = currentContext();
56-
if (!instrumenter().shouldStart(parentContext, httpMethod)) {
57-
return;
51+
public static class AdviceScope {
52+
private final Context context;
53+
private final Scope scope;
54+
55+
private AdviceScope(Context context, Scope scope) {
56+
this.context = context;
57+
this.scope = scope;
5858
}
5959

60-
context = instrumenter().start(parentContext, httpMethod);
61-
scope = context.makeCurrent();
60+
@Nullable
61+
public static AdviceScope start(HttpMethod httpMethod) {
62+
Context parentContext = currentContext();
63+
if (!instrumenter().shouldStart(parentContext, httpMethod)) {
64+
return null;
65+
}
66+
Context context = instrumenter().start(parentContext, httpMethod);
67+
return new AdviceScope(context, context.makeCurrent());
68+
}
69+
70+
public void end(HttpMethod httpMethod, Throwable throwable) {
71+
scope.close();
72+
instrumenter().end(context, httpMethod, httpMethod, throwable);
73+
}
74+
}
75+
76+
@Advice.OnMethodEnter(suppress = Throwable.class)
77+
public static AdviceScope methodEnter(@Advice.Argument(1) HttpMethod httpMethod) {
78+
return AdviceScope.start(httpMethod);
6279
}
6380

6481
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
6582
public static void methodExit(
6683
@Advice.Argument(1) HttpMethod httpMethod,
67-
@Advice.Thrown Throwable throwable,
68-
@Advice.Local("otelContext") Context context,
69-
@Advice.Local("otelScope") Scope scope) {
70-
if (scope == null) {
71-
return;
72-
}
84+
@Advice.Thrown @Nullable Throwable throwable,
85+
@Advice.Enter @Nullable AdviceScope adviceScope) {
7386

74-
scope.close();
75-
instrumenter().end(context, httpMethod, httpMethod, throwable);
87+
if (adviceScope != null) {
88+
adviceScope.end(httpMethod, throwable);
89+
}
7690
}
7791
}
7892
}

instrumentation/apache-httpclient/apache-httpclient-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v2_0/ApacheHttpClientInstrumentationModule.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010
import com.google.auto.service.AutoService;
1111
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
1212
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
13+
import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule;
1314
import java.util.List;
1415

1516
@AutoService(InstrumentationModule.class)
16-
public class ApacheHttpClientInstrumentationModule extends InstrumentationModule {
17+
public class ApacheHttpClientInstrumentationModule extends InstrumentationModule
18+
implements ExperimentalInstrumentationModule {
1719

1820
public ApacheHttpClientInstrumentationModule() {
1921
super("apache-httpclient", "apache-httpclient-2.0");
@@ -23,4 +25,9 @@ public ApacheHttpClientInstrumentationModule() {
2325
public List<TypeInstrumentation> typeInstrumentations() {
2426
return singletonList(new ApacheHttpClientInstrumentation());
2527
}
28+
29+
@Override
30+
public boolean isIndyReady() {
31+
return true;
32+
}
2633
}

instrumentation/apache-httpclient/apache-httpclient-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v4_0/ApacheHttpClientInstrumentation.java

Lines changed: 79 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020
import io.opentelemetry.context.Scope;
2121
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
2222
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
23+
import javax.annotation.Nullable;
2324
import net.bytebuddy.asm.Advice;
25+
import net.bytebuddy.asm.Advice.AssignReturned;
26+
import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument;
2427
import net.bytebuddy.description.type.TypeDescription;
2528
import net.bytebuddy.matcher.ElementMatcher;
2629
import org.apache.http.HttpHost;
@@ -123,171 +126,140 @@ public void transform(TypeTransformer transformer) {
123126
this.getClass().getName() + "$RequestWithHandlerAdvice");
124127
}
125128

126-
@SuppressWarnings("unused")
127-
public static class UriRequestAdvice {
129+
public static class AdviceScope {
130+
private final ApacheHttpClientRequest otelRequest;
131+
private final Context parentContext;
132+
private final Context context;
133+
private final Scope scope;
134+
135+
private AdviceScope(
136+
ApacheHttpClientRequest otelRequest, Context parentContext, Context context, Scope scope) {
137+
this.otelRequest = otelRequest;
138+
this.parentContext = parentContext;
139+
this.context = context;
140+
this.scope = scope;
141+
}
128142

129-
@Advice.OnMethodEnter(suppress = Throwable.class)
130-
public static void methodEnter(
131-
@Advice.Argument(0) HttpUriRequest request,
132-
@Advice.Local("otelRequest") ApacheHttpClientRequest otelRequest,
133-
@Advice.Local("otelContext") Context context,
134-
@Advice.Local("otelScope") Scope scope) {
143+
@Nullable
144+
public static AdviceScope start(ApacheHttpClientRequest otelRequest) {
135145
Context parentContext = currentContext();
136-
137-
otelRequest = new ApacheHttpClientRequest(request);
138-
139146
if (!instrumenter().shouldStart(parentContext, otelRequest)) {
140-
return;
147+
return null;
141148
}
142-
143-
context = instrumenter().start(parentContext, otelRequest);
144-
scope = context.makeCurrent();
149+
Context context = instrumenter().start(parentContext, otelRequest);
150+
return new AdviceScope(otelRequest, parentContext, context, context.makeCurrent());
145151
}
146152

147-
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
148-
public static void methodExit(
149-
@Advice.Argument(0) HttpUriRequest request,
150-
@Advice.Return Object result,
151-
@Advice.Thrown Throwable throwable,
152-
@Advice.Local("otelRequest") ApacheHttpClientRequest otelRequest,
153-
@Advice.Local("otelContext") Context context,
154-
@Advice.Local("otelScope") Scope scope) {
155-
if (scope == null) {
156-
return;
157-
}
153+
public <T> ResponseHandler<T> wrapHandler(ResponseHandler<T> handler) {
154+
return new WrappingStatusSettingResponseHandler<>(
155+
context, parentContext, otelRequest, handler);
156+
}
158157

158+
public void end(@Nullable Object result, @Nullable Throwable throwable) {
159159
scope.close();
160160
ApacheHttpClientHelper.doMethodExit(context, otelRequest, result, throwable);
161161
}
162162
}
163163

164164
@SuppressWarnings("unused")
165-
public static class UriRequestWithHandlerAdvice {
165+
public static class UriRequestAdvice {
166166

167167
@Advice.OnMethodEnter(suppress = Throwable.class)
168-
public static void methodEnter(
169-
@Advice.Argument(0) HttpUriRequest request,
170-
@Advice.Argument(value = 1, readOnly = false) ResponseHandler<?> handler,
171-
@Advice.Local("otelRequest") ApacheHttpClientRequest otelRequest,
172-
@Advice.Local("otelContext") Context context,
173-
@Advice.Local("otelScope") Scope scope) {
174-
Context parentContext = currentContext();
168+
public static AdviceScope methodEnter(@Advice.Argument(0) HttpUriRequest request) {
169+
return AdviceScope.start(new ApacheHttpClientRequest(request));
170+
}
175171

176-
otelRequest = new ApacheHttpClientRequest(request);
172+
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
173+
public static void methodExit(
174+
@Advice.Argument(0) HttpUriRequest request,
175+
@Advice.Return @Nullable Object result,
176+
@Advice.Thrown @Nullable Throwable throwable,
177+
@Advice.Enter @Nullable AdviceScope adviceScope) {
177178

178-
if (!instrumenter().shouldStart(parentContext, otelRequest)) {
179-
return;
179+
if (adviceScope != null) {
180+
adviceScope.end(result, throwable);
180181
}
182+
}
183+
}
181184

182-
context = instrumenter().start(parentContext, otelRequest);
183-
scope = context.makeCurrent();
185+
@SuppressWarnings("unused")
186+
public static class UriRequestWithHandlerAdvice {
187+
188+
@AssignReturned.ToArguments(@ToArgument(value = 1, index = 1))
189+
@Advice.OnMethodEnter(suppress = Throwable.class)
190+
public static Object[] methodEnter(
191+
@Advice.Argument(0) HttpUriRequest request,
192+
@Advice.Argument(1) ResponseHandler<?> handler) {
184193

194+
AdviceScope adviceScope = AdviceScope.start(new ApacheHttpClientRequest(request));
185195
// Wrap the handler so we capture the status code
186-
if (handler != null) {
187-
handler =
188-
new WrappingStatusSettingResponseHandler<>(
189-
context, parentContext, otelRequest, handler);
190-
}
196+
return new Object[] {
197+
adviceScope, adviceScope == null ? handler : adviceScope.wrapHandler(handler)
198+
};
191199
}
192200

193201
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
194202
public static void methodExit(
195-
@Advice.Argument(0) HttpUriRequest request,
196203
@Advice.Return Object result,
197204
@Advice.Thrown Throwable throwable,
198-
@Advice.Local("otelRequest") ApacheHttpClientRequest otelRequest,
199-
@Advice.Local("otelContext") Context context,
200-
@Advice.Local("otelScope") Scope scope) {
201-
if (scope == null) {
202-
return;
203-
}
205+
@Advice.Enter Object[] enterResult) {
204206

205-
scope.close();
206-
ApacheHttpClientHelper.doMethodExit(context, otelRequest, result, throwable);
207+
AdviceScope adviceScope = (AdviceScope) enterResult[0];
208+
if (adviceScope != null) {
209+
adviceScope.end(result, throwable);
210+
}
207211
}
208212
}
209213

210214
@SuppressWarnings("unused")
211215
public static class RequestAdvice {
212216

213217
@Advice.OnMethodEnter(suppress = Throwable.class)
214-
public static void methodEnter(
215-
@Advice.Argument(0) HttpHost host,
216-
@Advice.Argument(1) HttpRequest request,
217-
@Advice.Local("otelRequest") ApacheHttpClientRequest otelRequest,
218-
@Advice.Local("otelContext") Context context,
219-
@Advice.Local("otelScope") Scope scope) {
220-
Context parentContext = currentContext();
221-
222-
otelRequest = new ApacheHttpClientRequest(host, request);
223-
224-
if (!instrumenter().shouldStart(parentContext, otelRequest)) {
225-
return;
226-
}
227-
228-
context = instrumenter().start(parentContext, otelRequest);
229-
scope = context.makeCurrent();
218+
public static AdviceScope methodEnter(
219+
@Advice.Argument(0) HttpHost host, @Advice.Argument(1) HttpRequest request) {
220+
return AdviceScope.start(new ApacheHttpClientRequest(host, request));
230221
}
231222

232223
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
233224
public static void methodExit(
234225
@Advice.Return Object result,
235226
@Advice.Thrown Throwable throwable,
236-
@Advice.Local("otelRequest") ApacheHttpClientRequest otelRequest,
237-
@Advice.Local("otelContext") Context context,
238-
@Advice.Local("otelScope") Scope scope) {
239-
if (scope == null) {
240-
return;
241-
}
227+
@Advice.Enter AdviceScope adviceScope) {
242228

243-
scope.close();
244-
ApacheHttpClientHelper.doMethodExit(context, otelRequest, result, throwable);
229+
if (adviceScope != null) {
230+
adviceScope.end(result, throwable);
231+
}
245232
}
246233
}
247234

248235
@SuppressWarnings("unused")
249236
public static class RequestWithHandlerAdvice {
250237

238+
@AssignReturned.ToArguments(@ToArgument(value = 2, index = 1))
251239
@Advice.OnMethodEnter(suppress = Throwable.class)
252-
public static void methodEnter(
240+
public static Object[] methodEnter(
253241
@Advice.Argument(0) HttpHost host,
254242
@Advice.Argument(1) HttpRequest request,
255-
@Advice.Argument(value = 2, readOnly = false) ResponseHandler<?> handler,
256-
@Advice.Local("otelRequest") ApacheHttpClientRequest otelRequest,
257-
@Advice.Local("otelContext") Context context,
258-
@Advice.Local("otelScope") Scope scope) {
259-
Context parentContext = currentContext();
260-
261-
otelRequest = new ApacheHttpClientRequest(host, request);
262-
263-
if (!instrumenter().shouldStart(parentContext, otelRequest)) {
264-
return;
265-
}
266-
267-
context = instrumenter().start(parentContext, otelRequest);
268-
scope = context.makeCurrent();
269-
270-
// Wrap the handler so we capture the status code
271-
if (handler != null) {
272-
handler =
273-
new WrappingStatusSettingResponseHandler<>(
274-
context, parentContext, otelRequest, handler);
275-
}
243+
@Advice.Argument(2) ResponseHandler<?> handler) {
244+
245+
AdviceScope adviceScope = AdviceScope.start(new ApacheHttpClientRequest(host, request));
246+
return new Object[] {
247+
adviceScope,
248+
// Wrap the handler so we capture the status code
249+
adviceScope == null ? handler : adviceScope.wrapHandler(handler)
250+
};
276251
}
277252

278253
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
279254
public static void methodExit(
280255
@Advice.Return Object result,
281256
@Advice.Thrown Throwable throwable,
282-
@Advice.Local("otelRequest") ApacheHttpClientRequest otelRequest,
283-
@Advice.Local("otelContext") Context context,
284-
@Advice.Local("otelScope") Scope scope) {
285-
if (scope == null) {
286-
return;
287-
}
257+
@Advice.Enter Object[] enterResult) {
288258

289-
scope.close();
290-
ApacheHttpClientHelper.doMethodExit(context, otelRequest, result, throwable);
259+
AdviceScope adviceScope = (AdviceScope) enterResult[0];
260+
if (adviceScope != null) {
261+
adviceScope.end(result, throwable);
262+
}
291263
}
292264
}
293265
}

instrumentation/apache-httpclient/apache-httpclient-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v4_0/ApacheHttpClientInstrumentationModule.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010
import com.google.auto.service.AutoService;
1111
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
1212
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
13+
import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule;
1314
import java.util.List;
1415

1516
@AutoService(InstrumentationModule.class)
16-
public class ApacheHttpClientInstrumentationModule extends InstrumentationModule {
17+
public class ApacheHttpClientInstrumentationModule extends InstrumentationModule
18+
implements ExperimentalInstrumentationModule {
1719

1820
public ApacheHttpClientInstrumentationModule() {
1921
super("apache-httpclient", "apache-httpclient-4.0");
@@ -23,4 +25,9 @@ public ApacheHttpClientInstrumentationModule() {
2325
public List<TypeInstrumentation> typeInstrumentations() {
2426
return singletonList(new ApacheHttpClientInstrumentation());
2527
}
28+
29+
@Override
30+
public boolean isIndyReady() {
31+
return true;
32+
}
2633
}

0 commit comments

Comments
 (0)