提交 13cf3247 编写于 作者: IluckySi's avatar IluckySi

Support XMemcached V2.x

上级 b396c99e
...@@ -153,6 +153,11 @@ ...@@ -153,6 +153,11 @@
<artifactId>apm-sharding-jdbc-1.5.x-plugin</artifactId> <artifactId>apm-sharding-jdbc-1.5.x-plugin</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-xmemcached-2.x-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<!-- activation --> <!-- activation -->
<dependency> <dependency>
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
<module>jetty-plugin</module> <module>jetty-plugin</module>
<module>spymemcached-2.x-plugin</module> <module>spymemcached-2.x-plugin</module>
<module>sharding-jdbc-1.5.x-plugin</module> <module>sharding-jdbc-1.5.x-plugin</module>
<module>xmemcached-2.x-plugin</module>
</modules> </modules>
<packaging>pom</packaging> <packaging>pom</packaging>
......
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2017, OpenSkywalking Organization All rights reserved.
~
~ 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.
~
~ Project repository: https://github.com/OpenSkywalking/skywalking
-->
<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>org.skywalking</groupId>
<artifactId>apm-sdk-plugin</artifactId>
<version>3.2.3-2017</version>
</parent>
<artifactId>apm-xmemcached-2.x-plugin</artifactId>
<name>xmemcached-2.x-plugin</name>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<xmemcached.version>2.0.0</xmemcached.version>
</properties>
<dependencies>
<dependency>
<groupId>com.googlecode.xmemcached</groupId>
<artifactId>xmemcached</artifactId>
<version>${xmemcached.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.4.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.xmemcached.v2;
import java.net.InetSocketAddress;
import java.util.Map;
import java.util.Map.Entry;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
public class XMemcachedConstructorWithComplexArgInterceptor implements InstanceConstructorInterceptor {
@Override
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
StringBuilder memcachConnInfo = new StringBuilder();
@SuppressWarnings("unchecked")
Map<InetSocketAddress, InetSocketAddress> inetSocketAddressMap = (Map<InetSocketAddress, InetSocketAddress>)allArguments[6];
StringBuilder master = new StringBuilder();
for (Entry<InetSocketAddress, InetSocketAddress> entry : inetSocketAddressMap.entrySet()) {
if (master.length() <= 0) {
master = append(master,entry.getKey());
}
memcachConnInfo = append(memcachConnInfo, entry.getValue());
}
memcachConnInfo = master.append(memcachConnInfo);
int l = memcachConnInfo.length();
if (l > 1) {
memcachConnInfo = new StringBuilder(memcachConnInfo.substring(0, l - 1));
}
objInst.setSkyWalkingDynamicField(memcachConnInfo.toString());
}
/**
* Parse InetSocketAddress
* @param sb
* @param inetSocketAddress
* @return
*/
private StringBuilder append(StringBuilder sb, InetSocketAddress inetSocketAddress) {
if (inetSocketAddress != null) {
String host = inetSocketAddress.getAddress().getHostAddress();
int port = inetSocketAddress.getPort();
sb.append(host).append(":").append(port).append(";");
}
return sb;
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.xmemcached.v2;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
public class XMemcachedConstructorWithHostPortArgInterceptor implements InstanceConstructorInterceptor {
@Override
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
Object host = allArguments[0];
Object port = allArguments[1];
objInst.setSkyWalkingDynamicField(host + ":" + port);
}
}
\ No newline at end of file
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.xmemcached.v2;
import java.net.InetSocketAddress;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
public class XMemcachedConstructorWithInetSocketAddressArgInterceptor implements InstanceConstructorInterceptor {
@Override
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
InetSocketAddress inetSocketAddress = (InetSocketAddress)allArguments[0];
String host = inetSocketAddress.getAddress().getHostAddress();
int port = inetSocketAddress.getPort();
objInst.setSkyWalkingDynamicField(host + ":" + port);
}
}
\ No newline at end of file
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.xmemcached.v2;
import java.net.InetSocketAddress;
import java.util.List;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
public class XMemcachedConstructorWithInetSocketAddressListArgInterceptor implements InstanceConstructorInterceptor {
@Override
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
StringBuilder memcachConnInfo = new StringBuilder();
@SuppressWarnings("unchecked")
List<InetSocketAddress> inetSocketAddressList = (List<InetSocketAddress>)allArguments[0];
for (InetSocketAddress inetSocketAddress : inetSocketAddressList) {
String host = inetSocketAddress.getAddress().getHostAddress();
int port = inetSocketAddress.getPort();
memcachConnInfo.append(host).append(":").append(port).append(";");
}
int l = memcachConnInfo.length();
if (l > 1) {
memcachConnInfo = new StringBuilder(memcachConnInfo.substring(0, l - 1));
}
objInst.setSkyWalkingDynamicField(memcachConnInfo.toString());
}
}
\ No newline at end of file
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.xmemcached.v2;
import java.lang.reflect.Method;
import org.skywalking.apm.agent.core.context.ContextManager;
import org.skywalking.apm.agent.core.context.tag.Tags;
import org.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.skywalking.apm.network.trace.component.ComponentsDefine;
public class XMemcachedMethodInterceptor implements InstanceMethodsAroundInterceptor {
private static final String XMEMCACHED = "XMemcached/";
@Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
String peer = String.valueOf(objInst.getSkyWalkingDynamicField());
AbstractSpan span = ContextManager.createExitSpan(XMEMCACHED + method.getName(), peer);
span.setComponent(ComponentsDefine.MEMCACHE);
Tags.DB_TYPE.set(span, ComponentsDefine.MEMCACHE.getName());
SpanLayer.asDB(span);
Tags.DB_STATEMENT.set(span, method.getName() + " " + allArguments[0]);
}
@Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Object ret) throws Throwable {
ContextManager.stopSpan();
return ret;
}
@Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
AbstractSpan span = ContextManager.activeSpan();
span.errorOccurred();
span.log(t);
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.xmemcached.v2.define;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.Map;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
/**
* {@link MemcachedInstrumentation} presents that skywalking intercept all constructors and methods of
* {@link net.rubyeye.xmemcached.XMemcachedClient}.
* {@link XMemcachedConstructorWithHostPortArgInterceptor} intercepts the constructor with
* ip and port arguments.
* {@link XMemcachedConstructorWithInetSocketAddressArgInterceptor} intercepts the constructor with
* argument {@link java.net.InetSocketAddress}.
* {@link XMemcachedConstructorWithInetSocketAddressListArgInterceptor} intercepts the constructor with
* argument {@link java.net.InetSocketAddress}.
* {@link XMemcachedConstructorWithComplexArgInterceptor} intercepts the constructor with complex arguments.
*
* @author IluckySi
*/
public class XMemcachedInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String ENHANCE_CLASS = "net.rubyeye.xmemcached.XMemcachedClient";
private static final String CONSTRUCTOR_WITH_HOSTPORT_ARG_INTERCEPT_CLASS = "org.skywalking.apm.plugin.xmemcached.v2.XMemcachedConstructorWithHostPortArgInterceptor";
private static final String CONSTRUCTOR_WITH_INETSOCKETADDRESS_ARG_INTERCEPT_CLASS = "org.skywalking.apm.plugin.xmemcached.v2.XMemcachedConstructorWithInetSocketAddressArgInterceptor";
private static final String CONSTRUCTOR_WITH_INETSOCKETADDRESS_LIST_ARG_INTERCEPT_CLASS = "org.skywalking.apm.plugin.xmemcached.v2.XMemcachedConstructorWithInetSocketAddressListArgInterceptor";
private static final String CONSTRUCTOR_WITH_COMPLEX_ARG_INTERCEPT_CLASS = "org.skywalking.apm.plugin.xmemcached.v2.XMemcachedConstructorWithComplexArgInterceptor";
private static final String METHOD_INTERCEPT_CLASS = "org.skywalking.apm.plugin.xmemcached.v2.XMemcachedMethodInterceptor";
@Override
public ClassMatch enhanceClass() {
return byName(ENHANCE_CLASS);
}
@Override
protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[] {
new ConstructorInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getConstructorMatcher() {
return takesArguments(String.class, int.class);
}
@Override
public String getConstructorInterceptor() {
return CONSTRUCTOR_WITH_HOSTPORT_ARG_INTERCEPT_CLASS;
}
},
new ConstructorInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getConstructorMatcher() {
return takesArgument(0, InetSocketAddress.class);
}
@Override
public String getConstructorInterceptor() {
return CONSTRUCTOR_WITH_INETSOCKETADDRESS_ARG_INTERCEPT_CLASS;
}
},
new ConstructorInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getConstructorMatcher() {
return takesArgument(0, List.class);
}
@Override
public String getConstructorInterceptor() {
return CONSTRUCTOR_WITH_INETSOCKETADDRESS_LIST_ARG_INTERCEPT_CLASS;
}
},
new ConstructorInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getConstructorMatcher() {
return takesArgument(6, Map.class);
}
@Override
public String getConstructorInterceptor() {
return CONSTRUCTOR_WITH_COMPLEX_ARG_INTERCEPT_CLASS;
}
}
};
}
@Override
protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named("get").or(named("set")) .or(named("add")).or(named("replace")).or(named("gets"))
.or(named("append")) .or(named("prepend")).or(named("cas")).or(named("delete")).or(named("touch")).
or(named("getAndTouch")).or(named("incr")) .or(named("decr"));
}
@Override
public String getMethodsInterceptor() {
return METHOD_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
}
};
}
}
memcache-2.x=org.skywalking.apm.plugin.xmemcached.v2.define.XMemcachedInstrumentation
\ No newline at end of file
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.xmemcached.v2;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
@RunWith(MockitoJUnitRunner.class)
public class XMemcachedConstructorWithComplexArgInterceptorTest {
private XMemcachedConstructorWithComplexArgInterceptor interceptor;
@Mock
private EnhancedInstance enhancedInstance;
@Before
public void setUp() throws Exception {
interceptor = new XMemcachedConstructorWithComplexArgInterceptor();
}
@Test
public void onConstructWithComplex() {
Map<InetSocketAddress, InetSocketAddress> inetSocketAddressMap = new HashMap<InetSocketAddress, InetSocketAddress>();
inetSocketAddressMap.put(new InetSocketAddress("127.0.0.1", 11211), new InetSocketAddress("127.0.0.2", 11211));
interceptor.onConstruct(enhancedInstance, new Object[]{null, null, null, null, null, null, inetSocketAddressMap});
verify(enhancedInstance, times(1)).setSkyWalkingDynamicField("127.0.0.1:11211;127.0.0.2:11211");
}
}
\ No newline at end of file
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.xmemcached.v2;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
@RunWith(MockitoJUnitRunner.class)
public class XMemcachedConstructorWithHostPortArgInterceptorTest {
private XMemcachedConstructorWithHostPortArgInterceptor interceptor;
@Mock
private EnhancedInstance enhancedInstance;
@Before
public void setUp() throws Exception {
interceptor = new XMemcachedConstructorWithHostPortArgInterceptor();
}
@Test
public void onConstructWithHostPort() {
interceptor.onConstruct(enhancedInstance, new Object[]{"127.0.0.1", 11211});
verify(enhancedInstance, times(1)).setSkyWalkingDynamicField("127.0.0.1:11211");
}
}
\ No newline at end of file
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.xmemcached.v2;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import java.net.InetSocketAddress;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
@RunWith(MockitoJUnitRunner.class)
public class XMemcachedConstructorWithInetSocketAddressArgInterceptorTest {
private XMemcachedConstructorWithInetSocketAddressArgInterceptor interceptor;
@Mock
private EnhancedInstance enhancedInstance;
@Before
public void setUp() throws Exception {
interceptor = new XMemcachedConstructorWithInetSocketAddressArgInterceptor();
}
@Test
public void onConstructWithInetSocketAddress() {
interceptor.onConstruct(enhancedInstance, new Object[]{new InetSocketAddress("127.0.0.1", 11211)});
verify(enhancedInstance, times(1)).setSkyWalkingDynamicField("127.0.0.1:11211");
}
}
\ No newline at end of file
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.xmemcached.v2;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
@RunWith(MockitoJUnitRunner.class)
public class XMemcachedConstructorWithInetSocketAddressListArgInterceptorTest {
private XMemcachedConstructorWithInetSocketAddressListArgInterceptor interceptor;
@Mock
private EnhancedInstance enhancedInstance;
@Before
public void setUp() throws Exception {
interceptor = new XMemcachedConstructorWithInetSocketAddressListArgInterceptor();
}
@Test
public void onConstructWithInetSocketAddressList() {
List<InetSocketAddress> inetSocketAddressList = new ArrayList<InetSocketAddress>();
inetSocketAddressList.add(new InetSocketAddress("127.0.0.1", 11211));
inetSocketAddressList.add(new InetSocketAddress("127.0.0.2", 11211));
interceptor.onConstruct(enhancedInstance, new Object[]{inetSocketAddressList});
verify(enhancedInstance, times(1)).setSkyWalkingDynamicField("127.0.0.1:11211;127.0.0.2:11211");
}
}
\ No newline at end of file
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.xmemcached.v2;
import static junit.framework.TestCase.assertNotNull;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.when;
import java.lang.reflect.Method;
import java.util.List;
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
import org.skywalking.apm.agent.core.context.trace.LogDataEntity;
import org.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.skywalking.apm.agent.core.context.trace.TraceSegment;
import org.skywalking.apm.agent.core.context.util.KeyValuePair;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.test.helper.SegmentHelper;
import org.skywalking.apm.agent.test.helper.SpanHelper;
import org.skywalking.apm.agent.test.tools.AgentServiceRule;
import org.skywalking.apm.agent.test.tools.SegmentStorage;
import org.skywalking.apm.agent.test.tools.SegmentStoragePoint;
import org.skywalking.apm.agent.test.tools.TracingSegmentRunner;
import net.rubyeye.xmemcached.XMemcachedClient;
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(TracingSegmentRunner.class)
public class XMemcachedMethodInterceptorTest {
@SegmentStoragePoint
private SegmentStorage segmentStorage;
@Rule
public AgentServiceRule serviceRule = new AgentServiceRule();
@Mock
private EnhancedInstance enhancedInstance;
private XMemcachedMethodInterceptor interceptor;
private Object[] allArgument;
private Class[] argumentType;
@Before
public void setUp() throws Exception {
allArgument = new Object[] {"OperationKey", "OperationValue"};
argumentType = new Class[] {String.class, String.class};
interceptor = new XMemcachedMethodInterceptor();
when(enhancedInstance.getSkyWalkingDynamicField()).thenReturn("127.0.0.1:11211");
}
@Test
public void testIntercept() throws Throwable {
interceptor.beforeMethod(enhancedInstance, getMockSetMethod(), allArgument, argumentType, null);
interceptor.afterMethod(enhancedInstance, getMockGetMethod(), allArgument, argumentType, null);
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
assertThat(spans.size(), is(1));
assertMemcacheSpan(spans.get(0));
}
@Test
public void testInterceptWithException() throws Throwable {
interceptor.beforeMethod(enhancedInstance, getMockSetMethod(), allArgument, argumentType, null);
interceptor.handleMethodException(enhancedInstance, getMockSetMethod(), allArgument, argumentType, new RuntimeException());
interceptor.afterMethod(enhancedInstance, getMockSetMethod(), allArgument, argumentType, null);
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
assertThat(spans.size(), is(1));
assertMemcacheSpan(spans.get(0));
assertLogData(SpanHelper.getLogs(spans.get(0)));
}
private void assertLogData(List<LogDataEntity> logDataEntities) {
assertThat(logDataEntities.size(), is(1));
LogDataEntity logData = logDataEntities.get(0);
Assert.assertThat(logData.getLogs().size(), is(4));
Assert.assertThat(logData.getLogs().get(0).getValue(), CoreMatchers.<Object>is("error"));
Assert.assertThat(logData.getLogs().get(1).getValue(), CoreMatchers.<Object>is(RuntimeException.class.getName()));
Assert.assertNull(logData.getLogs().get(2).getValue());
assertNotNull(logData.getLogs().get(3).getValue());
}
private void assertMemcacheSpan(AbstractTracingSpan span) {
assertThat(span.getOperationName(), is("XMemcached/set"));
assertThat(span.isExit(), is(true));
assertThat(SpanHelper.getComponentId(span), is(20));
List<KeyValuePair> tags = SpanHelper.getTags(span);
assertThat(tags.get(0).getValue(), is("Memcache"));
assertThat(tags.get(1).getValue(), is("set OperationKey"));
assertThat(SpanHelper.getLayer(span), is(SpanLayer.DB));
}
private Method getMockSetMethod() {
try {
return XMemcachedClient.class.getMethod("set", String.class, int.class, Object.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
return null;
}
}
private Method getMockGetMethod() {
try {
return XMemcachedClient.class.getMethod("get", String.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
return null;
}
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册