From e474a1582ca82aed715db2d3a2a1ae0e7d2d1f8a Mon Sep 17 00:00:00 2001 From: Jaehong-Kim Date: Thu, 23 May 2024 11:22:29 +0900 Subject: [PATCH] [#11057] Fix getInputStream() loop in jdk http plugin --- .../spring-webflux-plugin-testweb/pom.xml | 4 + .../plugin/SpringWebfluxPluginController.java | 130 ++++++++++++++- .../plugin/jdk/http/HttpURLConnectionIT.java | 16 +- .../plugin/jdk/http/ConnectedGetter.java | 23 --- .../plugin/jdk/http/ConnectingGetter.java | 23 --- .../plugin/jdk/http/DelegateGetter.java | 23 --- .../jdk/http/JdkHttpClientRequestAdaptor.java | 8 +- .../http/JdkHttpClientResponseAdaptor.java | 2 - .../plugin/jdk/http/JdkHttpConstants.java | 3 + .../plugin/jdk/http/JdkHttpPlugin.java | 63 ++++--- .../plugin/jdk/http/JdkHttpTypeProvider.java | 1 + .../AbstractHttpURLConnectionInterceptor.java | 157 ++++-------------- ...RLConnectionGetHeaderFieldInterceptor.java | 145 ++++++++++++++++ ...RLConnectionGetInputStreamInterceptor.java | 96 +++++++++++ .../HttpURLConnectionInterceptor.java | 10 -- ...URLConnectionPlainConnect0Interceptor.java | 53 ++++++ .../HttpsURLConnectionImplInterceptor.java | 13 -- .../pinpoint/common/trace/ServiceType.java | 1 + 18 files changed, 504 insertions(+), 267 deletions(-) delete mode 100644 agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/ConnectedGetter.java delete mode 100644 agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/ConnectingGetter.java delete mode 100644 agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/DelegateGetter.java create mode 100644 agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpURLConnectionGetHeaderFieldInterceptor.java create mode 100644 agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpURLConnectionGetInputStreamInterceptor.java create mode 100644 agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpURLConnectionPlainConnect0Interceptor.java diff --git a/agent-module/agent-testweb/spring-webflux-plugin-testweb/pom.xml b/agent-module/agent-testweb/spring-webflux-plugin-testweb/pom.xml index dd4ed008be70..78f724cb4ed8 100644 --- a/agent-module/agent-testweb/spring-webflux-plugin-testweb/pom.xml +++ b/agent-module/agent-testweb/spring-webflux-plugin-testweb/pom.xml @@ -33,6 +33,10 @@ com.navercorp.pinpoint pinpoint-agent-testweb-commons + + commons-io + commons-io + diff --git a/agent-module/agent-testweb/spring-webflux-plugin-testweb/src/main/java/com/pinpoint/test/plugin/SpringWebfluxPluginController.java b/agent-module/agent-testweb/spring-webflux-plugin-testweb/src/main/java/com/pinpoint/test/plugin/SpringWebfluxPluginController.java index 78d4a460e998..844cefd719d6 100644 --- a/agent-module/agent-testweb/spring-webflux-plugin-testweb/src/main/java/com/pinpoint/test/plugin/SpringWebfluxPluginController.java +++ b/agent-module/agent-testweb/spring-webflux-plugin-testweb/src/main/java/com/pinpoint/test/plugin/SpringWebfluxPluginController.java @@ -21,15 +21,19 @@ import io.netty.channel.ChannelOption; import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.handler.timeout.WriteTimeoutHandler; +import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; import org.springframework.web.method.HandlerMethod; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.client.WebClient; @@ -40,6 +44,13 @@ import reactor.netty.http.client.HttpClient; import reactor.netty.http.client.HttpClientRequest; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.ArrayList; import java.util.Comparator; @@ -254,4 +265,121 @@ public Mono clientReactorTimeout(ServerWebExchange exchange) { return Mono.just("OK"); } -} + + @GetMapping("/client/resttemplate") + public Mono clientRestTemplate(ServerWebExchange exchange) { + RestTemplate restTemplate = new RestTemplate(); + String fooResourceUrl + = "http://httpbin.org"; + ResponseEntity response + = restTemplate.getForEntity(fooResourceUrl + "/", String.class); + System.out.println(response.getStatusCode()); + System.out.println(response.getBody()); + + return Mono.just("OK"); + } + + @GetMapping("/client/resttemplate/https") + public Mono clientRestTemplateHttps(ServerWebExchange exchange) { + RestTemplate restTemplate = new RestTemplate(); + String fooResourceUrl + = "https://naver.com"; + ResponseEntity response + = restTemplate.getForEntity(fooResourceUrl + "/", String.class); + System.out.println(response.getStatusCode()); + System.out.println(response.getBody()); + + return Mono.just("OK"); + } + + @RequestMapping(value = "/jdk/connect") + public String get() { + + final URL url = newURL("http://httpbin.org"); + try { + URLConnection connection = url.openConnection(); + connection.connect(); + } catch (IOException e) { + return "fail"; + } + + return "OK"; + } + @RequestMapping(value = "/jdk/connect/https") + public String getHttps() { + + final URL url = newURL("https://naver.com"); + try { + URLConnection connection = url.openConnection(); + connection.connect(); + } catch (IOException e) { + return "fail"; + } + + return "OK"; + } + @RequestMapping(value = "/jdk/connect/duplicated") + public String getDuplicated() { + + final URL url = newURL("http://httpbin.org"); + try { + URLConnection connection = url.openConnection(); + connection.connect(); + connection.connect(); + } catch (IOException e) { + return "fail"; + } + + return "OK"; + } + + @RequestMapping(value = "/jdk/connect2") + public String get2() { + + final URL url = newURL("http://httpbin.org"); + try { + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.connect(); + + final int responseCode = connection.getResponseCode(); + final List contents = readStream(connection); + } catch (IOException e) { + return "fail"; + } + + + return "OK"; + } + + @RequestMapping(value = "/jdk/connect2/https") + public String get2Https() { + + final URL url = newURL("https://naver.com"); + try { + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.connect(); + + final int responseCode = connection.getResponseCode(); + final List contents = readStream(connection); + } catch (IOException e) { + return "fail"; + } + + + return "OK"; + } + + private List readStream(HttpURLConnection connection) throws IOException { + try (InputStream inputStream = connection.getInputStream()) { + return IOUtils.readLines(inputStream, StandardCharsets.UTF_8); + } + } + + private URL newURL(String spec) { + try { + return new URL(spec); + } catch (MalformedURLException exception) { + throw new IllegalArgumentException("invalid url" + spec, exception); + } + } +} \ No newline at end of file diff --git a/agent-module/plugins-it/jdk-http-it/src/test/java/com/navercorp/pinpoint/it/plugin/jdk/http/HttpURLConnectionIT.java b/agent-module/plugins-it/jdk-http-it/src/test/java/com/navercorp/pinpoint/it/plugin/jdk/http/HttpURLConnectionIT.java index ece8c7377292..735a6f4ade6b 100644 --- a/agent-module/plugins-it/jdk-http-it/src/test/java/com/navercorp/pinpoint/it/plugin/jdk/http/HttpURLConnectionIT.java +++ b/agent-module/plugins-it/jdk-http-it/src/test/java/com/navercorp/pinpoint/it/plugin/jdk/http/HttpURLConnectionIT.java @@ -35,7 +35,6 @@ import java.net.UnknownHostException; import static com.navercorp.pinpoint.bootstrap.plugin.test.Expectations.annotation; -import static com.navercorp.pinpoint.bootstrap.plugin.test.Expectations.anyAnnotationValue; import static com.navercorp.pinpoint.bootstrap.plugin.test.Expectations.event; import static com.navercorp.pinpoint.bootstrap.plugin.test.Expectations.notNull; @@ -71,14 +70,11 @@ public void test() throws Exception { verifier.printMethod(); Class targetClass = Class.forName("sun.net.www.protocol.http.HttpURLConnection"); - Method getInputStream = targetClass.getMethod("getInputStream"); + Method getInputStream = targetClass.getMethod("connect"); String destinationId = webServer.getHostAndPort(); String httpUrl = webServer.getCallHttpUrl(); verifier.verifyTraceCount(2); - verifier.verifyTrace(event("JDK_HTTPURLCONNECTOR", getInputStream, null, null, destinationId, - annotation("http.url", httpUrl), - annotation("http.resp.header", anyAnnotationValue()))); } @Test @@ -94,16 +90,13 @@ public void testConnectTwice() throws Exception { Class targetClass = Class.forName("sun.net.www.protocol.http.HttpURLConnection"); Method connect = targetClass.getMethod("connect"); - Method getInputStream = targetClass.getMethod("getInputStream"); + Method getInputStream = targetClass.getMethod("getHeaderField", int.class); String destinationId = webServer.getHostAndPort(); String httpUrl = webServer.getCallHttpUrl(); - verifier.verifyTraceCount(2); + verifier.verifyTraceCount(3); verifier.verifyTrace(event("JDK_HTTPURLCONNECTOR", connect, null, null, destinationId, annotation("http.url", httpUrl))); - verifier.verifyTrace(event("JDK_HTTPURLCONNECTOR", getInputStream, null, null, destinationId, - annotation("http.url", httpUrl), - annotation("http.resp.header", anyAnnotationValue()))); } @Test @@ -133,10 +126,9 @@ public void testConnecting() throws Exception { Class targetClass = Class.forName("sun.net.www.protocol.http.HttpURLConnection"); Method getInputStream = targetClass.getMethod("connect"); - verifier.verifyTrace(event("JDK_HTTPURLCONNECTOR", getInputStream, null, null, "no.such.url", notNull(""), annotation("http.url", "http://no.such.url"))); verifier.verifyTrace(event("JDK_HTTPURLCONNECTOR", getInputStream, null, null, "no.such.url", notNull(""), annotation("http.url", "http://no.such.url"))); verifier.printMethod(); - verifier.verifyTraceCount(0); + verifier.verifyTraceCount(2); } } diff --git a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/ConnectedGetter.java b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/ConnectedGetter.java deleted file mode 100644 index b5a7efbc1e0f..000000000000 --- a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/ConnectedGetter.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2014 NAVER Corp. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.navercorp.pinpoint.plugin.jdk.http; - -/** - * @author Jongho Moon - * - */ -public interface ConnectedGetter { - boolean _$PINPOINT$_isConnected(); -} diff --git a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/ConnectingGetter.java b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/ConnectingGetter.java deleted file mode 100644 index 3fa08c62d026..000000000000 --- a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/ConnectingGetter.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2014 NAVER Corp. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.navercorp.pinpoint.plugin.jdk.http; - -/** - * @author Jongho Moon - * - */ -public interface ConnectingGetter { - boolean _$PINPOINT$_isConnecting(); -} diff --git a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/DelegateGetter.java b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/DelegateGetter.java deleted file mode 100644 index 286f783bda08..000000000000 --- a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/DelegateGetter.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2021 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.plugin.jdk.http; - -import sun.net.www.protocol.https.DelegateHttpsURLConnection; - -public interface DelegateGetter { - DelegateHttpsURLConnection _$PINPOINT$_getDelegate(); -} diff --git a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpClientRequestAdaptor.java b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpClientRequestAdaptor.java index c3c49cf09a9e..920f93ed6470 100644 --- a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpClientRequestAdaptor.java +++ b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpClientRequestAdaptor.java @@ -26,11 +26,9 @@ */ public class JdkHttpClientRequestAdaptor implements ClientRequestAdaptor { - public JdkHttpClientRequestAdaptor() { } - @Override public String getDestinationId(HttpURLConnection httpURLConnection) { final URL url = httpURLConnection.getURL(); @@ -39,12 +37,12 @@ public String getDestinationId(HttpURLConnection httpURLConnection) { final int port = url.getPort(); return getEndpoint(host, port); } - return "Unknown"; + return "UNKNOWN"; } - public static String getEndpoint(final String host, final int port) { + String getEndpoint(final String host, final int port) { if (host == null) { - return "Unknown"; + return "UNKNOWN"; } if (port < 0) { return host; diff --git a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpClientResponseAdaptor.java b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpClientResponseAdaptor.java index 0c2cd7b27205..efee0385d484 100644 --- a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpClientResponseAdaptor.java +++ b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpClientResponseAdaptor.java @@ -36,12 +36,10 @@ public boolean containsHeader(HttpURLConnection response, String name) { @Override public void setHeader(HttpURLConnection response, String name, String value) { - } @Override public void addHeader(HttpURLConnection response, String name, String value) { - } @Override diff --git a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpConstants.java b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpConstants.java index bd1c2cc5daad..e67f50821d69 100644 --- a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpConstants.java +++ b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpConstants.java @@ -28,4 +28,7 @@ private JdkHttpConstants() { } public static final ServiceType SERVICE_TYPE = ServiceTypeFactory.of(9055, "JDK_HTTPURLCONNECTOR", "JDK_HTTPCONNECTOR", RECORD_STATISTICS); + public static final ServiceType SERVICE_TYPE_INTERNAL = ServiceTypeFactory.of(9067, "JDK_HTTPURLCONNECTOR_INTERNAL", "JDK_HTTPCONNECTOR"); + + public static final String TRACE_SCOPE_NAME_GET_INPUT_STREAM = "_GetInputStream"; } diff --git a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpPlugin.java b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpPlugin.java index 94c8461b9871..43e9c0c8561b 100644 --- a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpPlugin.java +++ b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpPlugin.java @@ -1,4 +1,3 @@ -package com.navercorp.pinpoint.plugin.jdk.http; /* * Copyright 2014 NAVER Corp. * @@ -14,34 +13,34 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package com.navercorp.pinpoint.plugin.jdk.http; import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass; import com.navercorp.pinpoint.bootstrap.instrument.InstrumentException; import com.navercorp.pinpoint.bootstrap.instrument.InstrumentMethod; import com.navercorp.pinpoint.bootstrap.instrument.Instrumentor; +import com.navercorp.pinpoint.bootstrap.instrument.transformer.MatchableTransformTemplate; +import com.navercorp.pinpoint.bootstrap.instrument.transformer.MatchableTransformTemplateAware; import com.navercorp.pinpoint.bootstrap.instrument.transformer.TransformCallback; -import com.navercorp.pinpoint.bootstrap.instrument.transformer.TransformTemplate; -import com.navercorp.pinpoint.bootstrap.instrument.transformer.TransformTemplateAware; -import com.navercorp.pinpoint.bootstrap.interceptor.scope.ExecutionPolicy; import com.navercorp.pinpoint.bootstrap.logging.PluginLogManager; import com.navercorp.pinpoint.bootstrap.logging.PluginLogger; import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPlugin; import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPluginSetupContext; -import com.navercorp.pinpoint.bootstrap.plugin.util.InstrumentUtils; +import com.navercorp.pinpoint.plugin.jdk.http.interceptor.HttpURLConnectionGetHeaderFieldInterceptor; +import com.navercorp.pinpoint.plugin.jdk.http.interceptor.HttpURLConnectionGetInputStreamInterceptor; import com.navercorp.pinpoint.plugin.jdk.http.interceptor.HttpURLConnectionInterceptor; +import com.navercorp.pinpoint.plugin.jdk.http.interceptor.HttpURLConnectionPlainConnect0Interceptor; import com.navercorp.pinpoint.plugin.jdk.http.interceptor.HttpsURLConnectionImplInterceptor; import java.security.ProtectionDomain; /** - * * @author Jongho Moon * @author yjqg6666 - * */ -public class JdkHttpPlugin implements ProfilerPlugin, TransformTemplateAware { +public class JdkHttpPlugin implements ProfilerPlugin, MatchableTransformTemplateAware { - private TransformTemplate transformTemplate; + private MatchableTransformTemplate transformTemplate; private final PluginLogger logger = PluginLogManager.getLogger(this.getClass()); @@ -64,20 +63,22 @@ public static class HttpURLConnectionTransform implements TransformCallback { public byte[] doInTransform(Instrumentor instrumentor, ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException { InstrumentClass target = instrumentor.getInstrumentClass(loader, className, classfileBuffer); - target.addGetter(ConnectedGetter.class, "connected"); - - if (target.hasField("connecting", "boolean")) { - target.addGetter(ConnectingGetter.class, "connecting"); + final InstrumentMethod connectMethod = target.getDeclaredMethod("connect"); + if (connectMethod != null) { + connectMethod.addScopedInterceptor(HttpURLConnectionInterceptor.class, "HttpURLConnectionInterceptor"); + } + final InstrumentMethod plainConnect0Method = target.getDeclaredMethod("plainConnect0"); + if (plainConnect0Method != null) { + plainConnect0Method.addInterceptor(HttpURLConnectionPlainConnect0Interceptor.class); + } + final InstrumentMethod getHeaderFieldMethod = target.getDeclaredMethod("getHeaderField", "int"); + if (getHeaderFieldMethod != null) { + getHeaderFieldMethod.addInterceptor(HttpURLConnectionGetHeaderFieldInterceptor.class); + } + final InstrumentMethod getInputStreamMethod = target.getDeclaredMethod("getInputStream"); + if (getInputStreamMethod != null) { + getInputStreamMethod.addInterceptor(HttpURLConnectionGetInputStreamInterceptor.class); } - - final InstrumentMethod connectMethod = InstrumentUtils.findMethod(target, "connect"); - connectMethod.addScopedInterceptor(HttpURLConnectionInterceptor.class, "HttpURLConnectionConnect", ExecutionPolicy.ALWAYS); - - final InstrumentMethod getInputStreamMethod = InstrumentUtils.findMethod(target, "getInputStream"); - getInputStreamMethod.addScopedInterceptor(HttpURLConnectionInterceptor.class, "HttpURLConnectionInput", ExecutionPolicy.BOUNDARY); - - final InstrumentMethod getOutputStreamMethod = InstrumentUtils.findMethod(target, "getOutputStream"); - getOutputStreamMethod.addScopedInterceptor(HttpURLConnectionInterceptor.class, "HttpURLConnectionOutput", ExecutionPolicy.BOUNDARY); return target.toBytecode(); } @@ -89,23 +90,17 @@ public static class HttpsURLConnectionImplTransform implements TransformCallback public byte[] doInTransform(Instrumentor instrumentor, ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException { InstrumentClass target = instrumentor.getInstrumentClass(loader, className, classfileBuffer); - target.addGetter(DelegateGetter.class, "delegate"); - - final InstrumentMethod connectMethod = InstrumentUtils.findMethod(target, "connect"); - connectMethod.addScopedInterceptor(HttpsURLConnectionImplInterceptor.class, "HttpURLConnectionConnect", ExecutionPolicy.ALWAYS); - - final InstrumentMethod getInputStreamMethod = InstrumentUtils.findMethod(target, "getInputStream"); - getInputStreamMethod.addScopedInterceptor(HttpsURLConnectionImplInterceptor.class, "HttpURLConnectionInput", ExecutionPolicy.BOUNDARY); - - final InstrumentMethod getOutputStreamMethod = InstrumentUtils.findMethod(target, "getOutputStream"); - getOutputStreamMethod.addScopedInterceptor(HttpsURLConnectionImplInterceptor.class, "HttpURLConnectionOutput", ExecutionPolicy.BOUNDARY); + final InstrumentMethod connectMethod = target.getDeclaredMethod("connect"); + if (connectMethod != null) { + connectMethod.addScopedInterceptor(HttpsURLConnectionImplInterceptor.class, "HttpURLConnectionInterceptor"); + } return target.toBytecode(); } } @Override - public void setTransformTemplate(TransformTemplate transformTemplate) { + public void setTransformTemplate(MatchableTransformTemplate transformTemplate) { this.transformTemplate = transformTemplate; } -} +} \ No newline at end of file diff --git a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpTypeProvider.java b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpTypeProvider.java index 9f0e6c03de33..a7db9b951ae9 100644 --- a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpTypeProvider.java +++ b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/JdkHttpTypeProvider.java @@ -28,6 +28,7 @@ public class JdkHttpTypeProvider implements TraceMetadataProvider { @Override public void setup(TraceMetadataSetupContext context) { context.addServiceType(JdkHttpConstants.SERVICE_TYPE, AnnotationKeyMatchers.exact(AnnotationKey.HTTP_URL)); + context.addServiceType(JdkHttpConstants.SERVICE_TYPE_INTERNAL, AnnotationKeyMatchers.exact(AnnotationKey.HTTP_INTERNAL_DISPLAY)); } } diff --git a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/AbstractHttpURLConnectionInterceptor.java b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/AbstractHttpURLConnectionInterceptor.java index 4c19ca3381a2..b1443a9655ca 100644 --- a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/AbstractHttpURLConnectionInterceptor.java +++ b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/AbstractHttpURLConnectionInterceptor.java @@ -21,7 +21,6 @@ import com.navercorp.pinpoint.bootstrap.context.Trace; import com.navercorp.pinpoint.bootstrap.context.TraceContext; import com.navercorp.pinpoint.bootstrap.context.TraceId; -import com.navercorp.pinpoint.bootstrap.context.scope.TraceScope; import com.navercorp.pinpoint.bootstrap.interceptor.AroundInterceptor; import com.navercorp.pinpoint.bootstrap.interceptor.scope.InterceptorScope; import com.navercorp.pinpoint.bootstrap.interceptor.scope.InterceptorScopeInvocation; @@ -32,19 +31,12 @@ import com.navercorp.pinpoint.bootstrap.plugin.request.ClientRequestRecorder; import com.navercorp.pinpoint.bootstrap.plugin.request.DefaultRequestTraceWriter; import com.navercorp.pinpoint.bootstrap.plugin.request.RequestTraceWriter; -import com.navercorp.pinpoint.bootstrap.plugin.response.ResponseHeaderRecorderFactory; -import com.navercorp.pinpoint.bootstrap.plugin.response.ServerResponseHeaderRecorder; -import com.navercorp.pinpoint.bootstrap.util.ScopeUtils; -import com.navercorp.pinpoint.plugin.jdk.http.ConnectingGetter; import com.navercorp.pinpoint.plugin.jdk.http.HttpURLConnectionClientHeaderAdaptor; import com.navercorp.pinpoint.plugin.jdk.http.JdkHttpClientRequestAdaptor; -import com.navercorp.pinpoint.plugin.jdk.http.JdkHttpClientResponseAdaptor; import com.navercorp.pinpoint.plugin.jdk.http.JdkHttpConstants; -import com.navercorp.pinpoint.plugin.jdk.http.JdkHttpPlugin; import com.navercorp.pinpoint.plugin.jdk.http.JdkHttpPluginConfig; import java.net.HttpURLConnection; -import java.net.URL; /** * @author netspider @@ -53,17 +45,16 @@ */ public abstract class AbstractHttpURLConnectionInterceptor implements AroundInterceptor { private static final Object TRACE_BLOCK_BEGIN_MARKER = new Object(); - private static final String TRACE_SCOPE_NAME_RESPONSE = "_JdkHttpInputStreamRespRecording"; private final PluginLogger logger = PluginLogManager.getLogger(this.getClass()); private final boolean isDebug = logger.isDebugEnabled(); private final TraceContext traceContext; private final MethodDescriptor descriptor; private final InterceptorScope scope; - private final ClientRequestRecorder clientRequestRecorder; - private final ServerResponseHeaderRecorder responseHeaderRecorder; + private final ClientRequestRecorder clientRequestRecorder; private final RequestTraceWriter requestTraceWriter; + private final ClientRequestAdaptor clientRequestAdaptor = new JdkHttpClientRequestAdaptor(); public AbstractHttpURLConnectionInterceptor(TraceContext traceContext, MethodDescriptor descriptor, InterceptorScope scope) { this.traceContext = traceContext; @@ -71,68 +62,54 @@ public AbstractHttpURLConnectionInterceptor(TraceContext traceContext, MethodDes this.scope = scope; final JdkHttpPluginConfig config = new JdkHttpPluginConfig(traceContext.getProfilerConfig()); - - ClientRequestAdaptor clientRequestAdaptor = new JdkHttpClientRequestAdaptor(); this.clientRequestRecorder = new ClientRequestRecorder<>(config.isParam(), clientRequestAdaptor); - this.responseHeaderRecorder = ResponseHeaderRecorderFactory.newResponseHeaderRecorder(traceContext.getProfilerConfig(), new JdkHttpClientResponseAdaptor()); - - ClientHeaderAdaptor clientHeaderAdaptor = new HttpURLConnectionClientHeaderAdaptor(); + final ClientHeaderAdaptor clientHeaderAdaptor = new HttpURLConnectionClientHeaderAdaptor(); this.requestTraceWriter = new DefaultRequestTraceWriter<>(clientHeaderAdaptor, traceContext); } - abstract boolean isConnected(Object target); - @Override public void before(Object target, Object[] args) { if (isDebug) { logger.beforeInterceptor(target, args); } - if (target == null) { - return; - } - Trace trace = traceContext.currentRawTraceObject(); if (trace == null) { return; } - final boolean interceptingGetInputStream = isInterceptingGetInputStream(); - final boolean recordingResponse = isRecordingResponse(trace); - if (recordingResponse) { - if (interceptingGetInputStream) { - return; - } else { - clearRecordingResponseStatus(trace); - } - } - - boolean connected = isConnected(target); - boolean connecting = false; - if (target instanceof ConnectingGetter) { - connecting = ((ConnectingGetter) target)._$PINPOINT$_isConnecting(); - } - - boolean addRequestHeader = !connected && !connecting; - if (isInterceptingHttps()) { - addRequestHeader = addRequestHeader && isInterceptingConnect(); - } - - final HttpURLConnection request = (HttpURLConnection) target; - final boolean canSample = trace.canSampled(); - if (canSample) { - scope.getCurrentInvocation().setAttachment(TRACE_BLOCK_BEGIN_MARKER); - final SpanEventRecorder recorder = trace.traceBlockBegin(); - recorder.recordServiceType(JdkHttpConstants.SERVICE_TYPE); - if (addRequestHeader) { + try { + final HttpURLConnection request = (HttpURLConnection) target; + final boolean canSample = trace.canSampled(); + if (canSample) { final TraceId nextId = trace.getTraceId().getNextTraceId(); + String host = this.clientRequestAdaptor.getDestinationId(request); + try { + this.requestTraceWriter.write(request, nextId, host); + } catch (Exception e) { + // It happens if it is already connected or connected. + if(isDebug) { + logger.debug("Failed to requestTraceWriter, already connected or connected"); + } + return; + } + scope.getCurrentInvocation().setAttachment(TRACE_BLOCK_BEGIN_MARKER); + final SpanEventRecorder recorder = trace.traceBlockBegin(); + recorder.recordServiceType(JdkHttpConstants.SERVICE_TYPE); recorder.recordNextSpanId(nextId.getSpanId()); - String host = getHost(request); - this.requestTraceWriter.write(request, nextId, host); + } else { + try { + this.requestTraceWriter.write(request); + } catch (Exception ignored) { + // It happens if it is already connected or connected. + if(isDebug) { + logger.debug("Failed to requestTraceWriter, already connected or connected"); + } + } } - } else { - if (addRequestHeader) { - this.requestTraceWriter.write(request); + } catch (Throwable th) { + if (logger.isWarnEnabled()) { + logger.warn("BEFORE. Caused:{}", th.getMessage(), th); } } } @@ -143,12 +120,9 @@ public void after(Object target, Object[] args, Object result, Throwable throwab // do not log result logger.afterInterceptor(target, args); } - if (target == null) { - return; - } Trace trace = traceContext.currentTraceObject(); - if (trace == null || !trace.canSampled()) { + if (trace == null) { return; } @@ -157,78 +131,19 @@ public void after(Object target, Object[] args, Object result, Throwable throwab return; } - final boolean interceptingGetInputStream = isInterceptingGetInputStream(); - if (interceptingGetInputStream && isRecordingResponse(trace)) { - return; - } - try { final HttpURLConnection request = (HttpURLConnection) target; final SpanEventRecorder recorder = trace.currentSpanEventRecorder(); recorder.recordApi(descriptor); recorder.recordException(throwable); this.clientRequestRecorder.record(recorder, request, throwable); - if (interceptingGetInputStream) { - if (startRecordingResponse(trace)) { - this.responseHeaderRecorder.recordHeader(recorder, request); - } + } catch (Throwable th) { + if (logger.isWarnEnabled()) { + logger.warn("AFTER error. Caused:{}", th.getMessage(), th); } } finally { currentInvocation.removeAttachment(); trace.traceBlockEnd(); } } - - private String getHost(HttpURLConnection httpURLConnection) { - final URL url = httpURLConnection.getURL(); - if (url != null) { - final String host = url.getHost(); - final int port = url.getPort(); - if (host != null) { - return JdkHttpClientRequestAdaptor.getEndpoint(host, port); - } - } - return null; - } - - private boolean isInterceptingGetInputStream() { - return "getInputStream".contentEquals(this.descriptor.getMethodName()); - } - - private boolean isInterceptingConnect() { - return "connect".contentEquals(this.descriptor.getMethodName()); - } - - private boolean isInterceptingHttps() { - return JdkHttpPlugin.INTERCEPT_HTTPS_CLASS_NAME.contentEquals(this.descriptor.getClassName()); - } - - private boolean isRecordingResponse(Trace trace) { - return ScopeUtils.isEndScope(trace, TRACE_SCOPE_NAME_RESPONSE); - } - - private boolean startRecordingResponse(Trace trace) { - TraceScope scope = trace.getScope(TRACE_SCOPE_NAME_RESPONSE); - if (scope == null) { - trace.addScope(TRACE_SCOPE_NAME_RESPONSE); - scope = trace.getScope(TRACE_SCOPE_NAME_RESPONSE); - } - if (scope != null) { - final boolean ok = scope.tryEnter(); - if (!ok) { - logger.warn("Try to startRecording response failed, tryEnter scope failed"); - } - return ok; - } else { - logger.warn("Try to startRecording response failed, getOrAdd scope failed"); - return false; - } - } - - private void clearRecordingResponseStatus(Trace trace) { - if (!ScopeUtils.leaveScope(trace, TRACE_SCOPE_NAME_RESPONSE)) { - logger.warn("Try to learRecordingResponseStatus failed, canLeave scope returned false"); - } - } - } diff --git a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpURLConnectionGetHeaderFieldInterceptor.java b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpURLConnectionGetHeaderFieldInterceptor.java new file mode 100644 index 000000000000..2d93490b97a1 --- /dev/null +++ b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpURLConnectionGetHeaderFieldInterceptor.java @@ -0,0 +1,145 @@ +/* + * Copyright 2024 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.navercorp.pinpoint.plugin.jdk.http.interceptor; + +import com.navercorp.pinpoint.bootstrap.context.MethodDescriptor; +import com.navercorp.pinpoint.bootstrap.context.SpanEventRecorder; +import com.navercorp.pinpoint.bootstrap.context.Trace; +import com.navercorp.pinpoint.bootstrap.context.TraceContext; +import com.navercorp.pinpoint.bootstrap.context.scope.TraceScope; +import com.navercorp.pinpoint.bootstrap.interceptor.AroundInterceptor; +import com.navercorp.pinpoint.bootstrap.logging.PluginLogManager; +import com.navercorp.pinpoint.bootstrap.logging.PluginLogger; +import com.navercorp.pinpoint.bootstrap.plugin.response.ResponseHeaderRecorderFactory; +import com.navercorp.pinpoint.bootstrap.plugin.response.ServerResponseHeaderRecorder; +import com.navercorp.pinpoint.common.trace.AnnotationKey; +import com.navercorp.pinpoint.common.util.ArrayArgumentUtils; +import com.navercorp.pinpoint.plugin.jdk.http.JdkHttpClientResponseAdaptor; +import com.navercorp.pinpoint.plugin.jdk.http.JdkHttpConstants; + +import java.net.HttpURLConnection; + +public class HttpURLConnectionGetHeaderFieldInterceptor implements AroundInterceptor { + private final PluginLogger logger = PluginLogManager.getLogger(getClass()); + + private final TraceContext traceContext; + private final MethodDescriptor methodDescriptor; + private final ServerResponseHeaderRecorder responseHeaderRecorder; + + public HttpURLConnectionGetHeaderFieldInterceptor(TraceContext traceContext, MethodDescriptor descriptor) { + this.traceContext = traceContext; + this.methodDescriptor = descriptor; + this.responseHeaderRecorder = ResponseHeaderRecorderFactory.newResponseHeaderRecorder(traceContext.getProfilerConfig(), new JdkHttpClientResponseAdaptor()); + } + + @Override + public void before(Object target, Object[] args) { + Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + + if (Boolean.FALSE == isInTraceScope(trace)) { + return; + } + + if (Boolean.FALSE == isResponseCode(args)) { + return; + } + + try { + final SpanEventRecorder recorder = trace.traceBlockBegin(); + recorder.recordServiceType(JdkHttpConstants.SERVICE_TYPE_INTERNAL); + } catch (Throwable th) { + if (logger.isWarnEnabled()) { + logger.warn("BEFORE. Caused:{}", th.getMessage(), th); + } + } + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + + if (Boolean.FALSE == isInTraceScope(trace)) { + return; + } + + if (Boolean.FALSE == isResponseCode(args)) { + return; + } + + try { + final HttpURLConnection request = (HttpURLConnection) target; + final SpanEventRecorder recorder = trace.currentSpanEventRecorder(); + recorder.recordApi(methodDescriptor); + recorder.recordException(throwable); + + if (result instanceof String) { + final String response = (String) result; + if (response.startsWith("HTTP/1.")) { + int statusCode = toStatusCode(response); + if (statusCode > 0) { + recorder.recordAttribute(AnnotationKey.HTTP_STATUS_CODE, statusCode); + } + this.responseHeaderRecorder.recordHeader(recorder, request); + } + } + } catch (Throwable th) { + if (logger.isWarnEnabled()) { + logger.warn("AFTER error. Caused:{}", th.getMessage(), th); + } + } finally { + trace.traceBlockEnd(); + } + } + + private boolean isResponseCode(Object[] args) { + Integer index = ArrayArgumentUtils.getArgument(args, 0, Integer.class); + if (index == null || index != 0) { + return false; + } + + return true; + } + + private boolean isInTraceScope(Trace trace) { + final TraceScope scope = trace.getScope(JdkHttpConstants.TRACE_SCOPE_NAME_GET_INPUT_STREAM); + if (scope != null) { + return scope.isActive(); + } + return false; + } + + private int toStatusCode(String statusLine) { + int index = statusLine.indexOf(' '); + if (index > 0) { + int position = statusLine.indexOf(' ', index + 1); + if (position < 0) + position = statusLine.length(); + + try { + return Integer.parseInt(statusLine.substring(index + 1, position)); + } catch (NumberFormatException ignored) { + } + } + return -1; + } +} \ No newline at end of file diff --git a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpURLConnectionGetInputStreamInterceptor.java b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpURLConnectionGetInputStreamInterceptor.java new file mode 100644 index 000000000000..9f5fc95d312e --- /dev/null +++ b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpURLConnectionGetInputStreamInterceptor.java @@ -0,0 +1,96 @@ +/* + * Copyright 2024 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.navercorp.pinpoint.plugin.jdk.http.interceptor; + +import com.navercorp.pinpoint.bootstrap.context.Trace; +import com.navercorp.pinpoint.bootstrap.context.TraceContext; +import com.navercorp.pinpoint.bootstrap.context.scope.TraceScope; +import com.navercorp.pinpoint.bootstrap.interceptor.AroundInterceptor; +import com.navercorp.pinpoint.bootstrap.logging.PluginLogManager; +import com.navercorp.pinpoint.bootstrap.logging.PluginLogger; +import com.navercorp.pinpoint.bootstrap.util.ScopeUtils; +import com.navercorp.pinpoint.plugin.jdk.http.JdkHttpConstants; + +public class HttpURLConnectionGetInputStreamInterceptor implements AroundInterceptor { + private final PluginLogger logger = PluginLogManager.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private final TraceContext traceContext; + + public HttpURLConnectionGetInputStreamInterceptor(TraceContext traceContext) { + this.traceContext = traceContext; + } + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logger.beforeInterceptor(target, args); + } + + Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + + entryTraceScope(trace); + } + + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + // do not log result + logger.afterInterceptor(target, args); + } + + Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + + leavyTraceScope(trace); + } + + private boolean entryTraceScope(Trace trace) { + TraceScope scope = trace.getScope(JdkHttpConstants.TRACE_SCOPE_NAME_GET_INPUT_STREAM); + if (scope == null) { + trace.addScope(JdkHttpConstants.TRACE_SCOPE_NAME_GET_INPUT_STREAM); + scope = trace.getScope(JdkHttpConstants.TRACE_SCOPE_NAME_GET_INPUT_STREAM); + } + if (scope != null) { + final boolean ok = scope.tryEnter(); + if (!ok) { + if (isDebug) { + logger.debug("Try to startRecording response failed, tryEnter scope failed"); + } + } + return ok; + } else { + if (isDebug) { + logger.debug("Try to startRecording response failed, getOrAdd scope failed"); + } + return false; + } + } + + private void leavyTraceScope(Trace trace) { + if (!ScopeUtils.leaveScope(trace, JdkHttpConstants.TRACE_SCOPE_NAME_GET_INPUT_STREAM)) { + if (isDebug) { + logger.debug("Try to learRecordingResponseStatus failed, canLeave scope returned false"); + } + } + } +} diff --git a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpURLConnectionInterceptor.java b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpURLConnectionInterceptor.java index cb56bf41f0c8..4f7bf0c99fc0 100644 --- a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpURLConnectionInterceptor.java +++ b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpURLConnectionInterceptor.java @@ -19,19 +19,9 @@ import com.navercorp.pinpoint.bootstrap.context.MethodDescriptor; import com.navercorp.pinpoint.bootstrap.context.TraceContext; import com.navercorp.pinpoint.bootstrap.interceptor.scope.InterceptorScope; -import com.navercorp.pinpoint.plugin.jdk.http.ConnectedGetter; public class HttpURLConnectionInterceptor extends AbstractHttpURLConnectionInterceptor { public HttpURLConnectionInterceptor(TraceContext traceContext, MethodDescriptor descriptor, InterceptorScope scope) { super(traceContext, descriptor, scope); } - - @Override - boolean isConnected(Object target) { - if (target instanceof ConnectedGetter) { - final boolean connected = ((ConnectedGetter) target)._$PINPOINT$_isConnected(); - return connected; - } - return false; - } } diff --git a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpURLConnectionPlainConnect0Interceptor.java b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpURLConnectionPlainConnect0Interceptor.java new file mode 100644 index 000000000000..5493920c2782 --- /dev/null +++ b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpURLConnectionPlainConnect0Interceptor.java @@ -0,0 +1,53 @@ +/* + * Copyright 2018 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.navercorp.pinpoint.plugin.jdk.http.interceptor; + +import com.navercorp.pinpoint.bootstrap.context.MethodDescriptor; +import com.navercorp.pinpoint.bootstrap.context.SpanEventRecorder; +import com.navercorp.pinpoint.bootstrap.context.TraceContext; +import com.navercorp.pinpoint.bootstrap.interceptor.SpanEventSimpleAroundInterceptorForPlugin; +import com.navercorp.pinpoint.bootstrap.plugin.request.ClientRequestAdaptor; +import com.navercorp.pinpoint.common.trace.AnnotationKey; +import com.navercorp.pinpoint.plugin.jdk.http.JdkHttpClientRequestAdaptor; +import com.navercorp.pinpoint.plugin.jdk.http.JdkHttpConstants; + +import java.net.HttpURLConnection; + +public class HttpURLConnectionPlainConnect0Interceptor extends SpanEventSimpleAroundInterceptorForPlugin { + + private final ClientRequestAdaptor clientRequestAdaptor = new JdkHttpClientRequestAdaptor(); + + public HttpURLConnectionPlainConnect0Interceptor(TraceContext traceContext, MethodDescriptor descriptor) { + super(traceContext, descriptor); + } + + @Override + public void doInBeforeTrace(SpanEventRecorder recorder, Object target, Object[] args) throws Exception { + recorder.recordApi(methodDescriptor); + recorder.recordServiceType(JdkHttpConstants.SERVICE_TYPE_INTERNAL); + if (target instanceof HttpURLConnection) { + final HttpURLConnection request = (HttpURLConnection) target; + String destinationId = clientRequestAdaptor.getDestinationId(request); + recorder.recordAttribute(AnnotationKey.HTTP_INTERNAL_DISPLAY, destinationId); + } + } + + @Override + public void doInAfterTrace(SpanEventRecorder recorder, Object target, Object[] args, Object result, Throwable throwable) throws Exception { + recorder.recordException(throwable); + } +} diff --git a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpsURLConnectionImplInterceptor.java b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpsURLConnectionImplInterceptor.java index 508c697c3117..190a3c483d91 100644 --- a/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpsURLConnectionImplInterceptor.java +++ b/agent-module/plugins/jdk-http/src/main/java/com/navercorp/pinpoint/plugin/jdk/http/interceptor/HttpsURLConnectionImplInterceptor.java @@ -19,23 +19,10 @@ import com.navercorp.pinpoint.bootstrap.context.MethodDescriptor; import com.navercorp.pinpoint.bootstrap.context.TraceContext; import com.navercorp.pinpoint.bootstrap.interceptor.scope.InterceptorScope; -import com.navercorp.pinpoint.plugin.jdk.http.DelegateGetter; -import sun.net.www.protocol.https.DelegateHttpsURLConnection; public class HttpsURLConnectionImplInterceptor extends AbstractHttpURLConnectionInterceptor { public HttpsURLConnectionImplInterceptor(TraceContext traceContext, MethodDescriptor descriptor, InterceptorScope scope) { super(traceContext, descriptor, scope); } - - @Override - boolean isConnected(final Object target) { - if (target instanceof DelegateGetter) { - DelegateHttpsURLConnection delegateHttpsURLConnection = ((DelegateGetter) target)._$PINPOINT$_getDelegate(); - if (delegateHttpsURLConnection != null) { - return delegateHttpsURLConnection.isConnected(); - } - } - return false; - } } diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/trace/ServiceType.java b/commons/src/main/java/com/navercorp/pinpoint/common/trace/ServiceType.java index 0450036b9bad..a932defee719 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/trace/ServiceType.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/trace/ServiceType.java @@ -251,6 +251,7 @@ * 9063HTTP_CLIENT_5_INTERNAL * 9065JDK_HTTP_CLIENT * 9066JDK_HTTP_CLIENT_INTERNAL + * 9067JDK_HTTPURLCONNECTOR_INTERNAL * 9070RESERVED * 9080APACHE_CXF_CLIENT * 9081APACHE_CXF_SERVICE_INVOKER