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);