Migration against OT-0.30.0

This commit is contained in:
renaudboutet 2017-06-07 16:58:55 +02:00
parent 39a9eb7763
commit 4080943234
17 changed files with 572 additions and 396 deletions

View File

@ -0,0 +1,59 @@
package com.datadoghq.trace;
import io.opentracing.ActiveSpan;
/**
* Base implementation for opentracing {@link ActiveSpan}
*/
public class DDActiveSpan extends DDBaseSpan<ActiveSpan> implements ActiveSpan{
protected final DDActiveSpan parent;
protected DDActiveSpan(DDActiveSpan parent,DDSpan span) {
super(span.startTimeMicro, span.context());
this.startTimeNano = span.startTimeNano;
this.durationNano = span.durationNano;
this.parent = parent;
}
protected DDActiveSpan(DDActiveSpan parent,long timestampMicro, DDSpanContext context) {
super(timestampMicro, context);
this.parent = parent;
}
/**
* @return the generating parent if not null
*/
public DDActiveSpan getParent() {
return parent;
}
@Override
public void deactivate() {
context().getTracer().deactivate(this);
finish();
}
@Override
public Continuation capture() {
return new DDContinuation();
}
@Override
protected ActiveSpan thisInstance() {
return this;
}
public class DDContinuation implements Continuation{
@Override
public ActiveSpan activate() {
//Reactivate the current span
context().getTracer().makeActive(DDActiveSpan.this);
//And return the encapsulating ActiveSpan
return DDActiveSpan.this;
}
}
}

View File

@ -0,0 +1,332 @@
package com.datadoghq.trace;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.opentracing.BaseSpan;
@SuppressWarnings("rawtypes")
public abstract class DDBaseSpan<S extends BaseSpan> implements BaseSpan<S> {
/**
* StartTime stores the creation time of the span in milliseconds
*/
protected long startTimeMicro;
/**
* StartTimeNano stores the only the nanoseconds for more accuracy
*/
protected long startTimeNano;
/**
* The duration in nanoseconds computed using the startTimeMicro and startTimeNano
*/
protected long durationNano;
/**
* The context attached to the span
*/
protected final DDSpanContext context;
private final static Logger logger = LoggerFactory.getLogger(DDBaseSpan.class);
/**
* A simple constructor.
* Currently, users have
*
* @param timestampMicro if set, use this time instead of the auto-generated time
* @param context the context
*/
protected DDBaseSpan(
long timestampMicro,
DDSpanContext context) {
this.context = context;
// record the start time in nano (current milli + nano delta)
if (timestampMicro == 0L) {
this.startTimeMicro = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
} else {
this.startTimeMicro = timestampMicro;
}
this.startTimeNano = System.nanoTime();
// track each span of the trace
this.context.getTrace().add(this);
}
public final void finish() {
this.durationNano = System.nanoTime() - startTimeNano;
afterFinish();
}
public final void finish(long stoptimeMicros) {
this.durationNano = TimeUnit.MICROSECONDS.toNanos(stoptimeMicros - this.startTimeMicro);
afterFinish();
}
/**
* Close the span. If the current span is the parent, check if each child has also been closed
* If not, warned it
*/
protected final void afterFinish() {
logger.debug("{} - Closing the span.", this);
// warn if one of the parent's children is not finished
if (this.isRootSpan()) {
List<DDBaseSpan<?>> spans = this.context().getTrace();
for (DDBaseSpan<?> span : spans) {
if (((DDBaseSpan<?>) span).getDurationNano() == 0L) {
logger.warn("{} - The parent span is marked as finished but this span isn't. You have to close each children.", this);
}
}
this.context.getTracer().write(this.context.getTrace());
logger.debug("{} - Write the trace", this);
}
}
/* (non-Javadoc)
* @see io.opentracing.Span#close()
*/
public final void close() {
this.finish();
}
/**
* Check if the span is the root parent. It means that the traceId is the same as the spanId
*
* @return true if root, false otherwise
*/
protected final boolean isRootSpan() {
if (context().getTrace().isEmpty()) {
return false;
}
// First item of the array AND tracer set
DDSpan first = (DDSpan) context().getTrace().get(0);
return first.context().getSpanId() == this.context().getSpanId() && this.context.getTracer() != null;
}
/* (non-Javadoc)
* @see io.opentracing.BaseSpan#setTag(java.lang.String, java.lang.String)
*/
@Override
public final S setTag(String tag, String value) {
this.context().setTag(tag, (Object) value);
return thisInstance();
}
/* (non-Javadoc)
* @see io.opentracing.BaseSpan#setTag(java.lang.String, boolean)
*/
@Override
public final S setTag(String tag, boolean value) {
this.context().setTag(tag, (Object) value);
return thisInstance();
}
/* (non-Javadoc)
* @see io.opentracing.BaseSpan#setTag(java.lang.String, java.lang.Number)
*/
@Override
public final S setTag(String tag, Number value) {
this.context().setTag(tag, (Object) value);
return thisInstance();
}
/* (non-Javadoc)
* @see io.opentracing.BaseSpan#context()
*/
@Override
public final DDSpanContext context() {
return this.context;
}
/* (non-Javadoc)
* @see io.opentracing.BaseSpan#getBaggageItem(java.lang.String)
*/
@Override
public final String getBaggageItem(String key) {
return this.context.getBaggageItem(key);
}
/* (non-Javadoc)
* @see io.opentracing.BaseSpan#setBaggageItem(java.lang.String, java.lang.String)
*/
@Override
public final S setBaggageItem(String key, String value) {
this.context.setBaggageItem(key, value);
return thisInstance();
}
/* (non-Javadoc)
* @see io.opentracing.BaseSpan#setOperationName(java.lang.String)
*/
@Override
public final S setOperationName(String operationName) {
this.context().setOperationName(operationName);
return thisInstance();
}
/* (non-Javadoc)
* @see io.opentracing.BaseSpan#log(java.util.Map)
*/
@Override
public final S log(Map<String, ?> map) {
logger.debug("`log` method is not implemented. Doing nothing");
return thisInstance();
}
/* (non-Javadoc)
* @see io.opentracing.BaseSpan#log(long, java.util.Map)
*/
@Override
public final S log(long l, Map<String, ?> map) {
logger.debug("`log` method is not implemented. Doing nothing");
return thisInstance();
}
/* (non-Javadoc)
* @see io.opentracing.BaseSpan#log(java.lang.String)
*/
@Override
public final S log(String s) {
logger.debug("`log` method is not implemented. Provided log: {}",s);
return thisInstance();
}
/* (non-Javadoc)
* @see io.opentracing.BaseSpan#log(long, java.lang.String)
*/
@Override
public final S log(long l, String s) {
logger.debug("`log` method is not implemented. Provided log: {}",s);
return thisInstance();
}
/* (non-Javadoc)
* @see io.opentracing.BaseSpan#log(java.lang.String, java.lang.Object)
*/
@Override
public final S log(String s, Object o) {
logger.debug("`log` method is not implemented. Provided log: {}",s);
return thisInstance();
}
/* (non-Javadoc)
* @see io.opentracing.BaseSpan#log(long, java.lang.String, java.lang.Object)
*/
@Override
public final S log(long l, String s, Object o) {
logger.debug("`log` method is not implemented. Provided log: {}",s);
return thisInstance();
}
public final S setServiceName(String serviceName) {
this.context().setServiceName(serviceName);
return thisInstance();
}
public final S setResourceName(String resourceName) {
this.context().setResourceName(resourceName);
return thisInstance();
}
public final S setSpanType(String type) {
this.context().setSpanType(type);
return thisInstance();
}
protected abstract S thisInstance();
//Getters and JSON serialisation instructions
/**
* Meta merges baggage and tags (stringified values)
*
* @return merged context baggage and tags
*/
@JsonGetter
public Map<String, String> getMeta() {
Map<String, String> meta = new HashMap<String, String>();
for (Entry<String, String> entry : context().getBaggageItems().entrySet()) {
meta.put(entry.getKey(), entry.getValue());
}
for (Entry<String, Object> entry : getTags().entrySet()) {
meta.put(entry.getKey(), String.valueOf(entry.getValue()));
}
return meta;
}
@JsonGetter("start")
public long getStartTime() {
return startTimeMicro * 1000L;
}
@JsonGetter("duration")
public long getDurationNano() {
return durationNano;
}
@JsonGetter("service")
public String getServiceName() {
return context.getServiceName();
}
@JsonGetter("trace_id")
public long getTraceId() {
return context.getTraceId();
}
@JsonGetter("span_id")
public long getSpanId() {
return context.getSpanId();
}
@JsonGetter("parent_id")
public long getParentId() {
return context.getParentId();
}
@JsonGetter("resource")
public String getResourceName() {
return context.getResourceName();
}
@JsonGetter("name")
public String getOperationName() {
return context.getOperationName();
}
@JsonIgnore
public Map<String, Object> getTags() {
return this.context().getTags();
}
@JsonGetter
public String getType() {
return context.getSpanType();
}
@JsonGetter
public int getError() {
return context.getErrorFlag() ? 1 : 0;
}
@Override
public String toString() {
return context.toString();
}
}

View File

@ -1,16 +1,6 @@
package com.datadoghq.trace;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.opentracing.Span;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
/**
* Represents an in-flight span in the opentracing system.
@ -18,27 +8,7 @@ import java.util.concurrent.TimeUnit;
* <p>Spans are created by the {@link DDTracer#buildSpan}.
* This implementation adds some features according to the DD agent.
*/
public class DDSpan implements io.opentracing.Span {
/**
* StartTime stores the creation time of the span in milliseconds
*/
private long startTimeMicro;
/**
* StartTimeNano stores the only the nanoseconds for more accuracy
*/
private long startTimeNano;
/**
* The duration in nanoseconds computed using the startTimeMicro and startTimeNano
*/
private long durationNano;
/**
* The context attached to the span
*/
private final DDSpanContext context;
private final static Logger logger = LoggerFactory.getLogger(DDSpan.class);
public class DDSpan extends DDBaseSpan<Span> implements Span {
/**
* A simple constructor.
@ -50,276 +20,12 @@ public class DDSpan implements io.opentracing.Span {
protected DDSpan(
long timestampMicro,
DDSpanContext context) {
this.context = context;
// record the start time in nano (current milli + nano delta)
if (timestampMicro == 0L) {
this.startTimeMicro = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
} else {
this.startTimeMicro = timestampMicro;
}
this.startTimeNano = System.nanoTime();
// track each span of the trace
this.context.getTrace().add(this);
}
/* (non-Javadoc)
* @see io.opentracing.Span#finish()
*/
public void finish() {
this.durationNano = System.nanoTime() - startTimeNano;
afterFinish();
}
/* (non-Javadoc)
* @see io.opentracing.Span#finish(long)
*/
public void finish(long stoptimeMicros) {
this.durationNano = TimeUnit.MICROSECONDS.toNanos(stoptimeMicros - this.startTimeMicro);
afterFinish();
}
/**
* Close the span. If the current span is the parent, check if each child has also been closed
* If not, warned it
*/
protected void afterFinish() {
logger.debug("{} - Closing the span.", this);
// warn if one of the parent's children is not finished
if (this.isRootSpan()) {
List<Span> spans = this.context.getTrace();
for (Span span : spans) {
if (((DDSpan) span).getDurationNano() == 0L) {
logger.warn("{} - The parent span is marked as finished but this span isn't. You have to close each children.", this);
}
}
this.context.getTracer().write(this.context.getTrace());
logger.debug("{} - Write the trace", this);
}
}
/* (non-Javadoc)
* @see io.opentracing.Span#close()
*/
public void close() {
this.finish();
}
/**
* Check if the span is the root parent. It means that the traceId is the same as the spanId
*
* @return true if root, false otherwise
*/
private boolean isRootSpan() {
if (context().getTrace().isEmpty()) {
return false;
}
// First item of the array AND tracer set
DDSpan first = (DDSpan) context().getTrace().get(0);
return first.context.getSpanId() == this.context.getSpanId() && this.context.getTracer() != null;
}
/* (non-Javadoc)
* @see io.opentracing.Span#setTag(java.lang.String, java.lang.String)
*/
public Span setTag(String tag, String value) {
this.context().setTag(tag, (Object) value);
return this;
}
/* (non-Javadoc)
* @see io.opentracing.Span#setTag(java.lang.String, boolean)
*/
public Span setTag(String tag, boolean value) {
this.context().setTag(tag, (Object) value);
return this;
}
/* (non-Javadoc)
* @see io.opentracing.Span#setTag(java.lang.String, java.lang.Number)
*/
public Span setTag(String tag, Number value) {
this.context().setTag(tag, (Object) value);
return this;
super(timestampMicro,context);
}
/* (non-Javadoc)
* @see io.opentracing.Span#context()
*/
public DDSpanContext context() {
return this.context;
}
/* (non-Javadoc)
* @see io.opentracing.Span#setBaggageItem(java.lang.String, java.lang.String)
*/
public Span setBaggageItem(String key, String value) {
this.context.setBaggageItem(key, value);
return this;
}
/* (non-Javadoc)
* @see io.opentracing.Span#getBaggageItem(java.lang.String)
*/
public String getBaggageItem(String key) {
return this.context.getBaggageItem(key);
}
/* (non-Javadoc)
* @see io.opentracing.Span#setOperationName(java.lang.String)
*/
public Span setOperationName(String operationName) {
this.context().setOperationName(operationName);
return this;
}
/* (non-Javadoc)
* @see io.opentracing.Span#log(java.lang.String, java.lang.Object)
*/
public Span log(Map<String, ?> map) {
logger.debug("`log` method is not implemented. Doing nothing");
return this;
}
/* (non-Javadoc)
* @see io.opentracing.Span#log(java.lang.String, java.lang.Object)
*/
public Span log(long l, Map<String, ?> map) {
logger.debug("`log` method is not implemented. Doing nothing");
return this;
}
/* (non-Javadoc)
* @see io.opentracing.Span#log(java.lang.String, java.lang.Object)
*/
public Span log(String s) {
logger.debug("`log` method is not implemented. Provided log: {}",s);
return this;
}
/* (non-Javadoc)
* @see io.opentracing.Span#log(java.lang.String, java.lang.Object)
*/
public Span log(long l, String s) {
logger.debug("`log` method is not implemented. Provided log: {}",s);
return this;
}
/* (non-Javadoc)
* @see io.opentracing.Span#log(java.lang.String, java.lang.Object)
*/
public Span log(String s, Object o) {
logger.debug("`log` method is not implemented. Provided log: {}",s);
return this;
}
/* (non-Javadoc)
* @see io.opentracing.Span#log(long, java.lang.String, java.lang.Object)
*/
public Span log(long l, String s, Object o) {
logger.debug("`log` method is not implemented. Provided log: {}",s);
return this;
}
//Getters and JSON serialisation instructions
/**
* Meta merges baggage and tags (stringified values)
*
* @return merged context baggage and tags
*/
@JsonGetter
public Map<String, String> getMeta() {
Map<String, String> meta = new HashMap<String, String>();
for (Entry<String, String> entry : context().getBaggageItems().entrySet()) {
meta.put(entry.getKey(), entry.getValue());
}
for (Entry<String, Object> entry : getTags().entrySet()) {
meta.put(entry.getKey(), String.valueOf(entry.getValue()));
}
return meta;
}
@JsonGetter("start")
public long getStartTime() {
return startTimeMicro * 1000L;
}
@JsonGetter("duration")
public long getDurationNano() {
return durationNano;
}
@JsonGetter("service")
public String getServiceName() {
return context.getServiceName();
}
@JsonGetter("trace_id")
public long getTraceId() {
return context.getTraceId();
}
@JsonGetter("span_id")
public long getSpanId() {
return context.getSpanId();
}
@JsonGetter("parent_id")
public long getParentId() {
return context.getParentId();
}
@JsonGetter("resource")
public String getResourceName() {
return context.getResourceName();
}
@JsonGetter("name")
public String getOperationName() {
return context.getOperationName();
}
@JsonIgnore
public Map<String, Object> getTags() {
return this.context().getTags();
}
@JsonGetter
public String getType() {
return context.getSpanType();
}
@JsonGetter
public int getError() {
return context.getErrorFlag() ? 1 : 0;
}
@Override
public String toString() {
return context.toString();
}
public Span setServiceName(String serviceName) {
this.context().setServiceName(serviceName);
return this;
}
public Span setResourceName(String resourceName) {
this.context().setResourceName(resourceName);
return this;
}
public Span setSpanType(String type) {
this.context().setSpanType(type);
return this;
}
@Override
protected DDSpan thisInstance() {
return this;
}
}

View File

@ -1,12 +1,16 @@
package com.datadoghq.trace;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.datadoghq.trace.integration.DDSpanContextDecorator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.opentracing.Span;
import io.opentracing.tag.Tags;
import java.util.*;
import io.opentracing.tag.Tags;
/**
* SpanContext represents Span state that must propagate to descendant Spans and across process boundaries.
@ -44,7 +48,7 @@ public class DDSpanContext implements io.opentracing.SpanContext {
/**
* The collection of all span related to this one
*/
private final List<Span> trace;
private final List<DDBaseSpan<?>> trace;
/**
* Each span have an operation name describing the current span
*/
@ -70,7 +74,7 @@ public class DDSpanContext implements io.opentracing.SpanContext {
boolean errorFlag,
String spanType,
Map<String, Object> tags,
List<Span> trace,
List<DDBaseSpan<?>> trace,
DDTracer tracer) {
this.traceId = traceId;
@ -93,7 +97,7 @@ public class DDSpanContext implements io.opentracing.SpanContext {
this.tags = tags;
if (trace == null) {
this.trace = new ArrayList<Span>();
this.trace = new ArrayList<DDBaseSpan<?>>();
} else {
this.trace = trace;
}
@ -156,7 +160,7 @@ public class DDSpanContext implements io.opentracing.SpanContext {
}
@JsonIgnore
public List<Span> getTrace() {
public List<DDBaseSpan<?>> getTrace() {
return this.trace;
}

View File

@ -1,5 +1,14 @@
package com.datadoghq.trace;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.datadoghq.trace.integration.DDSpanContextDecorator;
import com.datadoghq.trace.propagation.Codec;
import com.datadoghq.trace.propagation.HTTPCodec;
@ -7,13 +16,12 @@ import com.datadoghq.trace.sampling.AllSampler;
import com.datadoghq.trace.sampling.Sampler;
import com.datadoghq.trace.writer.DDAgentWriter;
import com.datadoghq.trace.writer.Writer;
import io.opentracing.ActiveSpan;
import io.opentracing.BaseSpan;
import io.opentracing.Span;
import io.opentracing.SpanContext;
import io.opentracing.propagation.Format;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
/**
@ -132,11 +140,11 @@ public class DDTracer implements io.opentracing.Tracer {
*
* @param trace a list of the spans related to the same trace
*/
public void write(List<Span> trace) {
public void write(List<DDBaseSpan<?>> trace) {
if (trace.isEmpty()) {
return;
}
if (this.sampler.sample((DDSpan) trace.get(0))) {
if (this.sampler.sample(trace.get(0))) {
this.writer.write(trace);
}
}
@ -145,6 +153,48 @@ public class DDTracer implements io.opentracing.Tracer {
writer.close();
}
private final ThreadLocal<DDActiveSpan> currentActiveSpan = new ThreadLocal<DDActiveSpan>();
@Override
public DDActiveSpan activeSpan() {
return currentActiveSpan.get();
}
/**
* Set the newly created active span as the active one from the Tracer's perspective
*
* @param activeSpan
*/
protected void makeActive(DDActiveSpan activeSpan){
currentActiveSpan.set(activeSpan);
}
/**
* Deactivate the current span (if active) and make the parent active (again)
*
* @param activeSpan
*/
protected void deactivate(DDActiveSpan activeSpan){
DDActiveSpan current = activeSpan();
if(current==activeSpan){
//The parent becomes the active span
makeActive(activeSpan.getParent());
}
}
@Override
public ActiveSpan makeActive(Span span) {
if(!(span instanceof DDSpan))
throw new IllegalArgumentException("Cannot transform a non DDSpan into a DDActiveSpan. Provided class: "+span.getClass());
//Wrap the provided manual span into an active one with the current parent
DDActiveSpan activeSpan = new DDActiveSpan(activeSpan(),(DDSpan)span);
makeActive(activeSpan);
return activeSpan;
}
/**
* Spans are built using this builder
*/
@ -163,29 +213,53 @@ public class DDTracer implements io.opentracing.Tracer {
private String resourceName;
private boolean errorFlag;
private String spanType;
private boolean ignoreActiveSpan = false;
/**
* This method actually build the span according to the builder settings
* DD-Agent requires a serviceName. If it has not been provided, the method will throw a RuntimeException
*
* @return An fresh span
*/
public DDSpan start() {
@Override
public SpanBuilder ignoreActiveSpan() {
this.ignoreActiveSpan = true;
return this;
}
// build the context
DDSpanContext context = buildSpanContext();
DDSpan span = new DDSpan(this.timestamp, context);
@Override
public DDActiveSpan startActive() {
//Set the active span as parent if ignoreActiveSpan==true
DDActiveSpan activeParent = null;
if(!ignoreActiveSpan){
DDActiveSpan current = activeSpan();
if(current!=null){
activeParent = current;
}
}
logger.debug("{} - Starting a new span.", span);
//Create the active span
DDActiveSpan activeSpan = new DDActiveSpan(activeParent,this.timestamp, buildSpanContext());
logger.debug("{} - Starting a new active span.", activeSpan);
makeActive(activeSpan);
return activeSpan;
}
@Override
public DDSpan startManual() {
DDSpan span = new DDSpan(this.timestamp, buildSpanContext());
logger.debug("{} - Starting a new manuel span.", span);
return span;
}
@Override
@Deprecated
public DDSpan start() {
return startManual();
}
@Override
public DDTracer.DDSpanBuilder withTag(String tag, Number number) {
return withTag(tag, (Object) number);
}
@Override
public DDTracer.DDSpanBuilder withTag(String tag, String string) {
if (tag.equals(DDTags.SERVICE_NAME)) {
return withServiceName(string);
@ -198,15 +272,17 @@ public class DDTracer implements io.opentracing.Tracer {
}
}
@Override
public DDTracer.DDSpanBuilder withTag(String tag, boolean bool) {
return withTag(tag, (Object) bool);
}
public DDSpanBuilder(String operationName) {
this.operationName = operationName;
}
@Override
public DDTracer.DDSpanBuilder withStartTimestamp(long timestampMillis) {
this.timestamp = timestampMillis;
return this;
@ -239,15 +315,18 @@ public class DDTracer implements io.opentracing.Tracer {
return parent.baggageItems();
}
public DDTracer.DDSpanBuilder asChildOf(Span span) {
@Override
public DDTracer.DDSpanBuilder asChildOf(BaseSpan<?> span) {
return asChildOf(span == null ? null : span.context());
}
@Override
public DDTracer.DDSpanBuilder asChildOf(SpanContext spanContext) {
this.parent = spanContext;
return this;
}
@Override
public DDTracer.DDSpanBuilder addReference(String referenceType, SpanContext spanContext) {
logger.debug("`addReference` method is not implemented. Doing nothing");
return this;
@ -301,18 +380,18 @@ public class DDTracer implements io.opentracing.Tracer {
// some attributes are inherited from the parent
context = new DDSpanContext(
this.parent == null ? generatedId : p.getTraceId(),
generatedId,
this.parent == null ? 0L : p.getSpanId(),
serviceName,
operationName,
this.resourceName,
this.parent == null ? null : p.getBaggageItems(),
errorFlag,
spanType,
this.tags,
this.parent == null ? null : p.getTrace(),
DDTracer.this
);
generatedId,
this.parent == null ? 0L : p.getSpanId(),
serviceName,
operationName,
this.resourceName,
this.parent == null ? null : p.getBaggageItems(),
errorFlag,
spanType,
this.tags,
this.parent == null ? null : p.getTrace(),
DDTracer.this
);
return context;
}

View File

@ -5,9 +5,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import com.datadoghq.trace.DDSpan;
import io.opentracing.Span;
import com.datadoghq.trace.DDBaseSpan;
public abstract class ASampler implements Sampler{
@ -17,19 +15,16 @@ public abstract class ASampler implements Sampler{
protected Map<String,Pattern> skipTagsPatterns = new HashMap<String,Pattern>();
@Override
public boolean sample(Span span) {
if(span instanceof DDSpan){
DDSpan ddSpan = (DDSpan) span;
public boolean sample(DDBaseSpan<?> 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;
}
//Filter by tag values
for(Entry<String, Pattern> entry: skipTagsPatterns.entrySet()){
Object value = span.getTags().get(entry.getKey());
if(value != null){
String strValue = String.valueOf(value);
Pattern skipPattern = entry.getValue();
if(skipPattern.matcher(strValue).matches()){
return false;
}
}
}
@ -47,6 +42,6 @@ public abstract class ASampler implements Sampler{
skipTagsPatterns.put(tag, skipPattern);
}
protected abstract boolean doSample(Span span);
protected abstract boolean doSample(DDBaseSpan<?> span);
}

View File

@ -1,6 +1,6 @@
package com.datadoghq.trace.sampling;
import io.opentracing.Span;
import com.datadoghq.trace.DDBaseSpan;
/**
* Sampler that always says yes...
@ -8,7 +8,7 @@ import io.opentracing.Span;
public class AllSampler extends ASampler {
@Override
public boolean doSample(Span span) {
public boolean doSample(DDBaseSpan<?> span) {
return true;
}

View File

@ -4,10 +4,9 @@ package com.datadoghq.trace.sampling;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.datadoghq.trace.DDBaseSpan;
import com.google.auto.service.AutoService;
import io.opentracing.Span;
/**
* This sampler sample the traces at a predefined rate.
@ -45,7 +44,7 @@ public class RateSampler extends ASampler {
}
@Override
public boolean doSample(Span span) {
public boolean doSample(DDBaseSpan<?> span) {
boolean sample = Math.random() <= this.sampleRate;
logger.debug("{} - Span is sampled: {}", span, sample);
return sample;

View File

@ -1,7 +1,7 @@
package com.datadoghq.trace.sampling;
import io.opentracing.Span;
import com.datadoghq.trace.DDBaseSpan;
/**
* Main interface to sample a collection of traces.
@ -14,6 +14,6 @@ public interface Sampler {
* @param span the parent span with its context
* @return true when the trace/spans has to be reported/written
*/
boolean sample(Span span);
boolean sample(DDBaseSpan<?> span);
}

View File

@ -1,14 +1,19 @@
package com.datadoghq.trace.writer;
import io.opentracing.Span;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.auto.service.AutoService;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.datadoghq.trace.DDBaseSpan;
import com.google.auto.service.AutoService;
/**
* This writer write provided traces to the a DD agent which is most of time located on the same host.
@ -45,7 +50,7 @@ public class DDAgentWriter implements Writer {
/**
* In memory collection of traces waiting for departure
*/
private final BlockingQueue<List<Span>> traces;
private final BlockingQueue<List<DDBaseSpan<?>>> traces;
/**
* Async worker that posts the spans to the DD agent
@ -66,13 +71,13 @@ public class DDAgentWriter implements Writer {
this.api = api;
tokens = new Semaphore(DEFAULT_MAX_SPANS);
traces = new ArrayBlockingQueue<List<Span>>(DEFAULT_MAX_SPANS);
traces = new ArrayBlockingQueue<List<DDBaseSpan<?>>>(DEFAULT_MAX_SPANS);
}
/* (non-Javadoc)
* @see com.datadoghq.trace.Writer#write(java.util.List)
*/
public void write(List<Span> trace) {
public void write(List<DDBaseSpan<?>> trace) {
//Try to add a new span in the queue
boolean proceed = tokens.tryAcquire(trace.size());
@ -111,10 +116,10 @@ public class DDAgentWriter implements Writer {
public void run() {
while (true) {
try {
List<List<Span>> payload = new ArrayList<List<Span>>();
List<List<DDBaseSpan<?>>> payload = new ArrayList<List<DDBaseSpan<?>>>();
//WAIT until a new span comes
List<Span> l = DDAgentWriter.this.traces.take();
List<DDBaseSpan<?>> l = DDAgentWriter.this.traces.take();
payload.add(l);
//Drain all spans up to a certain batch suze
@ -126,7 +131,7 @@ public class DDAgentWriter implements Writer {
//Compute the number of spans sent
int spansCount = 0;
for (List<Span> trace : payload) {
for (List<DDBaseSpan<?>> trace : payload) {
spansCount += trace.size();
}
logger.debug("Async writer just sent {} spans through {} traces", spansCount, payload.size());

View File

@ -8,12 +8,11 @@ import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.datadoghq.trace.DDBaseSpan;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.opentracing.Span;
/**
* The API pointing to a DD agent
*/
@ -41,7 +40,7 @@ public class DDApi {
* @param traces the traces to be sent
* @return the staus code returned
*/
public boolean sendTraces(List<List<Span>> traces) {
public boolean sendTraces(List<List<DDBaseSpan<?>>> traces) {
int status = callPUT(tracesEndpoint, traces);
if (status == 200) {
logger.debug("Succesfully sent {} traces to the DD agent.", traces.size());

View File

@ -5,17 +5,16 @@ import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.datadoghq.trace.DDBaseSpan;
import com.google.auto.service.AutoService;
import io.opentracing.Span;
@AutoService(Writer.class)
public class LoggingWriter implements Writer{
private static final Logger logger = LoggerFactory.getLogger(LoggingWriter.class.getName());
@Override
public void write(List<Span> trace) {
public void write(List<DDBaseSpan<?>> trace) {
logger.info("write(trace): {}", trace);
}

View File

@ -2,7 +2,7 @@ package com.datadoghq.trace.writer;
import java.util.List;
import io.opentracing.Span;
import com.datadoghq.trace.DDBaseSpan;
/**
* A writer is responsible to send collected spans to some place
@ -14,7 +14,7 @@ public interface Writer {
*
* @param trace the list of spans to write
*/
void write(List<Span> trace);
void write(List<DDBaseSpan<?>> trace);
/**
* Start the writer

View File

@ -131,9 +131,7 @@ public class DDSpanBuilderTest {
final long expectedParentId = spanId;
DDSpanContext mockedContext = mock(DDSpanContext.class);
DDSpan mockedSpan = mock(DDSpan.class);
when(mockedSpan.context()).thenReturn(mockedContext);
when(mockedContext.getSpanId()).thenReturn(spanId);
when(mockedContext.getServiceName()).thenReturn("foo");
@ -142,13 +140,12 @@ public class DDSpanBuilderTest {
DDSpan span = tracer
.buildSpan(expectedName)
.withServiceName("foo")
.asChildOf(mockedSpan)
.asChildOf(mockedContext)
.start();
DDSpanContext actualContext = span.context();
assertThat(actualContext.getParentId()).isEqualTo(expectedParentId);
}

View File

@ -16,6 +16,7 @@ import com.datadoghq.trace.DDTracer;
import com.datadoghq.trace.sampling.RateSampler;
import com.datadoghq.trace.writer.Writer;
import io.opentracing.BaseSpan;
import io.opentracing.Span;
@ -34,7 +35,7 @@ public class DDTracerTest {
.thenReturn(true)
.thenReturn(false);
List<Span> spans = new ArrayList<Span>();
List<DDBaseSpan<?>> spans = new ArrayList<DDBaseSpan<?>>();
spans.add(span);
spans.add(span);
spans.add(span);

View File

@ -11,6 +11,7 @@ import java.util.List;
import org.junit.Before;
import org.junit.Test;
import com.datadoghq.trace.DDBaseSpan;
import com.datadoghq.trace.DDSpan;
import com.datadoghq.trace.DDTracer;
import com.datadoghq.trace.writer.DDAgentWriter;
@ -22,7 +23,7 @@ public class DDAgentWriterTest {
DDSpan parent = null;
DDApi mockedAPI = null;
List<List<Span>> traces = new ArrayList<List<Span>>();
List<List<DDBaseSpan<?>>> traces = new ArrayList<List<DDBaseSpan<?>>>();
DDAgentWriter ddAgentWriter = null;
@Before

View File

@ -44,7 +44,7 @@
</modules>
<properties>
<opentracing.version>0.22.0</opentracing.version>
<opentracing.version>0.30.0</opentracing.version>
<java.version>1.7</java.version>
</properties>