diff --git a/apm-application-toolkit/apm-toolkit-trace/pom.xml b/apm-application-toolkit/apm-toolkit-trace/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..a4a5a4ad8cc96c2495281e4f37f0152f415c305d --- /dev/null +++ b/apm-application-toolkit/apm-toolkit-trace/pom.xml @@ -0,0 +1,45 @@ + + + apm-application-toolkit + org.skywalking + 3.2-2017 + + 4.0.0 + + apm-toolkit-trace + jar + + http://maven.apache.org + + + + + + org.apache.maven.plugins + maven-source-plugin + + + + attach-sources + + jar + + + + 2.4 + + + + + + + bintray-wu-sheng-sky-walking-repository + wu-sheng-sky-walking-repository + + https://api.bintray.com/maven/wu-sheng/skywalking/org.skywalking.apm-toolkit-trace/;publish=1 + + + + diff --git a/apm-application-toolkit/apm-toolkit-trace/src/main/java/org/skywalking/apm/toolkit/trace/ActiveSpan.java b/apm-application-toolkit/apm-toolkit-trace/src/main/java/org/skywalking/apm/toolkit/trace/ActiveSpan.java new file mode 100644 index 0000000000000000000000000000000000000000..a1776d7a83fa312e3e524eab55245de5c8655b88 --- /dev/null +++ b/apm-application-toolkit/apm-toolkit-trace/src/main/java/org/skywalking/apm/toolkit/trace/ActiveSpan.java @@ -0,0 +1,16 @@ +package org.skywalking.apm.toolkit.trace; + +/** + * provide custom api that set tag for current active span. + * + * @author zhangxin + */ +public class ActiveSpan { + /** + * @param key tag key + * @param value tag value + */ + public static void tag(String key, String value) { + + } +} diff --git a/apm-application-toolkit/apm-toolkit-trace/src/main/java/org/skywalking/apm/toolkit/trace/Trace.java b/apm-application-toolkit/apm-toolkit-trace/src/main/java/org/skywalking/apm/toolkit/trace/Trace.java new file mode 100644 index 0000000000000000000000000000000000000000..6d5f7f4625ee470dcb2f289b04df0baf8192f16e --- /dev/null +++ b/apm-application-toolkit/apm-toolkit-trace/src/main/java/org/skywalking/apm/toolkit/trace/Trace.java @@ -0,0 +1,22 @@ +package org.skywalking.apm.toolkit.trace; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The agent create local span if the method that annotation with {@link Trace}. The value of span operation name will + * fetch by {@link #operationName()}. if the value of {@link #operationName()} is blank string. the operation name will + * be set the class name + method name. + * + * @author zhangxin + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Trace { + /** + * @return operation name, the default value is blank string. + */ + String operationName() default ""; +} diff --git a/apm-application-toolkit/pom.xml b/apm-application-toolkit/pom.xml index c786e2fff484505506de0fb3084c836ed9b43272..b8f68ffd72ea5462235ebbdba5c12af0772e6dd4 100644 --- a/apm-application-toolkit/pom.xml +++ b/apm-application-toolkit/pom.xml @@ -19,5 +19,6 @@ apm-toolkit-logback-1.x apm-toolkit-trace-context apm-toolkit-opentracing + apm-toolkit-trace diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextManager.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextManager.java index 01765f638580508a4230a36e09e45eb77a75ac0c..c950031f7a29dcfdb2e091aa5a8f1a89007914fd 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextManager.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextManager.java @@ -39,7 +39,7 @@ public class ContextManager implements TracingContextListener, BootService, Igno context = new IgnoredTracerContext(); } else { if (RemoteDownstreamConfig.Agent.APPLICATION_ID != DictionaryUtil.nullValue() - || RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID != DictionaryUtil.nullValue() + && RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID != DictionaryUtil.nullValue() ) { int suffixIdx = operationName.lastIndexOf("."); if (suffixIdx > -1 && Config.Agent.IGNORE_SUFFIX.contains(operationName.substring(suffixIdx))) { @@ -108,6 +108,12 @@ public class ContextManager implements TracingContextListener, BootService, Igno return span; } + public static AbstractSpan createExitSpan(String operationName, String remotePeer) { + AbstractTracerContext context = getOrCreate(operationName, false); + AbstractSpan span = context.createExitSpan(operationName, remotePeer); + return span; + } + public static void inject(ContextCarrier carrier) { get().inject(carrier); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/MethodAnnotationMatch.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/MethodAnnotationMatch.java index b8059aea082d38c9969fab0f79ffa690c5a7060d..0a91ff56a971a3c6e00c0487431aa34403b7fe2a 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/MethodAnnotationMatch.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/MethodAnnotationMatch.java @@ -1,5 +1,6 @@ package org.skywalking.apm.agent.core.plugin.match; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import net.bytebuddy.description.annotation.AnnotationDescription; @@ -47,7 +48,7 @@ public class MethodAnnotationMatch implements IndirectMatch { @Override public boolean isMatch(TypeDescription typeDescription) { for (MethodDescription.InDefinedShape methodDescription : typeDescription.getDeclaredMethods()) { - List annotationList = Arrays.asList(annotations); + List annotationList = new ArrayList(Arrays.asList(annotations)); AnnotationList declaredAnnotations = methodDescription.getDeclaredAnnotations(); for (AnnotationDescription annotation : declaredAnnotations) { diff --git a/apm-sniffer/apm-agent/pom.xml b/apm-sniffer/apm-agent/pom.xml index bda4d71373ce3734d15e7b3850ca6c50a7863af5..b9d1845b1e7244dc42cbee82c381211c0d4e4939 100644 --- a/apm-sniffer/apm-agent/pom.xml +++ b/apm-sniffer/apm-agent/pom.xml @@ -126,6 +126,12 @@ ${project.version} + + org.skywalking + apm-toolkit-trace-activation + ${project.version} + + skywalking-agent diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/CallableStatementTracing.java b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/CallableStatementTracing.java index 30d82ae34640ccb739b65af181fca253896846b2..f41884d25ddcd9ea9bc97b428c03e7efbf13a18a 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/CallableStatementTracing.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/CallableStatementTracing.java @@ -1,7 +1,6 @@ package org.skywalking.apm.plugin.jdbc; import java.sql.SQLException; -import org.skywalking.apm.agent.core.context.ContextCarrier; 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; @@ -20,7 +19,7 @@ public class CallableStatementTracing { } else { remotePeer = connectInfo.getHost() + ":" + connectInfo.getPort(); } - AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/CallableStatement/" + method, new ContextCarrier(), remotePeer); + AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/CallableStatement/" + method, remotePeer); Tags.DB_TYPE.set(span, "sql"); SpanLayer.asDB(span); Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName()); diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/ConnectionTracing.java b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/ConnectionTracing.java index c87685ba3bdd644e67746ea0def3ce54e42585e2..46e9b59f80d90bcfde316e15c692a98caf8067ed 100755 --- a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/ConnectionTracing.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/ConnectionTracing.java @@ -1,7 +1,6 @@ package org.skywalking.apm.plugin.jdbc; import java.sql.SQLException; -import org.skywalking.apm.agent.core.context.ContextCarrier; 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; @@ -20,7 +19,7 @@ public class ConnectionTracing { } else { remotePeer = connectInfo.getHost() + ":" + connectInfo.getPort(); } - AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/Connection/" + method, new ContextCarrier(), remotePeer); + AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/Connection/" + method, remotePeer); Tags.DB_TYPE.set(span, "sql"); Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName()); Tags.DB_STATEMENT.set(span, sql); diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/PreparedStatementTracing.java b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/PreparedStatementTracing.java index 3d94b45aabb509f9c3e7a734b29131c75e5e41cc..a0db29ba34d15cc62b3ec9fe09c824a95a3d50bc 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/PreparedStatementTracing.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/PreparedStatementTracing.java @@ -1,7 +1,6 @@ package org.skywalking.apm.plugin.jdbc; import java.sql.SQLException; -import org.skywalking.apm.agent.core.context.ContextCarrier; 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; @@ -21,7 +20,7 @@ public class PreparedStatementTracing { remotePeer = connectInfo.getHost() + ":" + connectInfo.getPort(); } - AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/PreparedStatement/" + method, new ContextCarrier(), remotePeer); + AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/PreparedStatement/" + method, remotePeer); Tags.DB_TYPE.set(span, "sql"); Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName()); Tags.DB_STATEMENT.set(span, sql); diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/StatementTracing.java b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/StatementTracing.java index a8510864714a77c05abc13ea73f2930bfe50140f..6d496f6bc8411f9a28e3d958997d35de85642826 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/StatementTracing.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/StatementTracing.java @@ -1,7 +1,6 @@ package org.skywalking.apm.plugin.jdbc; import java.sql.SQLException; -import org.skywalking.apm.agent.core.context.ContextCarrier; 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; @@ -20,7 +19,7 @@ public class StatementTracing { remotePeer = connectInfo.getHost() + ":" + connectInfo.getPort(); } - AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/Statement/" + method, new ContextCarrier(), remotePeer); + AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/Statement/" + method, remotePeer); Tags.DB_TYPE.set(span, "sql"); Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName()); Tags.DB_STATEMENT.set(span, sql); diff --git a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/skywalking/apm/plugin/jedis/v2/JedisMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/skywalking/apm/plugin/jedis/v2/JedisMethodInterceptor.java index 83b3c41ee66c67cb1bc55e2b27eccc1aa756b893..d16deb8a56131f392acb9938fecc741d95104c56 100644 --- a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/skywalking/apm/plugin/jedis/v2/JedisMethodInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/skywalking/apm/plugin/jedis/v2/JedisMethodInterceptor.java @@ -1,7 +1,6 @@ package org.skywalking.apm.plugin.jedis.v2; import java.lang.reflect.Method; -import org.skywalking.apm.agent.core.context.ContextCarrier; 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; @@ -16,7 +15,7 @@ public class JedisMethodInterceptor implements InstanceMethodsAroundInterceptor @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("Jedis/" + method.getName(), new ContextCarrier(), peer); + AbstractSpan span = ContextManager.createExitSpan("Jedis/" + method.getName(), peer); span.setComponent(ComponentsDefine.REDIS); Tags.DB_TYPE.set(span, "Redis"); SpanLayer.asDB(span); diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/skywalking/apm/plugin/spring/mvc/ControllerServiceMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/skywalking/apm/plugin/spring/mvc/ControllerServiceMethodInterceptor.java index a735251c4385cc19034ceee6148dd8db37d4a071..4a5ba25715b82efad2d8abb2878181e305dabd68 100644 --- a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/skywalking/apm/plugin/spring/mvc/ControllerServiceMethodInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/skywalking/apm/plugin/spring/mvc/ControllerServiceMethodInterceptor.java @@ -36,6 +36,7 @@ public class ControllerServiceMethodInterceptor implements InstanceMethodsAround requestURL = ""; } pathMappingCache.addPathMapping(method, requestURL); + requestURL = pathMappingCache.findPathMapping(method); } HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(); diff --git a/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/helper/SpanHelper.java b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/helper/SpanHelper.java index 0b752e9474715b412e5b7d81cb043ba24b33196a..ff5ba70345187dcb02b27f16e666154e4ef6d116 100644 --- a/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/helper/SpanHelper.java +++ b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/helper/SpanHelper.java @@ -24,10 +24,16 @@ public class SpanHelper { public static List getLogs(AbstractSpan tracingSpan) { try { - return FieldGetter.get2LevelParentFieldValue(tracingSpan, "logs"); + List logs = FieldGetter.get2LevelParentFieldValue(tracingSpan, "logs"); + if (logs != null) { + return logs; + } } catch (Exception e) { try { - return FieldGetter.getParentFieldValue(tracingSpan, "logs"); + List logs = FieldGetter.getParentFieldValue(tracingSpan, "logs"); + if (logs != null) { + return logs; + } } catch (Exception e1) { } @@ -38,10 +44,16 @@ public class SpanHelper { public static List getTags(AbstractSpan tracingSpan) { try { - return FieldGetter.get2LevelParentFieldValue(tracingSpan, "tags"); + List tags = FieldGetter.get2LevelParentFieldValue(tracingSpan, "tags"); + if (tags != null) { + return tags; + } } catch (Exception e) { try { - return FieldGetter.getParentFieldValue(tracingSpan, "tags"); + List tags = FieldGetter.getParentFieldValue(tracingSpan, "tags"); + if (tags != null) { + return tags; + } } catch (Exception e1) { } diff --git a/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/SpanAssert.java b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/SpanAssert.java index 584c870f7d470dab1c9b1ad202e6b284fd43acce..ca6280e1135902eacdf0934743ae2b0064097082 100644 --- a/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/SpanAssert.java +++ b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/SpanAssert.java @@ -17,6 +17,10 @@ public class SpanAssert { assertThat(SpanHelper.getLogs(span).size(), is(exceptedSize)); } + public static void assertTagSize(AbstractSpan span, int exceptedSize) { + assertThat(SpanHelper.getTags(span).size(), is(exceptedSize)); + } + public static void assertException(LogDataEntity logDataEntity, Class throwableClass, String message) { Assert.assertThat(logDataEntity.getLogs().size(), is(4)); diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/ConstructorWithSpanBuilderInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/ConstructorWithSpanBuilderInterceptor.java index b9127ab20573318039b26bb63323a7f9dcb9a464..387abd4dfdc1d5528a0ea1cf1004c2f9a41be0ff 100644 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/ConstructorWithSpanBuilderInterceptor.java +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/ConstructorWithSpanBuilderInterceptor.java @@ -1,6 +1,5 @@ package org.skywalking.apm.toolkit.activation.opentracing.span; -import org.skywalking.apm.agent.core.context.ContextCarrier; import org.skywalking.apm.agent.core.context.ContextManager; import org.skywalking.apm.agent.core.context.trace.AbstractSpan; import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; @@ -19,8 +18,7 @@ public class ConstructorWithSpanBuilderInterceptor implements InstanceConstructo if (spanBuilder.isEntry()) { span = ContextManager.createEntrySpan(spanBuilder.getOperationName(), null); } else if (spanBuilder.isExit() && (!StringUtil.isEmpty(spanBuilder.getPeer()))) { - span = ContextManager.createExitSpan(spanBuilder.getOperationName(), - new ContextCarrier(), buildRemotePeer(spanBuilder)); + span = ContextManager.createExitSpan(spanBuilder.getOperationName(), buildRemotePeer(spanBuilder)); } else { span = ContextManager.createLocalSpan(spanBuilder.getOperationName()); } diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/pom.xml b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..ff76498e887df30fbf4f02e6c0c0b5bf56ddb7b7 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/pom.xml @@ -0,0 +1,22 @@ + + + + apm-toolkit-activation + org.skywalking + 3.2-2017 + + 4.0.0 + + apm-toolkit-trace-activation + + + + org.skywalking + apm-toolkit-trace + ${project.version} + provided + + + diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/ActiveSpanTagActivation.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/ActiveSpanTagActivation.java new file mode 100644 index 0000000000000000000000000000000000000000..ba810d9a9604ece0d4fff991a0a8015484f70a1b --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/ActiveSpanTagActivation.java @@ -0,0 +1,50 @@ +package org.skywalking.apm.toolkit.activation.trace; + +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.StaticMethodsInterceptPoint; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassStaticMethodsEnhancePluginDefine; +import org.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +/** + * {@link TraceAnnotationActivation} enhance the tag method of org.skywalking.apm.toolkit.trace.ActiveSpan + * by org.skywalking.apm.toolkit.activation.trace.ActiveSpanTagInterceptor. + * + * @author zhangxin + */ +public class ActiveSpanTagActivation extends ClassStaticMethodsEnhancePluginDefine { + + public static final String ENHANCE_CLASS = "org.skywalking.apm.toolkit.trace.ActiveSpan"; + public static final String INTERCEPTOR_CLASS = "org.skywalking.apm.toolkit.activation.trace.ActiveSpanTagInterceptor"; + public static final String INTERCEPTOR_METHOD_NAME = "tag"; + + @Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override protected StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() { + return new StaticMethodsInterceptPoint[] { + new StaticMethodsInterceptPoint() { + @Override public ElementMatcher getMethodsMatcher() { + return named(INTERCEPTOR_METHOD_NAME); + } + + @Override public String getMethodsInterceptor() { + return INTERCEPTOR_CLASS; + } + + @Override public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/ActiveSpanTagInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/ActiveSpanTagInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..17f4741332a30dba97c821c5941866c9f91dbdfb --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/ActiveSpanTagInterceptor.java @@ -0,0 +1,26 @@ +package org.skywalking.apm.toolkit.activation.trace; + +import java.lang.reflect.Method; +import org.skywalking.apm.agent.core.context.ContextManager; +import org.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor; + +public class ActiveSpanTagInterceptor implements StaticMethodsAroundInterceptor { + @Override public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, + MethodInterceptResult result) { + AbstractSpan activeSpan = ContextManager.activeSpan(); + activeSpan.tag(String.valueOf(allArguments[0]), String.valueOf(allArguments[1])); + } + + @Override public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, + Object ret) { + return ret; + } + + @Override + public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, + Throwable t) { + + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/TraceAnnotationActivation.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/TraceAnnotationActivation.java new file mode 100644 index 0000000000000000000000000000000000000000..f02709102387ddf3c08ad13e4ebcbfef34187092 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/TraceAnnotationActivation.java @@ -0,0 +1,50 @@ +package org.skywalking.apm.toolkit.activation.trace; + +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.isAnnotatedWith; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.skywalking.apm.agent.core.plugin.match.MethodAnnotationMatch.byMethodAnnotationMatch; + +/** + * {@link TraceAnnotationActivation} enhance all method that annotated with org.skywalking.apm.toolkit.trace.annotation.Trace + * by org.skywalking.apm.toolkit.activation.trace.TraceAnnotationMethodInterceptor. + * + * @author zhangxin + */ +public class TraceAnnotationActivation extends ClassInstanceMethodsEnhancePluginDefine { + + public static final String TRACE_ANNOTATION_METHOD_INTERCEPTOR = "org.skywalking.apm.toolkit.activation.trace.TraceAnnotationMethodInterceptor"; + public static final String TRACE_ANNOTATION = "org.skywalking.apm.toolkit.trace.Trace"; + + @Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override public ElementMatcher getMethodsMatcher() { + return isAnnotatedWith(named(TRACE_ANNOTATION)); + } + + @Override public String getMethodsInterceptor() { + return TRACE_ANNOTATION_METHOD_INTERCEPTOR; + } + + @Override public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override protected ClassMatch enhanceClass() { + return byMethodAnnotationMatch(new String[] {TRACE_ANNOTATION}); + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/TraceAnnotationMethodInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/TraceAnnotationMethodInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..39f0988bbdc8e474320947e43afd07b9ef574583 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/TraceAnnotationMethodInterceptor.java @@ -0,0 +1,54 @@ +package org.skywalking.apm.toolkit.activation.trace; + +import java.lang.reflect.Method; +import org.skywalking.apm.agent.core.context.ContextManager; +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.toolkit.trace.Trace; + +/** + * {@link TraceAnnotationMethodInterceptor} create a local span and set the operation name which fetch from + * org.skywalking.apm.toolkit.trace.annotation.Trace.operationName. if the fetch value is blank string, and + * the operation name will be the method name. + * + * @author zhangxin + */ +public class TraceAnnotationMethodInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + Trace trace = method.getAnnotation(Trace.class); + String operationName = trace.operationName(); + if (operationName.length() == 0) { + operationName = generateOperationName(method); + } + + ContextManager.createLocalSpan(operationName); + } + + private String generateOperationName(Method method) { + StringBuilder operationName = new StringBuilder(method.getDeclaringClass().getName() + "." + method.getName() + "("); + Class[] parameterTypes = method.getParameterTypes(); + for (int i = 0; i < parameterTypes.length; i++) { + operationName.append(parameterTypes[i].getName()); + if (i < (parameterTypes.length - 1)) { + operationName.append(","); + } + } + operationName.append(")"); + return operationName.toString(); + } + + @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) { + ContextManager.activeSpan().errorOccurred().log(t); + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/resources/skywalking-plugin.def new file mode 100644 index 0000000000000000000000000000000000000000..42ba1a8e60521e8590174b8d245f7f09c7bb85fe --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/resources/skywalking-plugin.def @@ -0,0 +1,2 @@ +trace-annotation=org.skywalking.apm.toolkit.activation.trace.ActiveSpanTagActivation +trace-annotation=org.skywalking.apm.toolkit.activation.trace.TraceAnnotationActivation diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/test/java/org/skywalking/apm/toolkit/activation/trace/TraceAnnotationTest.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/test/java/org/skywalking/apm/toolkit/activation/trace/TraceAnnotationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ce5350e6f6e5104346696427f056f836371ef932 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/test/java/org/skywalking/apm/toolkit/activation/trace/TraceAnnotationTest.java @@ -0,0 +1,103 @@ +package org.skywalking.apm.toolkit.activation.trace; + +import java.lang.reflect.Method; +import java.util.List; +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.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 org.skywalking.apm.toolkit.trace.Trace; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertLogSize; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertTagSize; + +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +public class TraceAnnotationTest { + + @SegmentStoragePoint + private SegmentStorage storage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + + @Mock + private EnhancedInstance enhancedInstance; + + private TraceAnnotationMethodInterceptor methodInterceptor; + private ActiveSpanTagInterceptor tagInterceptor; + private Object[] tagParameters; + private Class[] tagParameterTypes; + + @Before + public void setUp() throws Exception { + methodInterceptor = new TraceAnnotationMethodInterceptor(); + tagInterceptor = new ActiveSpanTagInterceptor(); + tagParameters = new Object[] {"testTagKey", "testTagValue"}; + tagParameterTypes = new Class[] {String.class, String.class}; + } + + @Test + public void testTraceWithOperationName() throws Throwable { + Method withOperationNameMethod = TestAnnotationMethodClass.class.getDeclaredMethod("testMethodWithOperationName"); + methodInterceptor.beforeMethod(enhancedInstance, withOperationNameMethod, null, null, null); + tagInterceptor.beforeMethod(TestAnnotationMethodClass.class, withOperationNameMethod, tagParameters, tagParameterTypes, null); + tagInterceptor.afterMethod(TestAnnotationMethodClass.class, withOperationNameMethod, tagParameters, tagParameterTypes, null); + methodInterceptor.afterMethod(enhancedInstance, withOperationNameMethod, null, null, null); + + assertThat(storage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = storage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + + AbstractTracingSpan tracingSpan = spans.get(0); + assertThat(tracingSpan.getOperationName(), is("testMethod")); + assertLogSize(tracingSpan, 0); + assertTagSize(tracingSpan, 1); + List tags = SpanHelper.getTags(tracingSpan); + assertThat(tags.get(0).getKey(), is("testTagKey")); + assertThat(tags.get(0).getValue(), is("testTagValue")); + } + + @Test + public void testTrace() throws Throwable { + Method withOperationNameMethod = TestAnnotationMethodClass.class.getDeclaredMethod("testMethodWithDefaultValue"); + methodInterceptor.beforeMethod(enhancedInstance, withOperationNameMethod, null, null, null); + methodInterceptor.afterMethod(enhancedInstance, withOperationNameMethod, null, null, null); + + assertThat(storage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = storage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + + AbstractTracingSpan tracingSpan = spans.get(0); + assertThat(tracingSpan.getOperationName(), is(TestAnnotationMethodClass.class.getName() + "." + withOperationNameMethod.getName() + "()")); + assertLogSize(tracingSpan, 0); + assertTagSize(tracingSpan, 0); + } + + private class TestAnnotationMethodClass { + @Trace(operationName = "testMethod") + public void testMethodWithOperationName() { + } + + @Trace + public void testMethodWithDefaultValue() { + } + } +} diff --git a/apm-sniffer/apm-toolkit-activation/pom.xml b/apm-sniffer/apm-toolkit-activation/pom.xml index 655cfd01f1cb54b7e2a9feb0ad25445d5c6f31cd..32b2aa533012bf3f84e79ffd34c0e6ef43825a74 100644 --- a/apm-sniffer/apm-toolkit-activation/pom.xml +++ b/apm-sniffer/apm-toolkit-activation/pom.xml @@ -15,6 +15,7 @@ apm-toolkit-logback-1.x-activation apm-toolkit-trace-context-activation apm-toolkit-opentracing-activation + apm-toolkit-trace-activation apm-toolkit-activation