You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ta...@apache.org on 2019/05/06 09:15:55 UTC

[skywalking] 01/02: init netty http.

This is an automated email from the ASF dual-hosted git repository.

tanjian pushed a commit to branch webflux_cat_exception
in repository https://gitbox.apache.org/repos/asf/skywalking.git

commit 8e1d41f340e66425251b2d5c981a4e07de6bcf86
Author: Jared.Tan <ji...@daocloud.io>
AuthorDate: Mon May 6 15:43:28 2019 +0800

    init netty http.
---
 .../network/trace/component/ComponentsDefine.java  |  41 +++++----
 apm-sniffer/apm-sdk-plugin/spring-plugins/pom.xml  |   1 +
 .../reactor-netty-http-client-0.8.x-plugin/pom.xml |  42 +++++++++
 .../http/client/DefaultHttpHeadersInterceptor.java |  31 +++++++
 .../HttpClientOperationsHeadersInterceptor.java    |  47 ++++++++++
 .../HttpClientOperationsSendInterceptor.java       |  86 ++++++++++++++++++
 .../HttpClientOperationsStatusInterceptor.java     |  56 ++++++++++++
 .../define/DefaultHttpHeadersInstrumentation.java  |  60 +++++++++++++
 .../HttpClientOperationsInstrumentation.java       | 100 +++++++++++++++++++++
 .../src/main/resources/skywalking-plugin.def       |  20 +++++
 .../src/main/resources/component-libraries.yml     |   3 +
 11 files changed, 468 insertions(+), 19 deletions(-)

diff --git a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java
index 2a31161..bd018b1 100644
--- a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java
+++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java
@@ -64,11 +64,11 @@ public class ComponentsDefine {
 
     public static final OfficialComponent SERVICECOMB = new OfficialComponent(28, "ServiceComb");
 
-    public static final OfficialComponent HYSTRIX =  new OfficialComponent(29, "Hystrix");
+    public static final OfficialComponent HYSTRIX = new OfficialComponent(29, "Hystrix");
 
-    public static final OfficialComponent JEDIS =  new OfficialComponent(30, "Jedis");
+    public static final OfficialComponent JEDIS = new OfficialComponent(30, "Jedis");
 
-    public static final OfficialComponent H2_JDBC_DRIVER =  new OfficialComponent(32, "jdbc-jdbc-driver");
+    public static final OfficialComponent H2_JDBC_DRIVER = new OfficialComponent(32, "jdbc-jdbc-driver");
 
     public static final OfficialComponent MYSQL_JDBC_DRIVER = new OfficialComponent(33, "mysql-connector-java");
 
@@ -90,31 +90,33 @@ public class ComponentsDefine {
 
     public static final OfficialComponent MONGO_DRIVER = new OfficialComponent(42, "mongodb-driver");
 
-    public static final OfficialComponent SOFARPC =  new OfficialComponent(43, "SOFARPC");
+    public static final OfficialComponent SOFARPC = new OfficialComponent(43, "SOFARPC");
 
-    public static final  OfficialComponent ACTIVEMQ_PRODUCER = new OfficialComponent(45,"activemq-producer");
+    public static final OfficialComponent ACTIVEMQ_PRODUCER = new OfficialComponent(45, "activemq-producer");
 
-    public static final  OfficialComponent ACTIVEMQ_CONSUMER = new OfficialComponent(46,"activemq-consumer");
+    public static final OfficialComponent ACTIVEMQ_CONSUMER = new OfficialComponent(46, "activemq-consumer");
 
-    public static final OfficialComponent TRANSPORT_CLIENT =  new OfficialComponent(48, "transport-client");
+    public static final OfficialComponent TRANSPORT_CLIENT = new OfficialComponent(48, "transport-client");
 
-    public static final OfficialComponent UNDERTOW =  new OfficialComponent(49, "Undertow");
+    public static final OfficialComponent UNDERTOW = new OfficialComponent(49, "Undertow");
 
-    public static final OfficialComponent RABBITMQ_PRODUCER = new OfficialComponent(52,"rabbitmq-producer");
+    public static final OfficialComponent RABBITMQ_PRODUCER = new OfficialComponent(52, "rabbitmq-producer");
 
-    public static final OfficialComponent RABBITMQ_CONSUMER = new OfficialComponent(53,"rabbitmq-consumer");
+    public static final OfficialComponent RABBITMQ_CONSUMER = new OfficialComponent(53, "rabbitmq-consumer");
 
-    public static final OfficialComponent CANAL = new OfficialComponent(54,"Canal");
-  
-    public static final OfficialComponent GSON = new OfficialComponent(55,"Gson");
-  
-    public static final OfficialComponent REDISSON =  new OfficialComponent(56, "Redisson");
+    public static final OfficialComponent CANAL = new OfficialComponent(54, "Canal");
 
-    public static final OfficialComponent LETTUCE =  new OfficialComponent(57, "Lettuce");
+    public static final OfficialComponent GSON = new OfficialComponent(55, "Gson");
 
-    public static final OfficialComponent ZOOKEEPER =  new OfficialComponent(58, "Zookeeper");
+    public static final OfficialComponent REDISSON = new OfficialComponent(56, "Redisson");
 
-    public static final OfficialComponent VERTX =  new OfficialComponent(59, "Vert.x");
+    public static final OfficialComponent LETTUCE = new OfficialComponent(57, "Lettuce");
+
+    public static final OfficialComponent ZOOKEEPER = new OfficialComponent(58, "Zookeeper");
+
+    public static final OfficialComponent VERTX = new OfficialComponent(59, "Vert.x");
+
+    public static final OfficialComponent NETTY_HTTP = new OfficialComponent(60, "Netty-Http-Client");
 
     private static ComponentsDefine INSTANCE = new ComponentsDefine();
 
@@ -125,7 +127,7 @@ public class ComponentsDefine {
     }
 
     public ComponentsDefine() {
-        components = new String[60];
+        components = new String[61];
         addComponent(TOMCAT);
         addComponent(HTTPCLIENT);
         addComponent(DUBBO);
@@ -170,6 +172,7 @@ public class ComponentsDefine {
         addComponent(LETTUCE);
         addComponent(ZOOKEEPER);
         addComponent(VERTX);
+        addComponent(NETTY_HTTP);
     }
 
     private void addComponent(OfficialComponent component) {
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/pom.xml b/apm-sniffer/apm-sdk-plugin/spring-plugins/pom.xml
index 070a2fc..1fcd6b9 100644
--- a/apm-sniffer/apm-sdk-plugin/spring-plugins/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/pom.xml
@@ -38,6 +38,7 @@
         <module>spring-commons</module>
         <module>mvc-annotation-5.x-plugin</module>
         <module>webflux-5.x-plugin</module>
+        <module>reactor-netty-http-client-0.8.x-plugin</module>
     </modules>
     <packaging>pom</packaging>
 
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/pom.xml
new file mode 100644
index 0000000..b33a2fe
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/pom.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You 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.
+  -->
+
+<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">
+    <parent>
+        <artifactId>spring-plugins</artifactId>
+        <groupId>org.apache.skywalking</groupId>
+        <version>6.2.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>reactor-netty-http-client-0.8.x-plugin</artifactId>
+    <packaging>jar</packaging>
+
+    <dependencies>
+        <!-- https://mvnrepository.com/artifact/io.projectreactor.netty/reactor-netty -->
+        <dependency>
+            <groupId>io.projectreactor.netty</groupId>
+            <artifactId>reactor-netty</artifactId>
+            <version>0.8.6.RELEASE</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/reactor/netty/http/client/DefaultHttpHeadersInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/reactor/netty/http/client/DefaultHttpHeadersInterceptor.java
new file mode 100644
index 0000000..baf63a4
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/reactor/netty/http/client/DefaultHttpHeadersInterceptor.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.reactor.netty.http.client;
+
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
+
+public class DefaultHttpHeadersInterceptor implements InstanceConstructorInterceptor {
+    @Override
+    public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
+        if (ContextManager.isActive()) {
+            objInst.setSkyWalkingDynamicField(ContextManager.capture());
+        }
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/reactor/netty/http/client/HttpClientOperationsHeadersInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/reactor/netty/http/client/HttpClientOperationsHeadersInterceptor.java
new file mode 100644
index 0000000..a977344
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/reactor/netty/http/client/HttpClientOperationsHeadersInterceptor.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.reactor.netty.http.client;
+
+import java.lang.reflect.Method;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+
+/**
+ * @author zhaoyuguang
+ */
+public class HttpClientOperationsHeadersInterceptor implements InstanceMethodsAroundInterceptor {
+
+    @Override
+    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
+        MethodInterceptResult result) throws Throwable {
+    }
+
+    @Override
+    public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
+        Class<?>[] argumentsTypes, Object ret) throws Throwable {
+        ((EnhancedInstance)ret).setSkyWalkingDynamicField(((EnhancedInstance)allArguments[0]).getSkyWalkingDynamicField());
+        return ret;
+    }
+
+    @Override
+    public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
+        Class<?>[] argumentsTypes, Throwable t) {
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/reactor/netty/http/client/HttpClientOperationsSendInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/reactor/netty/http/client/HttpClientOperationsSendInterceptor.java
new file mode 100644
index 0000000..d316c51
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/reactor/netty/http/client/HttpClientOperationsSendInterceptor.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.reactor.netty.http.client;
+
+import io.netty.handler.codec.http.HttpHeaders;
+import java.lang.reflect.Method;
+import java.net.InetSocketAddress;
+import org.apache.skywalking.apm.agent.core.context.CarrierItem;
+import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
+import org.apache.skywalking.apm.agent.core.context.tag.Tags;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import reactor.netty.channel.ChannelOperations;
+import reactor.netty.http.client.HttpClientRequest;
+
+/**
+ * @author zhaoyuguang
+ */
+public class HttpClientOperationsSendInterceptor implements InstanceMethodsAroundInterceptor {
+
+    @Override
+    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
+        MethodInterceptResult result) throws Throwable {
+        HttpClientRequest request = (HttpClientRequest)objInst;
+        EnhancedInstance instance = (EnhancedInstance)request;
+
+        HttpHeaders header = request.requestHeaders();
+        ChannelOperations channelOpt = (ChannelOperations)objInst;
+        InetSocketAddress remote = (InetSocketAddress)(channelOpt.channel().remoteAddress());
+        String peer = remote.getHostName() + ":" + remote.getPort();
+
+        ContextCarrier contextCarrier = new ContextCarrier();
+        AbstractSpan span = ContextManager.createExitSpan(request.uri(), contextCarrier, peer);
+
+        ContextSnapshot snapshot = (ContextSnapshot)instance.getSkyWalkingDynamicField();
+        if (snapshot != null) {
+            ContextManager.continued((ContextSnapshot)instance.getSkyWalkingDynamicField());
+            ContextManager.inject(contextCarrier);
+        }
+
+        span.setComponent(ComponentsDefine.NETTY_HTTP);
+        Tags.URL.set(span, peer + request.uri());
+        Tags.HTTP.METHOD.set(span, request.method().name());
+        SpanLayer.asHttp(span);
+
+        CarrierItem next = contextCarrier.items();
+        while (next.hasNext()) {
+            next = next.next();
+            header.set(next.getHeadKey(), next.getHeadValue());
+        }
+    }
+
+    @Override
+    public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
+        Class<?>[] argumentsTypes, Object ret) throws Throwable {
+        return ret;
+    }
+
+    @Override
+    public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
+        Class<?>[] argumentsTypes, Throwable t) {
+        ContextManager.activeSpan().errorOccurred().log(t);
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/reactor/netty/http/client/HttpClientOperationsStatusInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/reactor/netty/http/client/HttpClientOperationsStatusInterceptor.java
new file mode 100644
index 0000000..483b306
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/reactor/netty/http/client/HttpClientOperationsStatusInterceptor.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.reactor.netty.http.client;
+
+import io.netty.handler.codec.http.HttpResponseStatus;
+import java.lang.reflect.Method;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.tag.Tags;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+
+/**
+ * @author zhaoyuguang
+ */
+public class HttpClientOperationsStatusInterceptor implements InstanceMethodsAroundInterceptor {
+
+    @Override
+    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
+        MethodInterceptResult result) throws Throwable {
+    }
+
+    @Override
+    public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
+        Object ret) throws Throwable {
+        HttpResponseStatus response = (HttpResponseStatus)ret;
+        if (response.code() > 400) {
+            ContextManager.activeSpan().errorOccurred();
+            Tags.STATUS_CODE.set(ContextManager.activeSpan(), String.valueOf(response.code()));
+        }
+        ContextManager.stopSpan();
+        return ret;
+    }
+
+    @Override
+    public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
+        Class<?>[] argumentsTypes, Throwable t) {
+        ContextManager.activeSpan().errorOccurred().log(t);
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/reactor/netty/http/client/define/DefaultHttpHeadersInstrumentation.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/reactor/netty/http/client/define/DefaultHttpHeadersInstrumentation.java
new file mode 100644
index 0000000..a8eed8e
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/reactor/netty/http/client/define/DefaultHttpHeadersInstrumentation.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.reactor.netty.http.client.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+
+import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType;
+import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
+
+/**
+ * @author zhaoyuguang
+ */
+
+public class DefaultHttpHeadersInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+
+    @Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+        return new ConstructorInterceptPoint[] {
+            new ConstructorInterceptPoint() {
+                @Override public ElementMatcher<MethodDescription> getConstructorMatcher() {
+                    return takesArgumentWithType(0, "io.netty.handler.codec.DefaultHeaders");
+                }
+
+                @Override public String getConstructorInterceptor() {
+                    return "org.apache.skywalking.apm.plugin.reactor.netty.http.client.DefaultHttpHeadersInterceptor";
+                }
+            }
+        };
+    }
+
+    @Override
+    protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+        return new InstanceMethodsInterceptPoint[0];
+    }
+
+    @Override
+    public ClassMatch enhanceClass() {
+        return byName("io.netty.handler.codec.http.DefaultHttpHeaders");
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/reactor/netty/http/client/define/HttpClientOperationsInstrumentation.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/reactor/netty/http/client/define/HttpClientOperationsInstrumentation.java
new file mode 100644
index 0000000..d67ca9f
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/reactor/netty/http/client/define/HttpClientOperationsInstrumentation.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.reactor.netty.http.client.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType;
+import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
+
+/**
+ * @author jian.tan
+ */
+public class HttpClientOperationsInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+
+    private final static String ENHANCE_CLASS = "reactor.netty.http.client.HttpClientOperations";
+
+    @Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+        return new ConstructorInterceptPoint[0];
+    }
+
+    @Override
+    protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+        return new InstanceMethodsInterceptPoint[] {
+            new InstanceMethodsInterceptPoint() {
+                @Override
+                public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                    return named("headers").and(takesArgumentWithType(0, "io.netty.handler.codec.http.HttpHeaders"));
+                }
+
+                @Override
+                public String getMethodsInterceptor() {
+                    return "org.apache.skywalking.apm.plugin.reactor.netty.http.client.HttpClientOperationsHeadersInterceptor";
+                }
+
+                @Override
+                public boolean isOverrideArgs() {
+                    return false;
+                }
+            }, new InstanceMethodsInterceptPoint() {
+                @Override
+                public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                    return named("send").and(takesArgumentWithType(0, "org.reactivestreams.Publisher"));
+                }
+
+                @Override
+                public String getMethodsInterceptor() {
+                    return "org.apache.skywalking.apm.plugin.reactor.netty.http.client.HttpClientOperationsSendInterceptor";
+                }
+
+                @Override
+                public boolean isOverrideArgs() {
+                    return false;
+                }
+            },
+            new InstanceMethodsInterceptPoint() {
+                @Override
+                public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                    return named("status");
+                }
+
+                @Override
+                public String getMethodsInterceptor() {
+                    return "org.apache.skywalking.apm.plugin.reactor.netty.http.client.HttpClientOperationsStatusInterceptor";
+                }
+
+                @Override
+                public boolean isOverrideArgs() {
+                    return false;
+                }
+            },
+        };
+    }
+
+    @Override
+    public ClassMatch enhanceClass() {
+        return byName(ENHANCE_CLASS);
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/resources/skywalking-plugin.def
new file mode 100644
index 0000000..9291dc4
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/reactor-netty-http-client-0.8.x-plugin/src/main/resources/skywalking-plugin.def
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ *
+ */
+
+reactor-netty-http-client-0.8.x-plugin=org.apache.skywalking.apm.plugin.reactor.netty.http.client.define.DefaultHttpHeadersInstrumentation
+reactor-netty-http-client-0.8.x-plugin=org.apache.skywalking.apm.plugin.reactor.netty.http.client.define.HttpClientOperationsInstrumentation
diff --git a/oap-server/server-starter/src/main/resources/component-libraries.yml b/oap-server/server-starter/src/main/resources/component-libraries.yml
index 8759266..10cc621 100644
--- a/oap-server/server-starter/src/main/resources/component-libraries.yml
+++ b/oap-server/server-starter/src/main/resources/component-libraries.yml
@@ -207,6 +207,9 @@ Zookeeper:
 Vertx:
   id: 59
   languages: Java
+Netty-Http-Client:
+  id: 60
+  languages: Java
 
 # .NET/.NET Core components
 # [3000, 4000) for C#/.NET only