Add sofa rpc plugin integration (#1210)
* sofa rpc integration * remove unused class and method,add component defination * only support after sofa rpc 5.4.0 * set sofarpc componentId be 32 * Add document of component library settings and incuating features abstract. (#1185) * sofa rpc integration * Update UI licenses (#1189) * Update UI licenses for beta version * Update FAQ doc (#1184) * update faq doc * update faq * update faq * Update readme for beta release. (#1191) * New english readme. * New chinese readme. * Fix #1186 Webapp read timeout config (#1192) * Updat ui (#1197) * Change the intercept point of block call way (#1190) * Change the buired point of block call way * Support future way and change the operation name of span * Update screenshot for new release. (#1209) * remove unused class and method,add component defination * only support after sofa rpc 5.4.0 * set sofarpc componentId be 32 * sofa rpc integration * remove unused class and method,add component defination * only support after sofa rpc 5.4.0 * set sofarpc componentId be 32 * sofa rpc integration * remove unused class and method,add component defination * change parent pom version * remove unused dependency
This commit is contained in:
parent
7c305fe00c
commit
c4766ecbf2
|
|
@ -153,6 +153,9 @@ kafka-consumer:
|
|||
mongodb-driver:
|
||||
id: 42
|
||||
languages: Java
|
||||
SOFARPC:
|
||||
id: 43
|
||||
languages: Java
|
||||
|
||||
# .NET/.NET Core components
|
||||
# [3000, 4000) for C#/.NET only
|
||||
|
|
|
|||
|
|
@ -124,6 +124,9 @@ Hystrix:
|
|||
Jedis:
|
||||
id: 30
|
||||
languages: Java
|
||||
SOFARPC:
|
||||
id: 43
|
||||
languages: Java
|
||||
|
||||
|
||||
# Component Server mapping defines the server display names of some components
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ public class ComponentsDefine {
|
|||
public static final OfficialComponent GRPC = new OfficialComponent(23, "GRPC");
|
||||
|
||||
public static final OfficialComponent ELASTIC_JOB = new OfficialComponent(24, "ElasticJob");
|
||||
|
||||
|
||||
public static final OfficialComponent HTTP_ASYNC_CLIENT = new OfficialComponent(26, "httpasyncclient");
|
||||
|
||||
public static final OfficialComponent SERVICECOMB = new OfficialComponent(28, "ServiceComb");
|
||||
|
|
@ -90,6 +90,8 @@ public class ComponentsDefine {
|
|||
|
||||
public static final OfficialComponent MONGO_DRIVER = new OfficialComponent(42, "mongodb-driver");
|
||||
|
||||
public static final OfficialComponent SOFARPC = new OfficialComponent(43, "SOFARPC");
|
||||
|
||||
private static ComponentsDefine INSTANCE = new ComponentsDefine();
|
||||
|
||||
private String[] components;
|
||||
|
|
@ -99,7 +101,7 @@ public class ComponentsDefine {
|
|||
}
|
||||
|
||||
public ComponentsDefine() {
|
||||
components = new String[43];
|
||||
components = new String[44];
|
||||
addComponent(TOMCAT);
|
||||
addComponent(HTTPCLIENT);
|
||||
addComponent(DUBBO);
|
||||
|
|
@ -132,6 +134,7 @@ public class ComponentsDefine {
|
|||
addComponent(KAFKA_PRODUCER);
|
||||
addComponent(KAFKA_CONSUMER);
|
||||
addComponent(MONGO_DRIVER);
|
||||
addComponent(SOFARPC);
|
||||
}
|
||||
|
||||
private void addComponent(OfficialComponent component) {
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
<module>kafka-v1-plugin</module>
|
||||
<module>servicecomb-plugin</module>
|
||||
<module>hystrix-1.x-plugin</module>
|
||||
<module>sofarpc-plugin</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
<!--
|
||||
~ 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>apm-sdk-plugin</artifactId>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<version>5.0.0-beta2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>sofa-rpc-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>sofarpc-plugin</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alipay.sofa</groupId>
|
||||
<artifactId>sofa-rpc-all</artifactId>
|
||||
<version>5.4.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!-- 源码插件 -->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<!-- 发布时自动将源码同时发布的配置 -->
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<phase>none</phase>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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.sofarpc;
|
||||
|
||||
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 org.apache.skywalking.apm.agent.core.plugin.match.NameMatch;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
||||
public class SofaRpcConsumerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
|
||||
private static final String ENHANCE_CLASS = "com.alipay.sofa.rpc.filter.ConsumerInvoker";
|
||||
private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.sofarpc.SofaRpcConsumerInterceptor";
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
return NameMatch.byName(ENHANCE_CLASS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[] {
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named("invoke");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return INTERCEPT_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* 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.sofarpc;
|
||||
|
||||
import com.alipay.sofa.rpc.client.ProviderInfo;
|
||||
import com.alipay.sofa.rpc.context.RpcInternalContext;
|
||||
import com.alipay.sofa.rpc.core.request.SofaRequest;
|
||||
import com.alipay.sofa.rpc.core.response.SofaResponse;
|
||||
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.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 java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* @author leizhiyuan
|
||||
*/
|
||||
public class SofaRpcConsumerInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
|
||||
public static final String SKYWALKING_PREFIX = "skywalking.";
|
||||
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
|
||||
SofaRequest sofaRequest = (SofaRequest) allArguments[0];
|
||||
RpcInternalContext rpcContext = RpcInternalContext.getContext();
|
||||
|
||||
ProviderInfo providerInfo = rpcContext.getProviderInfo();
|
||||
|
||||
AbstractSpan span = null;
|
||||
|
||||
final String host = providerInfo.getHost();
|
||||
final int port = providerInfo.getPort();
|
||||
final ContextCarrier contextCarrier = new ContextCarrier();
|
||||
final String operationName = generateOperationName(providerInfo, sofaRequest);
|
||||
span = ContextManager.createExitSpan(operationName, contextCarrier, host + ":" + port);
|
||||
CarrierItem next = contextCarrier.items();
|
||||
while (next.hasNext()) {
|
||||
next = next.next();
|
||||
String key = next.getHeadKey();
|
||||
String skyWalkingKey = SKYWALKING_PREFIX + key;
|
||||
sofaRequest.addRequestProp(skyWalkingKey, next.getHeadValue());
|
||||
}
|
||||
|
||||
Tags.URL.set(span, generateRequestURL(providerInfo, sofaRequest));
|
||||
span.setComponent(ComponentsDefine.SOFARPC);
|
||||
SpanLayer.asRPCFramework(span);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Object ret) throws Throwable {
|
||||
SofaResponse result = (SofaResponse) ret;
|
||||
if (result != null && result.isError()) {
|
||||
dealException((Throwable) result.getAppResponse());
|
||||
}
|
||||
|
||||
ContextManager.stopSpan();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Throwable t) {
|
||||
dealException(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the throwable, which occurs in Dubbo RPC service.
|
||||
*/
|
||||
private void dealException(Throwable throwable) {
|
||||
AbstractSpan span = ContextManager.activeSpan();
|
||||
span.errorOccurred();
|
||||
span.log(throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format operation name. e.g. org.apache.skywalking.apm.plugin.test.Test.test(String)
|
||||
*
|
||||
* @return operation name.
|
||||
*/
|
||||
private String generateOperationName(ProviderInfo providerInfo, SofaRequest sofaRequest) {
|
||||
StringBuilder operationName = new StringBuilder();
|
||||
operationName.append(sofaRequest.getInterfaceName());
|
||||
operationName.append("." + sofaRequest.getMethodName() + "(");
|
||||
for (String arg : sofaRequest.getMethodArgSigs()) {
|
||||
operationName.append(arg + ",");
|
||||
}
|
||||
|
||||
if (sofaRequest.getMethodArgs().length > 0) {
|
||||
operationName.delete(operationName.length() - 1, operationName.length());
|
||||
}
|
||||
|
||||
operationName.append(")");
|
||||
|
||||
return operationName.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Format request url.
|
||||
* e.g. bolt://127.0.0.1:20880/org.apache.skywalking.apm.plugin.test.Test.test(String).
|
||||
*
|
||||
* @return request url.
|
||||
*/
|
||||
private String generateRequestURL(ProviderInfo providerInfo, SofaRequest sofaRequest) {
|
||||
StringBuilder requestURL = new StringBuilder();
|
||||
requestURL.append(providerInfo.getProtocolType() + "://");
|
||||
requestURL.append(providerInfo.getHost());
|
||||
requestURL.append(":" + providerInfo.getPort() + "/");
|
||||
requestURL.append(generateOperationName(providerInfo, sofaRequest));
|
||||
return requestURL.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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.sofarpc;
|
||||
|
||||
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 org.apache.skywalking.apm.agent.core.plugin.match.NameMatch;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
||||
public class SofaRpcProviderInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
|
||||
private static final String ENHANCE_CLASS = "com.alipay.sofa.rpc.filter.ProviderInvoker";
|
||||
private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.sofarpc.SofaRpcProviderInterceptor";
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
return NameMatch.byName(ENHANCE_CLASS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[] {
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named("invoke");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return INTERCEPT_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* 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.sofarpc;
|
||||
|
||||
import com.alipay.sofa.rpc.core.request.SofaRequest;
|
||||
import com.alipay.sofa.rpc.core.response.SofaResponse;
|
||||
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.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 java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* @author leizhiyuan
|
||||
*/
|
||||
public class SofaRpcProviderInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
|
||||
public static final String SKYWALKING_PREFIX = "skywalking.";
|
||||
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
|
||||
SofaRequest sofaRequest = (SofaRequest) allArguments[0];
|
||||
|
||||
AbstractSpan span = null;
|
||||
|
||||
ContextCarrier contextCarrier = new ContextCarrier();
|
||||
CarrierItem next = contextCarrier.items();
|
||||
while (next.hasNext()) {
|
||||
next = next.next();
|
||||
final String headKey = next.getHeadKey();
|
||||
final Object attachment = sofaRequest.getRequestProp(SKYWALKING_PREFIX + headKey);
|
||||
if (attachment != null) {
|
||||
next.setHeadValue(attachment.toString());
|
||||
} else {
|
||||
next.setHeadValue("");
|
||||
}
|
||||
}
|
||||
span = ContextManager.createEntrySpan(generateViewPoint(sofaRequest), contextCarrier);
|
||||
|
||||
span.setComponent(ComponentsDefine.SOFARPC);
|
||||
SpanLayer.asRPCFramework(span);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Object ret) throws Throwable {
|
||||
SofaResponse result = (SofaResponse) ret;
|
||||
if (result != null && result.isError()) {
|
||||
dealException((Throwable) result.getAppResponse());
|
||||
}
|
||||
|
||||
ContextManager.stopSpan();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Throwable t) {
|
||||
dealException(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the throwable, which occurs in Dubbo RPC service.
|
||||
*/
|
||||
private void dealException(Throwable throwable) {
|
||||
AbstractSpan span = ContextManager.activeSpan();
|
||||
span.errorOccurred();
|
||||
span.log(throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format operation name. e.g. org.apache.skywalking.apm.plugin.test.Test.test(String)
|
||||
*
|
||||
* @return operation name.
|
||||
*/
|
||||
private String generateViewPoint(SofaRequest sofaRequest) {
|
||||
StringBuilder operationName = new StringBuilder();
|
||||
operationName.append(sofaRequest.getInterfaceName());
|
||||
operationName.append("." + sofaRequest.getMethodName() + "(");
|
||||
for (String arg : sofaRequest.getMethodArgSigs()) {
|
||||
operationName.append(arg + ",");
|
||||
}
|
||||
|
||||
if (sofaRequest.getMethodArgs().length > 0) {
|
||||
operationName.delete(operationName.length() - 1, operationName.length());
|
||||
}
|
||||
|
||||
operationName.append(")");
|
||||
|
||||
return operationName.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# 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.
|
||||
|
||||
sofarpc=org.apache.skywalking.apm.plugin.sofarpc.SofaRpcConsumerInstrumentation
|
||||
sofarpc=org.apache.skywalking.apm.plugin.sofarpc.SofaRpcProviderInstrumentation
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* 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.sofarpc;
|
||||
|
||||
import com.alipay.sofa.rpc.client.ProviderInfo;
|
||||
import com.alipay.sofa.rpc.context.RpcInternalContext;
|
||||
import com.alipay.sofa.rpc.core.request.SofaRequest;
|
||||
import com.alipay.sofa.rpc.core.response.SofaResponse;
|
||||
import com.alipay.sofa.rpc.filter.ConsumerInvoker;
|
||||
import org.apache.skywalking.apm.agent.core.conf.Config;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.*;
|
||||
import org.apache.skywalking.apm.agent.core.context.util.KeyValuePair;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
|
||||
import org.apache.skywalking.apm.agent.test.helper.SegmentHelper;
|
||||
import org.apache.skywalking.apm.agent.test.helper.SpanHelper;
|
||||
import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule;
|
||||
import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
|
||||
import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
|
||||
import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.powermock.api.mockito.PowerMockito.when;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PowerMockRunnerDelegate(TracingSegmentRunner.class)
|
||||
@PrepareForTest({RpcInternalContext.class, SofaRequest.class, SofaResponse.class})
|
||||
public class SofaRpcConsumerInterceptorTest {
|
||||
|
||||
@SegmentStoragePoint
|
||||
private SegmentStorage segmentStorage;
|
||||
|
||||
@Rule
|
||||
public AgentServiceRule agentServiceRule = new AgentServiceRule();
|
||||
|
||||
@Mock
|
||||
private EnhancedInstance enhancedInstance;
|
||||
|
||||
private SofaRpcConsumerInterceptor sofaRpcConsumerInterceptor;
|
||||
|
||||
@Mock
|
||||
private RpcInternalContext rpcContext;
|
||||
|
||||
@Mock
|
||||
private ConsumerInvoker invoker;
|
||||
|
||||
private SofaRequest sofaRequest = PowerMockito.mock(SofaRequest.class);
|
||||
@Mock
|
||||
private MethodInterceptResult methodInterceptResult;
|
||||
|
||||
private SofaResponse sofaResponse = PowerMockito.mock(SofaResponse.class);
|
||||
|
||||
private Object[] allArguments;
|
||||
private Class[] argumentTypes;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
sofaRpcConsumerInterceptor = new SofaRpcConsumerInterceptor();
|
||||
|
||||
PowerMockito.mockStatic(RpcInternalContext.class);
|
||||
|
||||
when(sofaRequest.getMethodName()).thenReturn("test");
|
||||
when(sofaRequest.getMethodArgSigs()).thenReturn(new String[] {"String"});
|
||||
when(sofaRequest.getMethodArgs()).thenReturn(new Object[] {"abc"});
|
||||
when(sofaRequest.getInterfaceName()).thenReturn("org.apache.skywalking.apm.test.TestSofaRpcService");
|
||||
PowerMockito.when(RpcInternalContext.getContext()).thenReturn(rpcContext);
|
||||
when(rpcContext.isConsumerSide()).thenReturn(true);
|
||||
final ProviderInfo providerInfo = new ProviderInfo();
|
||||
providerInfo.setHost("127.0.0.1");
|
||||
providerInfo.setPort(12200);
|
||||
when(rpcContext.getProviderInfo()).thenReturn(providerInfo);
|
||||
allArguments = new Object[] {sofaRequest};
|
||||
argumentTypes = new Class[] {sofaRequest.getClass()};
|
||||
Config.Agent.APPLICATION_CODE = "SOFARPC-TestCases-APP";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConsumerWithAttachment() throws Throwable {
|
||||
sofaRpcConsumerInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult);
|
||||
sofaRpcConsumerInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, sofaResponse);
|
||||
|
||||
assertThat(segmentStorage.getTraceSegments().size(), is(1));
|
||||
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
|
||||
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
|
||||
assertThat(spans.size(), is(1));
|
||||
assertConsumerSpan(spans.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConsumerWithException() throws Throwable {
|
||||
sofaRpcConsumerInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult);
|
||||
sofaRpcConsumerInterceptor.handleMethodException(enhancedInstance, null, allArguments, argumentTypes, new RuntimeException());
|
||||
sofaRpcConsumerInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, sofaResponse);
|
||||
assertThat(segmentStorage.getTraceSegments().size(), is(1));
|
||||
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
|
||||
assertConsumerTraceSegmentInErrorCase(traceSegment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConsumerWithResultHasException() throws Throwable {
|
||||
when(sofaResponse.isError()).thenReturn(true);
|
||||
when(sofaResponse.getAppResponse()).thenReturn(new RuntimeException());
|
||||
|
||||
sofaRpcConsumerInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult);
|
||||
sofaRpcConsumerInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, sofaResponse);
|
||||
|
||||
assertThat(segmentStorage.getTraceSegments().size(), is(1));
|
||||
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
|
||||
assertConsumerTraceSegmentInErrorCase(traceSegment);
|
||||
}
|
||||
|
||||
private void assertConsumerTraceSegmentInErrorCase(
|
||||
TraceSegment traceSegment) {
|
||||
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
|
||||
assertThat(spans.size(), is(1));
|
||||
assertConsumerSpan(spans.get(0));
|
||||
AbstractTracingSpan span = spans.get(0);
|
||||
assertThat(SpanHelper.getLogs(span).size(), is(1));
|
||||
assertErrorLog(SpanHelper.getLogs(span).get(0));
|
||||
}
|
||||
|
||||
private void assertErrorLog(LogDataEntity logData) {
|
||||
assertThat(logData.getLogs().size(), is(4));
|
||||
assertThat(logData.getLogs().get(0).getValue(), CoreMatchers.<Object>is("error"));
|
||||
assertThat(logData.getLogs().get(1).getValue(), CoreMatchers.<Object>is(RuntimeException.class.getName()));
|
||||
assertNull(logData.getLogs().get(2).getValue());
|
||||
}
|
||||
|
||||
private void assertConsumerSpan(AbstractTracingSpan span) {
|
||||
assertCommonsAttribute(span);
|
||||
assertTrue(span.isExit());
|
||||
}
|
||||
|
||||
private void assertCommonsAttribute(AbstractTracingSpan span) {
|
||||
List<KeyValuePair> tags = SpanHelper.getTags(span);
|
||||
assertThat(tags.size(), is(1));
|
||||
assertThat(SpanHelper.getLayer(span), CoreMatchers.is(SpanLayer.RPC_FRAMEWORK));
|
||||
assertThat(SpanHelper.getComponentId(span), is(43));
|
||||
assertThat(tags.get(0).getValue(), is("bolt://127.0.0.1:12200/org.apache.skywalking.apm.test.TestSofaRpcService.test(String)"));
|
||||
assertThat(span.getOperationName(), is("org.apache.skywalking.apm.test.TestSofaRpcService.test(String)"));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* 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.sofarpc;
|
||||
|
||||
import com.alipay.sofa.rpc.client.ProviderInfo;
|
||||
import com.alipay.sofa.rpc.context.RpcInternalContext;
|
||||
import com.alipay.sofa.rpc.core.request.SofaRequest;
|
||||
import com.alipay.sofa.rpc.core.response.SofaResponse;
|
||||
import com.alipay.sofa.rpc.filter.ProviderInvoker;
|
||||
import org.apache.skywalking.apm.agent.core.conf.Config;
|
||||
import org.apache.skywalking.apm.agent.core.context.SW3CarrierItem;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.TraceSegmentRef;
|
||||
import org.apache.skywalking.apm.agent.core.context.util.KeyValuePair;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
|
||||
import org.apache.skywalking.apm.agent.test.helper.SegmentHelper;
|
||||
import org.apache.skywalking.apm.agent.test.helper.SegmentRefHelper;
|
||||
import org.apache.skywalking.apm.agent.test.helper.SpanHelper;
|
||||
import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule;
|
||||
import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
|
||||
import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
|
||||
import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.powermock.api.mockito.PowerMockito.when;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PowerMockRunnerDelegate(TracingSegmentRunner.class)
|
||||
@PrepareForTest({RpcInternalContext.class, SofaRequest.class, SofaResponse.class})
|
||||
public class SofaRpcProviderInterceptorTest {
|
||||
|
||||
public static final String SKYWALKING_PREFIX = "skywalking.";
|
||||
|
||||
@SegmentStoragePoint
|
||||
private SegmentStorage segmentStorage;
|
||||
|
||||
@Rule
|
||||
public AgentServiceRule agentServiceRule = new AgentServiceRule();
|
||||
|
||||
@Mock
|
||||
private EnhancedInstance enhancedInstance;
|
||||
|
||||
private SofaRpcProviderInterceptor sofaRpcProviderInterceptor;
|
||||
|
||||
@Mock
|
||||
private RpcInternalContext rpcContext;
|
||||
|
||||
@Mock
|
||||
private ProviderInvoker invoker;
|
||||
|
||||
private SofaRequest sofaRequest = PowerMockito.mock(SofaRequest.class);
|
||||
@Mock
|
||||
private MethodInterceptResult methodInterceptResult;
|
||||
|
||||
private SofaResponse sofaResponse = PowerMockito.mock(SofaResponse.class);
|
||||
|
||||
private Object[] allArguments;
|
||||
private Class[] argumentTypes;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
sofaRpcProviderInterceptor = new SofaRpcProviderInterceptor();
|
||||
|
||||
PowerMockito.mockStatic(RpcInternalContext.class);
|
||||
|
||||
when(sofaRequest.getMethodName()).thenReturn("test");
|
||||
when(sofaRequest.getMethodArgSigs()).thenReturn(new String[] {"String"});
|
||||
when(sofaRequest.getMethodArgs()).thenReturn(new Object[] {"abc"});
|
||||
when(sofaRequest.getInterfaceName()).thenReturn("org.apache.skywalking.apm.test.TestSofaRpcService");
|
||||
PowerMockito.when(RpcInternalContext.getContext()).thenReturn(rpcContext);
|
||||
when(rpcContext.isConsumerSide()).thenReturn(false);
|
||||
final ProviderInfo providerInfo = new ProviderInfo();
|
||||
providerInfo.setHost("127.0.0.1");
|
||||
providerInfo.setPort(12200);
|
||||
when(rpcContext.getProviderInfo()).thenReturn(providerInfo);
|
||||
allArguments = new Object[] {sofaRequest};
|
||||
argumentTypes = new Class[] {sofaRequest.getClass()};
|
||||
Config.Agent.APPLICATION_CODE = "SOFARPC-TestCases-APP";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProviderWithAttachment() throws Throwable {
|
||||
when(rpcContext.isConsumerSide()).thenReturn(false);
|
||||
when(sofaRequest.getRequestProp(SKYWALKING_PREFIX + SW3CarrierItem.HEADER_NAME)).thenReturn(
|
||||
"1.323.4433|3|1|1|#192.168.1.8 :18002|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
|
||||
|
||||
sofaRpcProviderInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult);
|
||||
sofaRpcProviderInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, sofaResponse);
|
||||
assertProvider();
|
||||
}
|
||||
|
||||
private void assertProvider() {
|
||||
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
|
||||
assertThat(SegmentHelper.getSpans(traceSegment).size(), is(1));
|
||||
assertProviderSpan(SegmentHelper.getSpans(traceSegment).get(0));
|
||||
assertTraceSegmentRef(traceSegment.getRefs().get(0));
|
||||
}
|
||||
|
||||
private void assertTraceSegmentRef(TraceSegmentRef actual) {
|
||||
assertThat(SegmentRefHelper.getSpanId(actual), is(3));
|
||||
assertThat(SegmentRefHelper.getEntryApplicationInstanceId(actual), is(1));
|
||||
assertThat(SegmentRefHelper.getTraceSegmentId(actual).toString(), is("1.323.4433"));
|
||||
}
|
||||
|
||||
private void assertProviderSpan(AbstractTracingSpan span) {
|
||||
assertCommonsAttribute(span);
|
||||
assertTrue(span.isEntry());
|
||||
}
|
||||
|
||||
private void assertCommonsAttribute(AbstractTracingSpan span) {
|
||||
List<KeyValuePair> tags = SpanHelper.getTags(span);
|
||||
assertThat(tags.size(), is(0));
|
||||
assertThat(SpanHelper.getLayer(span), CoreMatchers.is(SpanLayer.RPC_FRAMEWORK));
|
||||
assertThat(SpanHelper.getComponentId(span), is(43));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue