Conflicts merging
This commit is contained in:
commit
abdbfffdff
|
|
@ -5,6 +5,6 @@ import com.datadoghq.trace.impl.DDSpan;
|
|||
|
||||
public interface Sampler {
|
||||
|
||||
public boolean sample(DDSpan span);
|
||||
boolean sample(DDSpan span);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public interface SpanSerializer {
|
|||
* @return the serialized object
|
||||
* @throws Exception
|
||||
*/
|
||||
public String serialize(Span span) throws Exception;
|
||||
String serialize(Span span) throws Exception;
|
||||
|
||||
/**
|
||||
* A collection of Span to serialize
|
||||
|
|
@ -23,7 +23,7 @@ public interface SpanSerializer {
|
|||
* @return the serialized objects
|
||||
* @throws Exception
|
||||
*/
|
||||
public String serialize(Object spans) throws Exception;
|
||||
String serialize(Object spans) throws Exception;
|
||||
|
||||
/**
|
||||
* Deserialize a string to convert it in a Span or a Trace
|
||||
|
|
@ -32,6 +32,6 @@ public interface SpanSerializer {
|
|||
* @return A Span or a Trace (List<Span>)
|
||||
* @throws Exception
|
||||
*/
|
||||
public Object deserialize(String str) throws Exception;
|
||||
Object deserialize(String str) throws Exception;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ public interface Writer {
|
|||
*
|
||||
* @param trace the list of spans to write
|
||||
*/
|
||||
public void write(List<Span> trace);
|
||||
void write(List<Span> trace);
|
||||
|
||||
/**
|
||||
* Indicates to the writer that no future writing will come and it should terminates all connections and tasks
|
||||
*/
|
||||
public void close();
|
||||
void close();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,27 @@
|
|||
package com.datadoghq.trace.impl;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.opentracing.Span;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
import io.opentracing.Span;
|
||||
|
||||
public class DDSpanContext implements io.opentracing.SpanContext {
|
||||
|
||||
private static final String SPAN_TYPE_DEFAULT = "custom";
|
||||
// Opentracing attributes
|
||||
protected long traceId;
|
||||
protected long spanId;
|
||||
protected long parentId;
|
||||
protected Map<String, String> baggageItems;
|
||||
// DD attributes
|
||||
|
||||
protected String serviceName;
|
||||
protected String resourceName;
|
||||
protected boolean errorFlag;
|
||||
protected Map<String, Object> metrics;
|
||||
protected String spanType;
|
||||
protected final List<Span> trace;
|
||||
// Others attributes
|
||||
|
|
@ -36,9 +36,7 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
String resourceName,
|
||||
Map<String, String> baggageItems,
|
||||
boolean errorFlag,
|
||||
Map<String, Object> metrics,
|
||||
String spanType,
|
||||
boolean sampled,
|
||||
List<Span> trace,
|
||||
DDTracer tracer) {
|
||||
|
||||
|
|
@ -54,9 +52,7 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
this.serviceName = serviceName;
|
||||
this.resourceName = resourceName;
|
||||
this.errorFlag = errorFlag;
|
||||
this.metrics = metrics;
|
||||
this.spanType = spanType;
|
||||
this.sampled = sampled;
|
||||
|
||||
if (trace == null) {
|
||||
this.trace = new ArrayList<Span>();
|
||||
|
|
@ -67,22 +63,6 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
this.tracer = tracer;
|
||||
}
|
||||
|
||||
protected static DDSpanContext newContext(long generateId, String serviceName, String resourceName) {
|
||||
DDSpanContext context = new DDSpanContext(
|
||||
// Opentracing attributes
|
||||
generateId, generateId, 0L,
|
||||
// DD attributes
|
||||
serviceName, resourceName,
|
||||
// Other stuff
|
||||
null, false, null,
|
||||
DDSpanContext.SPAN_TYPE_DEFAULT, true,
|
||||
null, null
|
||||
|
||||
);
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
public long getTraceId() {
|
||||
return this.traceId;
|
||||
}
|
||||
|
|
@ -107,18 +87,11 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
return errorFlag;
|
||||
}
|
||||
|
||||
public Map<String, Object> getMetrics() {
|
||||
return metrics;
|
||||
}
|
||||
|
||||
public String getSpanType() {
|
||||
return spanType;
|
||||
}
|
||||
|
||||
public boolean getSampled() {
|
||||
return sampled;
|
||||
}
|
||||
|
||||
public void setBaggageItem(String key, String value) {
|
||||
this.baggageItems.put(key, value);
|
||||
}
|
||||
|
|
@ -172,8 +145,6 @@ public class DDSpanContext implements io.opentracing.SpanContext {
|
|||
DDSpanContext other = (DDSpanContext) obj;
|
||||
if (spanId != other.spanId)
|
||||
return false;
|
||||
if (traceId != other.traceId)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return traceId == other.traceId;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package com.datadoghq.trace.impl;
|
|||
import com.datadoghq.trace.Sampler;
|
||||
import com.datadoghq.trace.Writer;
|
||||
import com.datadoghq.trace.writer.impl.LoggingWritter;
|
||||
|
||||
import io.opentracing.Span;
|
||||
import io.opentracing.SpanContext;
|
||||
import io.opentracing.propagation.Format;
|
||||
|
|
@ -22,10 +21,10 @@ public class DDTracer implements io.opentracing.Tracer {
|
|||
|
||||
private final static Logger logger = LoggerFactory.getLogger(DDTracer.class);
|
||||
|
||||
public DDTracer(){
|
||||
this(new LoggingWritter(),new AllSampler());
|
||||
public DDTracer() {
|
||||
this(new LoggingWritter(), new AllSampler());
|
||||
}
|
||||
|
||||
|
||||
public DDTracer(Writer writer, Sampler sampler) {
|
||||
this.writer = writer;
|
||||
this.sampler = sampler;
|
||||
|
|
@ -44,7 +43,10 @@ public class DDTracer implements io.opentracing.Tracer {
|
|||
}
|
||||
|
||||
public void write(List<Span> trace) {
|
||||
this.writer.write(trace);
|
||||
if (trace.size() == 0) return;
|
||||
if (this.sampler.sample((DDSpan)trace.get(0))) {
|
||||
this.writer.write(trace);
|
||||
}
|
||||
}
|
||||
|
||||
public class DDSpanBuilder implements SpanBuilder {
|
||||
|
|
@ -146,7 +148,7 @@ public class DDTracer implements io.opentracing.Tracer {
|
|||
|
||||
long generatedId = generateNewId();
|
||||
DDSpanContext context;
|
||||
DDSpanContext p = this.parent != null ? (DDSpanContext) this.parent.context() : null;
|
||||
DDSpanContext p = this.parent != null ? this.parent.context() : null;
|
||||
|
||||
// some attributes are inherited from the parent
|
||||
context = new DDSpanContext(
|
||||
|
|
@ -157,9 +159,7 @@ public class DDTracer implements io.opentracing.Tracer {
|
|||
this.resourceName,
|
||||
this.parent == null ? null : p.getBaggageItems(),
|
||||
errorFlag,
|
||||
null,
|
||||
this.parent == null ? this.spanType : p.getSpanType(),
|
||||
true,
|
||||
this.parent == null ? this.spanType : p.getSpanType(),
|
||||
this.parent == null ? null : p.getTrace(),
|
||||
DDTracer.this
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
package com.datadoghq.trace.impl;
|
||||
|
||||
|
||||
import com.datadoghq.trace.Sampler;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class RateSampler implements Sampler {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(RateSampler.class);
|
||||
private final double sampleRate;
|
||||
|
||||
public RateSampler(double sampleRate) {
|
||||
|
||||
if (sampleRate <= 0) {
|
||||
sampleRate = 1;
|
||||
logger.error("SampleRate is negative or null, disabling the sampler");
|
||||
} else if (sampleRate > 1) {
|
||||
sampleRate = 1;
|
||||
}
|
||||
|
||||
this.sampleRate = sampleRate;
|
||||
logger.debug("Initializing the RateSampler, sampleRate=" + this.sampleRate * 100 + "%");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sample(DDSpan span) {
|
||||
boolean sample = Math.random() <= this.sampleRate;
|
||||
logger.debug(span + " - Span is sampled: " + sample);
|
||||
return sample;
|
||||
}
|
||||
|
||||
public double getSampleRate() {
|
||||
return this.sampleRate;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.datadoghq.trace.Writer;
|
||||
import com.datadoghq.trace.impl.DDSpan;
|
||||
|
||||
import io.opentracing.Span;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +1,15 @@
|
|||
package com.datadoghq.trace.impl;
|
||||
|
||||
import com.datadoghq.trace.Writer;
|
||||
import com.datadoghq.trace.writer.impl.DDAgentWriter;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class DDSpanBuilderTest {
|
||||
|
|
@ -22,8 +18,7 @@ public class DDSpanBuilderTest {
|
|||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
Writer w = mock(Writer.class);
|
||||
tracer = new DDTracer(w, null);
|
||||
tracer = new DDTracer();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -36,7 +31,7 @@ public class DDSpanBuilderTest {
|
|||
public void shouldBuildSimpleSpan() {
|
||||
|
||||
final String expectedName = "fakeName";
|
||||
DDSpan span = (DDSpan) tracer.buildSpan(expectedName).withServiceName("foo").start();
|
||||
DDSpan span = tracer.buildSpan(expectedName).withServiceName("foo").start();
|
||||
assertThat(span.getOperationName()).isEqualTo(expectedName);
|
||||
}
|
||||
|
||||
|
|
@ -52,7 +47,7 @@ public class DDSpanBuilderTest {
|
|||
}
|
||||
};
|
||||
|
||||
DDSpan span = (DDSpan) tracer
|
||||
DDSpan span = tracer
|
||||
.buildSpan(expectedName)
|
||||
.withServiceName("foo")
|
||||
.withTag("1", (Boolean) tags.get("1"))
|
||||
|
|
@ -65,7 +60,7 @@ public class DDSpanBuilderTest {
|
|||
|
||||
// with no tag provided
|
||||
|
||||
span = (DDSpan) tracer
|
||||
span = tracer
|
||||
.buildSpan(expectedName)
|
||||
.withServiceName("foo")
|
||||
.start();
|
||||
|
|
@ -78,7 +73,7 @@ public class DDSpanBuilderTest {
|
|||
final String expectedService = "fakeService";
|
||||
final String expectedType = "fakeType";
|
||||
|
||||
span = (DDSpan) tracer
|
||||
span = tracer
|
||||
.buildSpan(expectedName)
|
||||
.withServiceName("foo")
|
||||
.withResourceName(expectedResource)
|
||||
|
|
@ -87,7 +82,7 @@ public class DDSpanBuilderTest {
|
|||
.withSpanType(expectedType)
|
||||
.start();
|
||||
|
||||
DDSpanContext actualContext = (DDSpanContext) span.context();
|
||||
DDSpanContext actualContext = span.context();
|
||||
|
||||
assertThat(actualContext.getResourceName()).isEqualTo(expectedResource);
|
||||
assertThat(actualContext.getErrorFlag()).isTrue();
|
||||
|
|
@ -102,7 +97,7 @@ public class DDSpanBuilderTest {
|
|||
final long expectedTimestamp = 4875178020000L;
|
||||
final String expectedName = "fakeName";
|
||||
|
||||
DDSpan span = (DDSpan) tracer
|
||||
DDSpan span = tracer
|
||||
.buildSpan(expectedName)
|
||||
.withServiceName("foo")
|
||||
.withStartTimestamp(expectedTimestamp)
|
||||
|
|
@ -112,7 +107,7 @@ public class DDSpanBuilderTest {
|
|||
|
||||
// auto-timestamp in nanoseconds
|
||||
long tick = System.currentTimeMillis() * 1000000L;
|
||||
span = (DDSpan) tracer
|
||||
span = tracer
|
||||
.buildSpan(expectedName)
|
||||
.withServiceName("foo")
|
||||
.start();
|
||||
|
|
@ -134,16 +129,17 @@ public class DDSpanBuilderTest {
|
|||
|
||||
when(mockedSpan.context()).thenReturn(mockedContext);
|
||||
when(mockedContext.getSpanId()).thenReturn(spanId);
|
||||
when(mockedContext.getServiceName()).thenReturn("foo");
|
||||
|
||||
final String expectedName = "fakeName";
|
||||
|
||||
DDSpan span = (DDSpan) tracer
|
||||
DDSpan span = tracer
|
||||
.buildSpan(expectedName)
|
||||
.withServiceName("foo")
|
||||
.asChildOf(mockedSpan)
|
||||
.start();
|
||||
|
||||
DDSpanContext actualContext = (DDSpanContext) span.context();
|
||||
DDSpanContext actualContext = span.context();
|
||||
|
||||
assertThat(actualContext.getParentId()).isEqualTo(expectedParentId);
|
||||
|
||||
|
|
@ -159,7 +155,7 @@ public class DDSpanBuilderTest {
|
|||
final String expectedBaggageItemKey = "fakeKey";
|
||||
final String expectedBaggageItemValue = "fakeValue";
|
||||
|
||||
DDSpan parent = (DDSpan) tracer
|
||||
DDSpan parent = tracer
|
||||
.buildSpan(expectedName)
|
||||
.withServiceName("foo")
|
||||
.withServiceName(expectedServiceName)
|
||||
|
|
@ -168,7 +164,7 @@ public class DDSpanBuilderTest {
|
|||
|
||||
parent.setBaggageItem(expectedBaggageItemKey, expectedBaggageItemValue);
|
||||
|
||||
DDSpan span = (DDSpan) tracer
|
||||
DDSpan span = tracer
|
||||
.buildSpan(expectedName)
|
||||
.withServiceName("foo")
|
||||
.asChildOf(parent)
|
||||
|
|
@ -176,8 +172,8 @@ public class DDSpanBuilderTest {
|
|||
|
||||
assertThat(span.getOperationName()).isEqualTo(expectedName);
|
||||
assertThat(span.getBaggageItem(expectedBaggageItemKey)).isEqualTo(expectedBaggageItemValue);
|
||||
assertThat(((DDSpanContext) span.context()).getServiceName()).isEqualTo(expectedServiceName);
|
||||
assertThat(((DDSpanContext) span.context()).getResourceName()).isNotEqualTo(expectedResourceName);
|
||||
assertThat(span.context().getServiceName()).isEqualTo(expectedServiceName);
|
||||
assertThat(span.context().getResourceName()).isNotEqualTo(expectedResourceName);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -191,13 +187,13 @@ public class DDSpanBuilderTest {
|
|||
// spans[1] has a predictable duration
|
||||
// others are just for fun
|
||||
|
||||
DDSpan root = (DDSpan) tracer.buildSpan("fake_O").withServiceName("foo").start();
|
||||
DDSpan root = tracer.buildSpan("fake_O").withServiceName("foo").start();
|
||||
spans.add(root);
|
||||
|
||||
long tickStart = System.currentTimeMillis();
|
||||
spans.add((DDSpan) tracer.buildSpan("fake_" + 1).withServiceName("foo").asChildOf(spans.get(0)).withStartTimestamp(tickStart).start());
|
||||
spans.add(tracer.buildSpan("fake_" + 1).withServiceName("foo").asChildOf(spans.get(0)).withStartTimestamp(tickStart).start());
|
||||
for (int i = 2; i <= 10; i++) {
|
||||
spans.add((DDSpan) tracer.buildSpan("fake_" + i).withServiceName("foo").asChildOf(spans.get(i - 1)).start());
|
||||
spans.add(tracer.buildSpan("fake_" + i).withServiceName("foo").asChildOf(spans.get(i - 1)).start());
|
||||
}
|
||||
|
||||
Thread.sleep(300);
|
||||
|
|
@ -210,13 +206,9 @@ public class DDSpanBuilderTest {
|
|||
assertThat(spans.get((int) (Math.random() * nbSamples)).context.getTrace()).containsAll(spans);
|
||||
|
||||
root.finish();
|
||||
//TODO Check order
|
||||
//assertThat(root.getTrace()).containsExactly(spans)
|
||||
assertThat(spans.get(1).durationNano).isEqualTo((tickEnd - tickStart) * 1000000L);
|
||||
for (DDSpan span : spans) {
|
||||
assertThat(span.getDurationNano()).isNotNull();
|
||||
assertThat(span.getDurationNano()).isNotZero();
|
||||
}
|
||||
|
||||
// not comparing the nano
|
||||
assertThat(spans.get(1).durationNano / 1000000L).isEqualTo((tickEnd - tickStart));
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,53 +8,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
public class DDSpanTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void testBaggageItem() {
|
||||
|
||||
/*
|
||||
DDSpanContext context = new DDSpanContext();
|
||||
|
||||
final String expectedBaggageItemKey = "fakeKey";
|
||||
final String expectedBaggageItemValue = "fakeValue";
|
||||
|
||||
|
||||
DDSpan span = new DDSpan(
|
||||
null,
|
||||
"fakeName",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
context
|
||||
);
|
||||
|
||||
assertThat(span.context().baggageItems()).isEmpty();
|
||||
|
||||
span.setBaggageItem(expectedBaggageItemKey, expectedBaggageItemValue);
|
||||
|
||||
assertThat(span.getBaggageItem(expectedBaggageItemKey)).isEqualTo(expectedBaggageItemValue);*/
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSetOperationName() {
|
||||
|
||||
/* final String expectedOperationName1 = "fake";
|
||||
final String expectedOperationName2 = "fake";
|
||||
|
||||
DDSpan span = new DDSpan(
|
||||
null,
|
||||
expectedOperationName1,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
|
||||
assertThat(span.getOperationName()).isEqualTo(expectedOperationName1);
|
||||
|
||||
span.setOperationName(expectedOperationName2);
|
||||
assertThat(span.getOperationName()).isEqualTo(expectedOperationName1);
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void shouldHaveServiceName() {
|
||||
new DDTracer().buildSpan("operationName").start();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package com.datadoghq.trace.impl;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.datadoghq.trace.Writer;
|
||||
|
||||
import io.opentracing.Span;
|
||||
|
||||
|
||||
public class DDTracerTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void write() throws Exception {
|
||||
|
||||
Writer writer = mock(Writer.class);
|
||||
RateSampler sampler = mock(RateSampler.class);
|
||||
DDSpan span = mock(DDSpan.class);
|
||||
|
||||
// Rate 0.5
|
||||
when(sampler.sample(any(DDSpan.class)))
|
||||
.thenReturn(true)
|
||||
.thenReturn(false);
|
||||
|
||||
List<Span> spans = new ArrayList<Span>();
|
||||
spans.add(span);
|
||||
spans.add(span);
|
||||
spans.add(span);
|
||||
|
||||
DDTracer tracer = new DDTracer(writer, sampler);
|
||||
|
||||
tracer.write(spans);
|
||||
tracer.write(spans);
|
||||
|
||||
verify(sampler, times(2)).sample(span);
|
||||
verify(writer, times(1)).write(spans);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package com.datadoghq.trace.impl;
|
||||
|
||||
import com.datadoghq.trace.Sampler;
|
||||
import com.datadoghq.trace.impl.DDSpan;
|
||||
import com.datadoghq.trace.impl.RateSampler;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
public class RateSamplerTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void testRateSampler() {
|
||||
|
||||
DDSpan mockSpan = mock(DDSpan.class);
|
||||
|
||||
final double sampleRate = 0.35;
|
||||
final int iterations = 100000;
|
||||
Sampler sampler = new RateSampler(sampleRate);
|
||||
|
||||
int kept = 0;
|
||||
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
if (sampler.sample(mockSpan)) {
|
||||
kept++;
|
||||
}
|
||||
}
|
||||
|
||||
assertThat(((double) kept / iterations)).isBetween(sampleRate - 0.01, sampleRate + 0.01);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRateBoundaries() {
|
||||
|
||||
RateSampler sampler = new RateSampler(1000);
|
||||
assertThat(sampler.getSampleRate()).isEqualTo(1);
|
||||
|
||||
sampler = new RateSampler(-1000);
|
||||
assertThat(sampler.getSampleRate()).isEqualTo(1);
|
||||
|
||||
sampler = new RateSampler(0.337);
|
||||
assertThat(sampler.getSampleRate()).isEqualTo(0.337);
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue