Skip to content

Commit

Permalink
Provide ignore mechanism for TracerContext.
Browse files Browse the repository at this point in the history
  • Loading branch information
wu-sheng committed Jun 15, 2017
1 parent 1d3f7ba commit c88cf2a
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 32 deletions.
Expand Up @@ -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
Expand All @@ -95,7 +95,7 @@ public void afterFinished(TraceSegment traceSegment) {
}

@Override
public void afterFinished(IgnoreTracerContext traceSegment) {
public void afterFinished(IgnoredTracerContext traceSegment) {
CONTEXT.remove();
}

Expand Down
Expand Up @@ -5,5 +5,5 @@
* @author wusheng
*/
public interface IgnoreTracerContextListener {
void afterFinished(IgnoreTracerContext traceSegment);
void afterFinished(IgnoredTracerContext traceSegment);
}
Expand Up @@ -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 <code>IgnoreTracerContext</code> represent a context should be ignored.
* The <code>IgnoredTracerContext</code> represent a context should be ignored.
* So it just maintains the stack with integer depth.
* All operations through this <code>IgnoreTracerContext</code> will be ignored, with low gc cost.
*
* TODO: Can't return null span
* All operations through this <code>IgnoredTracerContext</code> 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;
}

Expand All @@ -38,7 +39,7 @@ public String getGlobalTraceId() {
@Override
public AbstractSpan createSpan(String operationName, boolean isLeaf) {
stackDepth++;
return null;
return NOOP_SPAN;
}

@Override
Expand All @@ -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);
}
}

Expand All @@ -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);
}
}

Expand Down
Expand Up @@ -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 {
Expand Down
@@ -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 <code>NoopSpan</code> 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<String, String> fields) {
return this;
}

@Override
public AbstractSpan log(Throwable t) {
return this;
}

@Override
public AbstractSpan log(String event) {
return this;
}

}
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
@@ -1,12 +1,14 @@
package org.skywalking.apm.agent.core.context;

import java.lang.reflect.Field;
import org.junit.After;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
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;

/**
Expand All @@ -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<AbstractTracerContext>)context.get(null)).get();

Assert.assertTrue(tracerContext instanceof IgnoredTracerContext);

ContextManager.stopSpan();
tracerContext = ((ThreadLocal<AbstractTracerContext>)context.get(null)).get();
Assert.assertNull(tracerContext);

// check normal trace again
span = ContextManager.createSpan("serviceA");
Tags.COMPONENT.set(span, "test");

tracerContext = ((ThreadLocal<AbstractTracerContext>)context.get(null)).get();
Assert.assertTrue(tracerContext instanceof TracerContext);
ContextManager.stopSpan();
tracerContext = ((ThreadLocal<AbstractTracerContext>)context.get(null)).get();
Assert.assertNull(tracerContext);
}

@After
public void reset() {
TracerContext.ListenerManager.remove(TestTracerContextListener.INSTANCE);
Expand Down

0 comments on commit c88cf2a

Please sign in to comment.