diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/InterceptorException.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/InterceptorException.java new file mode 100644 index 000000000..7be0f8e02 --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/InterceptorException.java @@ -0,0 +1,13 @@ +package com.ai.cloud.skywalking.plugin.interceptor; + +public class InterceptorException extends RuntimeException { + private static final long serialVersionUID = 7846035239994885019L; + + public InterceptorException(String message) { + super(message); + } + + public InterceptorException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/assist/FirstInvokeInterceptor.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/assist/FirstInvokeInterceptor.java new file mode 100644 index 000000000..c6dff6d27 --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/assist/FirstInvokeInterceptor.java @@ -0,0 +1,42 @@ +package com.ai.cloud.skywalking.plugin.interceptor.assist; + +import java.util.concurrent.atomic.AtomicInteger; + +import com.ai.cloud.skywalking.plugin.interceptor.EnhancedClassInstanceContext; +import com.ai.cloud.skywalking.plugin.interceptor.IAroundInterceptor; +import com.ai.cloud.skywalking.plugin.interceptor.InterceptorException; + +/** + * 用于首次拦截方法调用,避免方法内部的方法调用被多次拦截。 + * + * @author wusheng + * + */ +public abstract class FirstInvokeInterceptor implements IAroundInterceptor { + protected String invokeCounterKey = "__$invokeCounterKey"; + + protected Object invokeCounterInstLock = new Object(); + + public boolean isFirstBeforeMethod(EnhancedClassInstanceContext context) { + if (!context.isContain(invokeCounterKey)) { + synchronized (invokeCounterInstLock) { + if (!context.isContain(invokeCounterKey)) { + context.set(invokeCounterKey, new AtomicInteger(0)); + } + } + } + AtomicInteger counter = context.get(invokeCounterKey, + AtomicInteger.class); + return counter.incrementAndGet() == 1; + } + + public boolean isLastAfterMethod(EnhancedClassInstanceContext context) { + if (!context.isContain(invokeCounterKey)) { + throw new InterceptorException( + "key=invokeCounterKey not found is context. unexpected failue."); + } + AtomicInteger counter = context.get(invokeCounterKey, + AtomicInteger.class); + return counter.decrementAndGet() == 0; + } +} diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/util/BuriedPointMachineUtil.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/util/BuriedPointMachineUtil.java index bfd9fc661..873ed1c2d 100644 --- a/skywalking-api/src/main/java/com/ai/cloud/skywalking/util/BuriedPointMachineUtil.java +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/util/BuriedPointMachineUtil.java @@ -35,9 +35,10 @@ public final class BuriedPointMachineUtil { if (StringUtil.isEmpty(IP)) { InetAddress netAddress = getInetAddress(); if (null == netAddress) { - return null; + IP = "N/A"; + }else{ + IP = netAddress.getHostAddress(); //get the ip address } - IP = netAddress.getHostAddress(); //get the ip address } return IP; } @@ -46,9 +47,10 @@ public final class BuriedPointMachineUtil { if (StringUtil.isEmpty(hostName)) { InetAddress netAddress = getInetAddress(); if (null == netAddress) { - return null; + hostName = "N/A"; + }else{ + hostName = netAddress.getHostName(); //get the host address } - hostName = netAddress.getHostName(); //get the host address } return hostName; } diff --git a/skywalking-api/src/test/java/test/ai/cloud/api/TimeTest.java b/skywalking-api/src/test/java/test/ai/cloud/api/TimeTest.java new file mode 100644 index 000000000..708386857 --- /dev/null +++ b/skywalking-api/src/test/java/test/ai/cloud/api/TimeTest.java @@ -0,0 +1,25 @@ +package test.ai.cloud.api; + +import org.junit.Test; + +import com.ai.cloud.skywalking.buriedpoint.RPCBuriedPointSender; +import com.ai.cloud.skywalking.model.Identification; +import com.ai.cloud.skywalking.model.Identification.IdentificationBuilder; + +public class TimeTest { + @Test + public void test(){ + RPCBuriedPointSender sender = new RPCBuriedPointSender(); + long start = System.currentTimeMillis(); + for (int i = 0; i < 100; i++) { + IdentificationBuilder builder = Identification + .newBuilder() + .viewPoint("1111"); + sender.beforeSend(builder.build()); + sender.afterSend(); + } + long end = System.currentTimeMillis(); + System.out.println(end - start + "ms"); + } + +} diff --git a/skywalking-api/src/test/java/test/ai/cloud/plugin/PluginMainTest.java b/skywalking-api/src/test/java/test/ai/cloud/plugin/PluginMainTest.java index 9455dbae0..ed30c53be 100644 --- a/skywalking-api/src/test/java/test/ai/cloud/plugin/PluginMainTest.java +++ b/skywalking-api/src/test/java/test/ai/cloud/plugin/PluginMainTest.java @@ -2,12 +2,9 @@ package test.ai.cloud.plugin; import java.lang.reflect.InvocationTargetException; -import org.junit.Test; - import com.ai.cloud.skywalking.plugin.TracingBootstrap; public class PluginMainTest { - @Test public void testMain() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException { diff --git a/skywalking-sdk-plugin/skywalking-jedis-2.x-plugin/src/main/java/org/skywalking/jedis/v2/plugin/JedisInterceptor.java b/skywalking-sdk-plugin/skywalking-jedis-2.x-plugin/src/main/java/org/skywalking/jedis/v2/plugin/JedisInterceptor.java index 297093150..fc7d24e5f 100644 --- a/skywalking-sdk-plugin/skywalking-jedis-2.x-plugin/src/main/java/org/skywalking/jedis/v2/plugin/JedisInterceptor.java +++ b/skywalking-sdk-plugin/skywalking-jedis-2.x-plugin/src/main/java/org/skywalking/jedis/v2/plugin/JedisInterceptor.java @@ -1,27 +1,74 @@ package org.skywalking.jedis.v2.plugin; +import java.net.URI; + +import redis.clients.jedis.JedisShardInfo; + +import com.ai.cloud.skywalking.buriedpoint.RPCBuriedPointSender; +import com.ai.cloud.skywalking.model.Identification; +import com.ai.cloud.skywalking.model.Identification.IdentificationBuilder; import com.ai.cloud.skywalking.plugin.interceptor.ConstructorInvokeContext; import com.ai.cloud.skywalking.plugin.interceptor.EnhancedClassInstanceContext; -import com.ai.cloud.skywalking.plugin.interceptor.IAroundInterceptor; import com.ai.cloud.skywalking.plugin.interceptor.MethodInvokeContext; +import com.ai.cloud.skywalking.plugin.interceptor.assist.FirstInvokeInterceptor; -public class JedisInterceptor implements IAroundInterceptor{ +public class JedisInterceptor extends FirstInvokeInterceptor { + private static final String REDIS_CONN_INFO_KEY = "redisConnInfo"; + + private static RPCBuriedPointSender sender = new RPCBuriedPointSender(); @Override public void onConstruct(EnhancedClassInstanceContext context, ConstructorInvokeContext interceptorContext) { - + String redisConnInfo = ""; + if (interceptorContext.allArguments().length > 0) { + if (interceptorContext.allArguments()[0] instanceof String) { + redisConnInfo = (String) interceptorContext.allArguments()[0]; + if (interceptorContext.allArguments().length > 1) { + redisConnInfo += ":" + + (Integer) interceptorContext.allArguments()[1]; + } + } else if (interceptorContext.allArguments()[0] instanceof JedisShardInfo) { + JedisShardInfo shardInfo = (JedisShardInfo) interceptorContext + .allArguments()[0]; + redisConnInfo = shardInfo.getHost() + ":" + shardInfo.getPort(); + } else if (interceptorContext.allArguments()[0] instanceof URI) { + URI uri = (URI) interceptorContext.allArguments()[0]; + redisConnInfo = uri.getHost() + ":" + uri.getPort(); + } + } + context.set(REDIS_CONN_INFO_KEY, redisConnInfo); } @Override public void beforeMethod(EnhancedClassInstanceContext context, MethodInvokeContext interceptorContext) { - + if (this.isFirstBeforeMethod(context)) { + /** + * redis server wouldn't process rpc context. ignore the + * return(ContextData) of sender's beforeSend + */ + IdentificationBuilder builder = Identification + .newBuilder() + .viewPoint( + context.get(REDIS_CONN_INFO_KEY, String.class) + + " " + interceptorContext.methodName()) + .spanType(RedisBuriedPointType.instance()); + if (interceptorContext.allArguments().length > 0 + && interceptorContext.allArguments()[0] instanceof String) { + builder.businessKey("key=" + + interceptorContext.allArguments()[0]); + } + sender.beforeSend(builder.build()); + } } @Override public Object afterMethod(EnhancedClassInstanceContext context, MethodInvokeContext interceptorContext, Object ret) { + if (this.isLastAfterMethod(context)) { + sender.afterSend(); + } return ret; } @@ -29,7 +76,7 @@ public class JedisInterceptor implements IAroundInterceptor{ public void handleMethodException(Throwable t, EnhancedClassInstanceContext context, MethodInvokeContext interceptorContext, Object ret) { - + sender.handleException(t); } } diff --git a/skywalking-sdk-plugin/skywalking-jedis-2.x-plugin/src/main/java/org/skywalking/jedis/v2/plugin/RedisBuriedPointType.java b/skywalking-sdk-plugin/skywalking-jedis-2.x-plugin/src/main/java/org/skywalking/jedis/v2/plugin/RedisBuriedPointType.java new file mode 100644 index 000000000..b119f4549 --- /dev/null +++ b/skywalking-sdk-plugin/skywalking-jedis-2.x-plugin/src/main/java/org/skywalking/jedis/v2/plugin/RedisBuriedPointType.java @@ -0,0 +1,29 @@ +package org.skywalking.jedis.v2.plugin; + +import com.ai.cloud.skywalking.api.IBuriedPointType; +import com.ai.cloud.skywalking.protocol.CallType; + +public class RedisBuriedPointType implements IBuriedPointType { + private static RedisBuriedPointType redisBuriedPointType; + + public static IBuriedPointType instance() { + if (redisBuriedPointType == null) { + redisBuriedPointType = new RedisBuriedPointType(); + } + + return redisBuriedPointType; + } + + + @Override + public String getTypeName() { + return "Redis"; + } + + @Override + public CallType getCallType() { + return CallType.SYNC; + } + + private RedisBuriedPointType(){} +} diff --git a/skywalking-sdk-plugin/skywalking-jedis-2.x-plugin/src/test/java/org/skywalking/jedis/v2/plugin/JedisTest.java b/skywalking-sdk-plugin/skywalking-jedis-2.x-plugin/src/test/java/org/skywalking/jedis/v2/plugin/JedisTest.java index 3e8200564..98e0e1948 100644 --- a/skywalking-sdk-plugin/skywalking-jedis-2.x-plugin/src/test/java/org/skywalking/jedis/v2/plugin/JedisTest.java +++ b/skywalking-sdk-plugin/skywalking-jedis-2.x-plugin/src/test/java/org/skywalking/jedis/v2/plugin/JedisTest.java @@ -5,19 +5,34 @@ import java.sql.SQLException; import org.junit.Test; +import redis.clients.jedis.Jedis; + import com.ai.cloud.skywalking.plugin.TracingBootstrap; public class JedisTest { - @Test - public void test() throws IllegalAccessException, - IllegalArgumentException, InvocationTargetException, - NoSuchMethodException, SecurityException, ClassNotFoundException { + public void test() throws IllegalAccessException, IllegalArgumentException, + InvocationTargetException, NoSuchMethodException, + SecurityException, ClassNotFoundException { TracingBootstrap .main(new String[] { "org.skywalking.jedis.v2.plugin.JedisTest" }); } public static void main(String[] args) throws ClassNotFoundException, - SQLException, InterruptedException {} - + SQLException, InterruptedException { + try(Jedis jedis = new Jedis("10.1.241.18", 16379)){ + long start = System.currentTimeMillis(); + jedis.set("11111", "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); + for (int i = 0; i < 1; i++) { + jedis.get("11111"); + } + long end = System.currentTimeMillis(); + System.out.println(end - start + "ms"); + jedis.del("11111"); + } + } + + public void testNormal() throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException, InterruptedException{ + JedisTest.main(null); + } } diff --git a/skywalking-server/src/main/java/com/ai/cloud/skywalking/reciever/util/MachineUtil.java b/skywalking-server/src/main/java/com/ai/cloud/skywalking/reciever/util/MachineUtil.java index 82ceaaafa..c9396f12e 100644 --- a/skywalking-server/src/main/java/com/ai/cloud/skywalking/reciever/util/MachineUtil.java +++ b/skywalking-server/src/main/java/com/ai/cloud/skywalking/reciever/util/MachineUtil.java @@ -35,9 +35,10 @@ public class MachineUtil { if (StringUtil.isEmpty(IP)) { InetAddress netAddress = getInetAddress(); if (null == netAddress) { - return null; + IP = "N/A"; + }else{ + IP = netAddress.getHostAddress(); //get the ip address } - IP = netAddress.getHostAddress(); //get the ip address } return IP; } @@ -46,9 +47,10 @@ public class MachineUtil { if (StringUtil.isEmpty(hostName)) { InetAddress netAddress = getInetAddress(); if (null == netAddress) { - return null; + hostName = "N/A"; + }else{ + hostName = netAddress.getHostName(); //get the host address } - hostName = netAddress.getHostName(); //get the host address } return hostName; }