Skip to content

Commit

Permalink
[pinpoint-apm#7463] Add Reactor-Netty HTTP client plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
jaehong-kim committed Dec 3, 2020
1 parent e59f2b2 commit 4dadb4c
Show file tree
Hide file tree
Showing 31 changed files with 1,009 additions and 40 deletions.
1 change: 1 addition & 0 deletions agent-testweb/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
<modules>
<module>thread-plugin-testweb</module>
<module>paho-mqtt-plugin-testweb</module>
<module>reactor-netty-plugin-testweb</module>
</modules>


Expand Down
15 changes: 15 additions & 0 deletions agent-testweb/reactor-netty-plugin-testweb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## Install
```
$ mvnw -P pinpoint-reactor-netty-plugin-testweb install -Dmaven.test.skip=true
```

## Run
```
$ mvnw -P pinpoint-reactor-netty-plugin-testweb spring-boot:start
```
You can then access here: http://localhost:18080/client/get

## Stop
```
$ mvnw -P pinpoint-reactor-netty-plugin-testweb spring-boot:stop
```
32 changes: 32 additions & 0 deletions agent-testweb/reactor-netty-plugin-testweb/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.navercorp.pinpoint</groupId>
<artifactId>pinpoint-agent-testweb</artifactId>
<version>2.2.1-SNAPSHOT</version>
</parent>

<artifactId>pinpoint-reactor-netty-plugin-testweb</artifactId>

<packaging>jar</packaging>

<properties>
<pinpoint.agent.jvmargument>
${pinpoint.agent.default.jvmargument}
-Dprofiler.reactor-netty.client.enable=true
-Dprofiler.reactor-netty.client.param=true
</pinpoint.agent.jvmargument>
</properties>

<dependencies>
<dependency>
<groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty</artifactId>
<version>0.9.12.RELEASE</version>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright 2020 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.pinpoint.test.plugin;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import reactor.netty.ByteBufFlux;
import reactor.netty.http.client.HttpClient;
import reactor.netty.http.client.HttpClientResponse;

import javax.servlet.http.HttpServletRequest;

/**
* @author jaehong.kim
*/
@RestController
public class ReactorNettyPluginTestController {

@RequestMapping(value = "/client/echo", method = RequestMethod.GET)
@ResponseBody
public String clientEcho() {
return "Welcome";
}

@RequestMapping(value = "/client/get", method = RequestMethod.GET)
@ResponseBody
public String clientGet() {
HttpClient client = HttpClient.create().port(80);
String response = client.get().uri("https://www.google.com?foo=bar").responseContent().aggregate().asString().block();
return response;
}

@RequestMapping(value = "/client/get_local", method = RequestMethod.GET)
@ResponseBody
public String clientError(HttpServletRequest request) {
HttpClient client = HttpClient.create().port(request.getLocalPort());
String response = client.get().uri("/client/echo").responseContent().aggregate().asString().block();
return response;
}

@RequestMapping(value = "/client/post", method = RequestMethod.GET)
@ResponseBody
public String clientPost() {
HttpClient client = HttpClient.create().port(80);
HttpClientResponse response = client.post().uri("https://www.google.com/").send(ByteBufFlux.fromString(Mono.just("hello"))).response().block();
return response.toString();
}

@RequestMapping(value = "/client/unknown_host", method = RequestMethod.GET)
@ResponseBody
public String clientError() {
HttpClient client = HttpClient.create().port(80);
String response = client.get().uri("http://fjalkjdlfaj.com").responseContent().aggregate().asString().block();
return response;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2020 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.pinpoint.test.plugin;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* @author jaehong.kim
*/
@SpringBootApplication
public class ReactorNettyPluginTestStarter {

public static void main(String[] args) {
SpringApplication.run(ReactorNettyPluginTestStarter.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Defined in commandlineArgument of agent-test pom.xml

server:
port: 18080

#logging:
# level:
# root: info

#springdoc:
# swagger-ui:
# path: /
11 changes: 11 additions & 0 deletions agent/src/main/resources/profiles/local/pinpoint.config
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ profiler.springboot.bootstrap.main=org.springframework.boot.loader.JarLauncher,
###########################################################
profiler.reactor-netty.enable=true

# Server
# Classes for detecting application server type. Comma separated list of fully qualified class names. Wildcard not supported.
profiler.reactor-netty.server.bootstrap.main=
# use an asynchronous endpoint.
Expand All @@ -520,11 +521,19 @@ profiler.reactor-netty.server.excludeurl=
# optional parameter, If the header value is ${profiler.reactor-netty.realipemptyvalue}, Ignore header value.
#profiler.reactor-netty.server.realipemptyvalue=unknown

# Client
profiler.reactor-netty.client.enable=true
# Record Parameter.
profiler.reactor-netty.client.param=true
# Unsupported cookie and entity information

# Set whether to trace the Subscriber.onError(Throwable t) method
profiler.reactor-netty.trace.subscribe.error=true
# Set messages to be excluded from errors. Messages are separated by ',' characters.
profiler.reactor-netty.trace.subscribe.error.exclude.message=



###########################################################
# JSP #
###########################################################
Expand Down Expand Up @@ -917,6 +926,8 @@ profiler.spring.async.executor.class.names=
profiler.spring.webflux.enable=true

# Client
# If you are not using Reactor-Netty, set it to true.
profiler.spring.webflux.client.enable=false
# Record Parameter.
profiler.spring.webflux.client.param=true
# Record cookies.
Expand Down
8 changes: 8 additions & 0 deletions agent/src/main/resources/profiles/release/pinpoint.config
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,12 @@ profiler.reactor-netty.server.excludeurl=
# optional parameter, If the header value is ${profiler.reactor-netty.realipemptyvalue}, Ignore header value.
#profiler.reactor-netty.server.realipemptyvalue=unknown

# Client
profiler.reactor-netty.client.enable=true
# Record Parameter.
profiler.reactor-netty.client.param=true
# Unsupported cookie and entity information

# Set whether to trace the Subscriber.onError(Throwable t) method
profiler.reactor-netty.trace.subscribe.error=true
# Set messages to be excluded from errors. Messages are separated by ',' characters.
Expand Down Expand Up @@ -916,6 +922,8 @@ profiler.spring.async.executor.class.names=
profiler.spring.webflux.enable=true

# Client
# If you are not using Reactor-Netty, set it to true.
profiler.spring.webflux.client.enable=false
# Record Parameter.
profiler.spring.webflux.client.param=true
# Record cookies.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public void after(Object target, Object[] args, Object result, Throwable throwab
logger.afterInterceptor(target, args, result, throwable);
}

final AsyncContext asyncContext = getAsyncContext(target, args);
final AsyncContext asyncContext = getAsyncContext(target, args, result, throwable);
if (asyncContext == null) {
logger.debug("AsyncContext not found");
return;
Expand Down Expand Up @@ -120,11 +120,11 @@ public void after(Object target, Object[] args, Object result, Throwable throwab

protected abstract void doInAfterTrace(SpanEventRecorder recorder, Object target, Object[] args, Object result, Throwable throwable);

protected AsyncContext getAsyncContext(Object target) {
return getAsyncContext(target, null);
protected AsyncContext getAsyncContext(Object target, Object[] args) {
return AsyncContextAccessorUtils.getAsyncContext(target);
}

protected AsyncContext getAsyncContext(Object target, Object[] args) {
protected AsyncContext getAsyncContext(Object target, Object[] args, Object result, Throwable throwable) {
return AsyncContextAccessorUtils.getAsyncContext(target);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@
* <tr><td>9151</td><td>NETTY_INTERNAL</td></tr>
* <tr><td>9152</td><td>NETTY_HTTP</td></tr>
* <tr><td>9153</td><td>SPRING_WEBFLUX_CLIENT</td></tr>
* <tr><td>9154</td><td>REACTOR_NETTY_CLIENT</td></tr>
* <tr><td>9155</td><td>REACTOR_NETTY_CLIENT_INTERNAL</td></tr>
* <tr><td>9160</td><td>GRPC</td></tr>
* <tr><td>9161</td><td>GRPC_INTERNAL</td></tr>
* <tr><td>9162</td><td>GRPC_SERVER_INTERNAL</td></tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public void after(Object target, Object[] args, Object result, Throwable throwab
logger.afterInterceptor(target, args, result, throwable);
}

final AsyncContext asyncContext = getAsyncContext(target);
final AsyncContext asyncContext = getAsyncContext(target, args, result, throwable);
if (asyncContext == null) {
logger.debug("Not found asynchronous invocation metadata");
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ public ServerListenerInterceptor(TraceContext traceContext, MethodDescriptor met
super(traceContext, methodDescriptor);
}

// BEFORE
@Override
protected AsyncContext getAsyncContext(Object target) {
protected AsyncContext getAsyncContext(Object target, Object[] args) {
if (target instanceof AsyncContextAccessor) {
return ((AsyncContextAccessor) target)._$PINPOINT$_getAsyncContext();
}
Expand All @@ -44,13 +45,22 @@ protected AsyncContext getAsyncContext(Object target) {

@Override
protected void doInBeforeTrace(SpanEventRecorder recorder, AsyncContext asyncContext, Object target, Object[] args) {
}

// AFTER
@Override
protected AsyncContext getAsyncContext(Object target, Object[] args, Object result, Throwable throwable) {
if (target instanceof AsyncContextAccessor) {
return ((AsyncContextAccessor) target)._$PINPOINT$_getAsyncContext();
}

logger.info("failed to get AsyncContext");
return null;
}

@Override
protected void doInAfterTrace(SpanEventRecorder recorder, Object target, Object[] args, Object result, Throwable throwable) {
recorder.recordApi(methodDescriptor);
recorder.recordServiceType(GrpcConstants.SERVER_SERVICE_TYPE_INTERNAL);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,30 @@ public HystrixObservableTimeoutListenerTickInterceptor(TraceContext traceContext
traceContext.cacheApi(HYSTRIX_COMMAND_TIMEOUT_TIMER_METHOD_DESCRIPTOR);
}

// BEFORE
@Override
protected AsyncContext getAsyncContext(Object target) {
return getAsyncContext(target, null);
}

@Override
protected AsyncContext getAsyncContext(Object target, Object[] args) {
public AsyncContext getAsyncContext(Object target, Object[] args) {
if (target instanceof EnclosingInstanceAccessor) {
return AsyncContextAccessorUtils.getAsyncContext(((EnclosingInstanceAccessor) target)._$PINPOINT$_getEnclosingInstance());
}
return null;
}

@Override
protected void doInBeforeTrace(SpanEventRecorder recorder, AsyncContext asyncContext, Object target, Object[] args) {
public void doInBeforeTrace(SpanEventRecorder recorder, AsyncContext asyncContext, Object target, Object[] args) {
}

// AFTER
@Override
public AsyncContext getAsyncContext(Object target, Object[] args, Object result, Throwable throwable) {
if (target instanceof EnclosingInstanceAccessor) {
return AsyncContextAccessorUtils.getAsyncContext(((EnclosingInstanceAccessor) target)._$PINPOINT$_getEnclosingInstance());
}
return null;
}

@Override
protected void doInAfterTrace(SpanEventRecorder recorder, Object target, Object[] args, Object result, Throwable throwable) {
public void doInAfterTrace(SpanEventRecorder recorder, Object target, Object[] args, Object result, Throwable throwable) {
recorder.recordServiceType(HystrixPluginConstants.HYSTRIX_INTERNAL_SERVICE_TYPE);
recorder.recordApi(HYSTRIX_COMMAND_TIMEOUT_TIMER_METHOD_DESCRIPTOR);
recorder.recordException(throwable);
Expand Down
11 changes: 10 additions & 1 deletion plugins/reactor-netty/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
## Reactor Netty
* Version: 1.0
* Version: 1.1
* Since: Pinpoint 2.0.0
* See: https://github.com/reactor/reactor-netty
* See: [Project Reactor](https://projectreactor.io/)
Expand Down Expand Up @@ -34,6 +34,12 @@ profiler.reactor-netty.server.excludeurl=
#profiler.reactor-netty.server.realipheader=X-Real-IP
# optional parameter, If the header value is ${profiler.reactor-netty.realipemptyvalue}, Ignore header value.
#profiler.reactor-netty.server.realipemptyvalue=unknown
# Client
profiler.reactor-netty.client.enable=true
# Record Parameter.
profiler.reactor-netty.client.param=true
# Unsupported cookie and entity information
~~~

If you use Spring boot starter, if you set main class as profiler.spring boot.bootstrap.main setting value.
Expand All @@ -44,3 +50,6 @@ profiler.springboot.bootstrap.main=foo.bar.SampleApplication

### Web Server
* Netty(Reactor Netty) HTTP Server

### HTTP Client
* Netty(Reactor Netty) HTTP Client
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@
public class ReactorNettyConstants {
public static final ServiceType REACTOR_NETTY = ServiceTypeProvider.getByName("REACTOR_NETTY");
public static final ServiceType REACTOR_NETTY_INTERNAL = ServiceTypeProvider.getByName("REACTOR_NETTY_INTERNAL");
public static final ServiceType REACTOR_NETTY_CLIENT = ServiceTypeProvider.getByName("REACTOR_NETTY_CLIENT");
public static final ServiceType REACTOR_NETTY_CLIENT_INTERNAL = ServiceTypeProvider.getByName("REACTOR_NETTY_CLIENT_INTERNAL");
}
Loading

0 comments on commit 4dadb4c

Please sign in to comment.