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 72671097ff75..826a81585044 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 @@ -86,7 +86,7 @@ public static void stopSpan() { @Override public void bootUp() { TracerContext.ListenerManager.add(this); - IgnoreTracerContext.ListenerManager.add(this); + IgnoredTracerContext.ListenerManager.add(this); } @Override @@ -95,7 +95,7 @@ public void afterFinished(TraceSegment traceSegment) { } @Override - public void afterFinished(IgnoreTracerContext traceSegment) { + public void afterFinished(IgnoredTracerContext traceSegment) { CONTEXT.remove(); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/IgnoreTracerContextListener.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/IgnoreTracerContextListener.java index dba27d026e92..80f5fedb1567 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/IgnoreTracerContextListener.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/IgnoreTracerContextListener.java @@ -5,5 +5,5 @@ * @author wusheng */ public interface IgnoreTracerContextListener { - void afterFinished(IgnoreTracerContext traceSegment); + void afterFinished(IgnoredTracerContext traceSegment); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/IgnoreTracerContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/IgnoredTracerContext.java similarity index 66% rename from apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/IgnoreTracerContext.java rename to apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/IgnoredTracerContext.java index d1db8e5ff3fa..52435f14f440 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/IgnoreTracerContext.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/IgnoredTracerContext.java @@ -3,20 +3,21 @@ import java.util.LinkedList; import java.util.List; import org.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.skywalking.apm.agent.core.context.trace.NoopSpan; /** - * The IgnoreTracerContext represent a context should be ignored. + * The IgnoredTracerContext represent a context should be ignored. * So it just maintains the stack with integer depth. - * All operations through this IgnoreTracerContext will be ignored, with low gc cost. - * - * TODO: Can't return null span + * All operations through this IgnoredTracerContext will be ignored, with low gc cost. * * @author wusheng */ -public class IgnoreTracerContext implements AbstractTracerContext { +public class IgnoredTracerContext implements AbstractTracerContext { + private static final NoopSpan NOOP_SPAN = new NoopSpan(); + private int stackDepth; - public IgnoreTracerContext(int initStackDepth) { + public IgnoredTracerContext(int initStackDepth) { this.stackDepth = initStackDepth; } @@ -38,7 +39,7 @@ public String getGlobalTraceId() { @Override public AbstractSpan createSpan(String operationName, boolean isLeaf) { stackDepth++; - return null; + return NOOP_SPAN; } @Override @@ -48,14 +49,14 @@ public AbstractSpan createSpan(String operationName, long startTime, boolean isL @Override public AbstractSpan activeSpan() { - return null; + return NOOP_SPAN; } @Override public void stopSpan(AbstractSpan span) { stackDepth--; if (stackDepth == 0) { - + ListenerManager.notifyFinish(this); } } @@ -82,15 +83,15 @@ public static synchronized void add(IgnoreTracerContextListener listener) { } /** - * Notify the {@link IgnoreTracerContext.ListenerManager} about the given {@link IgnoreTracerContext} have - * finished. And trigger {@link IgnoreTracerContext.ListenerManager} to notify all {@link #LISTENERS} 's {@link - * IgnoreTracerContextListener#afterFinished(IgnoreTracerContext)} + * Notify the {@link IgnoredTracerContext.ListenerManager} about the given {@link IgnoredTracerContext} have + * finished. And trigger {@link IgnoredTracerContext.ListenerManager} to notify all {@link #LISTENERS} 's {@link + * IgnoreTracerContextListener#afterFinished(IgnoredTracerContext)} * - * @param ignoreTracerContext + * @param ignoredTracerContext */ - static void notifyFinish(IgnoreTracerContext ignoreTracerContext) { + static void notifyFinish(IgnoredTracerContext ignoredTracerContext) { for (IgnoreTracerContextListener listener : LISTENERS) { - listener.afterFinished(ignoreTracerContext); + listener.afterFinished(ignoredTracerContext); } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/TracerContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/TracerContext.java index 19196eac2e0f..e1cc0d650f69 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/TracerContext.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/TracerContext.java @@ -59,6 +59,14 @@ public AbstractSpan createSpan(String operationName, long startTime, boolean isL Span parentSpan = peek(); Span span; if (parentSpan == null) { + if (operationName != null) { + int suffixIdx = operationName.lastIndexOf("."); + if (suffixIdx > -1 && Config.Agent.IGNORE_SUFFIX.contains(operationName.substring(suffixIdx))) { + ContextManager.ContextSwitcher.INSTANCE.toNew(new IgnoredTracerContext(1)); + return ContextManager.activeSpan(); + } + } + if (isLeaf) { span = new LeafSpan(spanIdGenerator++, operationName, startTime); } else { diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/NoopSpan.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/NoopSpan.java new file mode 100644 index 000000000000..459951086004 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/NoopSpan.java @@ -0,0 +1,63 @@ +package org.skywalking.apm.agent.core.context.trace; + +import java.util.Map; +import org.skywalking.apm.agent.core.context.IgnoredTracerContext; + +/** + * The NoopSpan represents a span implementation without any actual operation. + * This span implementation is for {@link IgnoredTracerContext}. + * + * @author wusheng + */ +public class NoopSpan implements AbstractSpan { + @Override + public AbstractSpan setOperationName(String operationName) { + return this; + } + + @Override + public void setPeerHost(String peerHost) { + + } + + @Override + public void setPort(int port) { + + } + + @Override + public void setPeers(String peers) { + + } + + @Override + public AbstractSpan setTag(String key, String value) { + return this; + } + + @Override + public AbstractSpan setTag(String key, boolean value) { + return this; + } + + @Override + public AbstractSpan setTag(String key, Integer value) { + return this; + } + + @Override + public AbstractSpan log(Map fields) { + return this; + } + + @Override + public AbstractSpan log(Throwable t) { + return this; + } + + @Override + public AbstractSpan log(String event) { + return this; + } + +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/Span.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/Span.java index dfb4a2523dfc..28f32f6acacd 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/Span.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/Span.java @@ -13,9 +13,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; -import org.skywalking.apm.agent.core.conf.Config; -import org.skywalking.apm.agent.core.context.ContextManager; -import org.skywalking.apm.agent.core.context.IgnoreTracerContext; import org.skywalking.apm.agent.core.context.tag.BooleanTagItem; import org.skywalking.apm.agent.core.context.tag.IntTagItem; import org.skywalking.apm.agent.core.context.tag.StringTagItem; @@ -191,22 +188,12 @@ public void finish(TraceSegment owner, long endTime) { } /** - * Sets the string name for the logical operation this span represents. - * These is one scenario, which trigger context switch. - * 1) the operations ends with the defined suffix, see {@link Config.Agent#IGNORE_SUFFIX} + * Set the string name for the logical operation this span represents. * * @return this Span instance, for chaining */ public AbstractSpan setOperationName(String operationName) { this.operationName = operationName; - if (this.spanId == 0) { - if (operationName != null) { - int suffixIdx = operationName.lastIndexOf("."); - if (suffixIdx > -1 && Config.Agent.IGNORE_SUFFIX.contains(operationName.substring(suffixIdx))) { - ContextManager.ContextSwitcher.INSTANCE.toNew(new IgnoreTracerContext(1)); - } - } - } return this; } diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/ContextManagerTestCase.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/ContextManagerTestCase.java index 050fa4c877e2..9c56b5e086c7 100644 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/ContextManagerTestCase.java +++ b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/ContextManagerTestCase.java @@ -1,5 +1,6 @@ package org.skywalking.apm.agent.core.context; +import java.lang.reflect.Field; import org.junit.After; import org.junit.Assert; import org.junit.BeforeClass; @@ -7,6 +8,7 @@ import org.skywalking.apm.agent.core.boot.ServiceManager; 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.NoopSpan; import org.skywalking.apm.agent.core.context.trace.TraceSegment; /** @@ -33,6 +35,35 @@ public void testDelegateToTracerContext() { Assert.assertEquals(span, segment.getSpans().get(0)); } + @Test + public void testSwitchToIgnoredTracerContext() throws NoSuchFieldException, IllegalAccessException { + AbstractSpan span = ContextManager.createSpan("/webresource/jquery.js"); + Tags.COMPONENT.set(span, "test"); + + Assert.assertTrue(span instanceof NoopSpan); + Assert.assertTrue(ContextManager.activeSpan() instanceof NoopSpan); + + Field context = ContextManager.class.getDeclaredField("CONTEXT"); + context.setAccessible(true); + AbstractTracerContext tracerContext = ((ThreadLocal)context.get(null)).get(); + + Assert.assertTrue(tracerContext instanceof IgnoredTracerContext); + + ContextManager.stopSpan(); + tracerContext = ((ThreadLocal)context.get(null)).get(); + Assert.assertNull(tracerContext); + + // check normal trace again + span = ContextManager.createSpan("serviceA"); + Tags.COMPONENT.set(span, "test"); + + tracerContext = ((ThreadLocal)context.get(null)).get(); + Assert.assertTrue(tracerContext instanceof TracerContext); + ContextManager.stopSpan(); + tracerContext = ((ThreadLocal)context.get(null)).get(); + Assert.assertNull(tracerContext); + } + @After public void reset() { TracerContext.ListenerManager.remove(TestTracerContextListener.INSTANCE);