Move back resolver in core + added the skipTagsPatterns option over samplers (+tests & examples)
MODIFY
dd-trace-examples/dropwizard-mongo-client/src/main/resources/dd-trace.yaml
dd-trace-examples/dropwizard-mongo-client/src/main/resources/dd-trace.yaml
@@ -19,6 +19,8 @@ sampler:
# RateSample: only a portion of spans are reported to the writer
# - Param 'rate': the portion of spans to keep
type: AllSampler
+ # Skip some traces if the root span tag values matches some regexp patterns
+ # skipTagsPatterns: {"http.url": ".*/demo/add.*"}
# Enable custom tracing (annotations)
enableCustomTracing: true
\ No newline at end of file

MODIFY
dd-trace/src/main/java/com/datadoghq/trace/resolver/DDTracerFactory.java
dd-trace/src/main/java/com/datadoghq/trace/resolver/DDTracerFactory.java
package com.datadoghq.trace.resolver;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Pattern;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.datadoghq.trace.DDTracer;
+import com.datadoghq.trace.sampling.ASampler;
import com.datadoghq.trace.sampling.AllSampler;
import com.datadoghq.trace.sampling.RateSampler;
import com.datadoghq.trace.sampling.Sampler;
@@ -27,6 +32,7 @@ public class DDTracerFactory {
* @param config
* @return the corresponding tracer
*/
+ @SuppressWarnings("unchecked")
public static DDTracer create(TracerConfig config){
String defaultServiceName = config.getDefaultServiceName() != null ? config.getDefaultServiceName() : DDTracer.UNASSIGNED_DEFAULT_SERVICE_NAME;
@@ -45,18 +51,27 @@ public class DDTracerFactory {
}
//Create sampler
- Sampler rateSampler = DDTracer.UNASSIGNED_SAMPLER;
+ Sampler sampler = DDTracer.UNASSIGNED_SAMPLER;
if (config.getSampler() != null && config.getSampler().get("type") != null) {
String type = (String) config.getSampler().get("type");
if (type.equals(AllSampler.class.getSimpleName())) {
- rateSampler = new AllSampler();
+ sampler = new AllSampler();
} else if (type.equals(RateSampler.class.getSimpleName())) {
- rateSampler = new RateSampler((Double) config.getSampler().get("rate"));
+ sampler = new RateSampler((Double) config.getSampler().get("rate"));
+ }
+
+ //Add sampled tags
+ Map<String,String> skipTagsPatterns = (Map<String, String>) config.getSampler().get("skipTagsPatterns");
+ if(skipTagsPatterns!=null && sampler instanceof ASampler){
+ ASampler aSampler = (ASampler) sampler;
+ for(Entry<String,String> entry:skipTagsPatterns.entrySet()){
+ aSampler.addSkipTagPattern(entry.getKey(), Pattern.compile(entry.getValue()));
+ }
}
}
//Create tracer
- return new DDTracer(defaultServiceName, writer, rateSampler);
+ return new DDTracer(defaultServiceName, writer, sampler);
}

RENAME
dd-java-agent/src/main/java/com/datadoghq/trace/resolver/DDTracerResolver.java
dd-trace/src/main/java/com/datadoghq/trace/resolver/DDTracerResolver.java
ADD
dd-trace/src/main/java/com/datadoghq/trace/sampling/ASampler.java
+package com.datadoghq.trace.sampling;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Pattern;
+
+import com.datadoghq.trace.DDSpan;
+
+import io.opentracing.Span;
+
+public abstract class ASampler implements Sampler{
+
+ /**
+ * Sample tags
+ */
+ protected Map<String,Pattern> skipTagsPatterns = new HashMap<String,Pattern>();
+
+ @Override
+ public boolean sample(Span span) {
+ if(span instanceof DDSpan){
+ DDSpan ddSpan = (DDSpan) span;
+
+ //Filter by tag values
+ for(Entry<String, Pattern> entry: skipTagsPatterns.entrySet()){
+ Object value = ddSpan.getTags().get(entry.getKey());
+ if(value != null){
+ String strValue = String.valueOf(value);
+ Pattern skipPattern = entry.getValue();
+ if(skipPattern.matcher(strValue).matches()){
+ return false;
+ }
+ }
+ }
+ }
+
+ return doSample(span);
+ }
+
+ /**
+ * Pattern based skipping of tag values
+ *
+ * @param tag
+ * @param skipPattern
+ */
+ public void addSkipTagPattern(String tag,Pattern skipPattern){
+ skipTagsPatterns.put(tag, skipPattern);
+ }
+
+ protected abstract boolean doSample(Span span);
+
+}

MODIFY
dd-trace/src/main/java/com/datadoghq/trace/sampling/AllSampler.java
dd-trace/src/main/java/com/datadoghq/trace/sampling/AllSampler.java
@@ -5,10 +5,10 @@ import io.opentracing.Span;
/**
* Sampler that always says yes...
*/
-public class AllSampler implements Sampler {
+public class AllSampler extends ASampler {
@Override
- public boolean sample(Span span) {
+ public boolean doSample(Span span) {
return true;
}

MODIFY
dd-trace/src/main/java/com/datadoghq/trace/sampling/RateSampler.java
dd-trace/src/main/java/com/datadoghq/trace/sampling/RateSampler.java
@@ -16,7 +16,7 @@ import io.opentracing.Span;
* It samples randomly, its main purpose is to reduce the instrumentation footprint.
*/
@AutoService(Sampler.class)
-public class RateSampler implements Sampler {
+public class RateSampler extends ASampler {
private final static Logger logger = LoggerFactory.getLogger(RateSampler.class);
@@ -45,7 +45,7 @@ public class RateSampler implements Sampler {
}
@Override
- public boolean sample(Span span) {
+ public boolean doSample(Span span) {
boolean sample = Math.random() <= this.sampleRate;
logger.debug("{} - Span is sampled: {}", span, sample);
return sample;

ADD
dd-trace/src/test/java/com/datadoghq/trace/AllSamplerTest.java
+package com.datadoghq.trace;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import org.junit.Test;
+
+import com.datadoghq.trace.sampling.AllSampler;
+
+public class AllSamplerTest {
+
+
+ @Test
+ public void testAllSampler() {
+
+
+
+ AllSampler sampler = new AllSampler();
+ sampler.addSkipTagPattern("http.url", Pattern.compile(".*/hello"));
+
+ DDSpan mockSpan = mock(DDSpan.class);
+ Map<String,Object> tags = new HashMap<String,Object>();
+ tags.put("http.url", "http://a/hello");
+ when(mockSpan.getTags()).thenReturn(tags).thenReturn(tags);
+
+ assertThat(sampler.sample(mockSpan)).isEqualTo(false);
+
+ tags.put("http.url", "http://a/hello2");
+
+ assertThat(sampler.sample(mockSpan)).isEqualTo(true);
+
+ }
+}
\ No newline at end of file

RENAME
dd-java-agent/src/test/java/com/datadoghq/trace/resolver/TracerResolverTest.java
dd-trace/src/test/java/com/datadoghq/trace/resolver/TracerResolverTest.java
RENAME
dd-java-agent/src/test/resources/dd-trace-decorators.yaml
dd-trace/src/test/resources/dd-trace-decorators.yaml
RENAME
dd-java-agent/src/test/resources/dd-trace.yaml
dd-trace/src/test/resources/dd-trace.yaml
Move back resolver in core + added the skipTagsPatterns option over samplers (+tests & examples)