diff --git a/pom.xml b/pom.xml
index 4c68604ca9..48b1b6d67a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -61,8 +61,8 @@
org.apache.maven.plugins
maven-compiler-plugin
- 1.8
- 1.8
+ 1.6
+ 1.6
diff --git a/src/main/java/com/datadoghq/trace/Utils/TracerLogger.java b/src/main/java/com/datadoghq/trace/Utils/TracerLogger.java
deleted file mode 100644
index 9e34d94092..0000000000
--- a/src/main/java/com/datadoghq/trace/Utils/TracerLogger.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.datadoghq.trace.Utils;
-
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TracerLogger {
-
- private Logger logger = LoggerFactory.getLogger("com.datadoghq.trace");
-
- private final String startNewSpan = "Starting new span - %s [%s]";
-
- public void startNewSpan(String operationName, long spanId) {
-
- if (!logger.isTraceEnabled()) return;
- logger.trace(String.format(startNewSpan, operationName, String.valueOf(spanId)));
- }
-
-}
diff --git a/src/main/java/com/datadoghq/trace/impl/DDSpan.java b/src/main/java/com/datadoghq/trace/impl/DDSpan.java
index f5cfc3da6e..1351cdcfe5 100644
--- a/src/main/java/com/datadoghq/trace/impl/DDSpan.java
+++ b/src/main/java/com/datadoghq/trace/impl/DDSpan.java
@@ -1,67 +1,83 @@
package com.datadoghq.trace.impl;
-import java.time.Clock;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
import com.fasterxml.jackson.annotation.JsonGetter;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-
import io.opentracing.Span;
import io.opentracing.SpanContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.Map;
public class DDSpan implements io.opentracing.Span {
- protected final DDTracer tracer;
protected String operationName;
protected Map tags;
+ protected final long startTime;
protected long startTimeNano;
protected long durationNano;
protected final DDSpanContext context;
- protected final List trace;
+
+ private final static Logger logger = LoggerFactory.getLogger(DDSpan.class);
DDSpan(
- DDTracer tracer,
String operationName,
- List trace,
Map tags,
Long timestampMilliseconds,
DDSpanContext context) {
- this.tracer = tracer;
this.operationName = operationName;
- this.trace = Optional.ofNullable(trace).orElse(new ArrayList<>());
this.tags = tags;
- this.startTimeNano = Optional.ofNullable(timestampMilliseconds).orElse(Clock.systemUTC().millis()) * 1000000L;
this.context = context;
+ // record the start time in nano (current milli + nano delta)
+ if (timestampMilliseconds == 0L) {
+ this.startTime = System.currentTimeMillis();
+ } else {
+ this.startTime = timestampMilliseconds;
+ }
+ this.startTimeNano = System.nanoTime();
+
// track each span of the trace
- this.trace.add(this);
+ this.context.getTrace().add(this);
- }
+ // check DD attributes required
+ if (this.context.getServiceName() == null) {
+ throw new IllegalArgumentException("No ServiceName provided");
+ }
- public SpanContext context() {
- return this.context;
- }
+ logger.debug("Starting a new span. " + this.toString());
- public void finish() {
- finish(Clock.systemUTC().millis());
}
public void finish(long stopTimeMillis) {
- this.durationNano = (stopTimeMillis * 1000000L - startTimeNano) ;
+
+ // formula: millis(stop - start) * 1000 * 1000 + nano(stop - start)
+ long stopTimeNano = System.nanoTime();
+ this.durationNano = (stopTimeMillis - startTime) * 1000000L + (stopTimeNano - this.startTimeNano);
+
+ logger.debug("Finishing the span." + this.toString());
+
+ // warn if one of the parent's children is not finished
if (this.isRootSpan()) {
- this.trace.stream()
- .filter(s -> {
- boolean isSelf = ((DDSpanContext) s.context()).getSpanId() == ((DDSpanContext) this.context()).getSpanId();
- boolean isFinished = ((DDSpan) s).getDurationNano() != 0L;
- return !isSelf && !isFinished;
- })
- .forEach(Span::finish);
+ logger.debug("Checking all children attached to the current root span");
+ List spans = this.context.getTrace();
+ for (Span span : spans) {
+ if (((DDSpan) span).getDurationNano() == 0L) {
+ // FIXME
+ logger.warn("The parent span is marked as finished but this span isn't. You have to close each children." + this.toString());
+ }
+ }
+ this.context.getTracer().write(this.context.getTrace());
+ logger.debug("Sending the trace to the writer");
+
}
+
+ }
+
+ public void finish() {
+ finish(System.currentTimeMillis());
}
public void close() {
@@ -105,6 +121,10 @@ public class DDSpan implements io.opentracing.Span {
return null;
}
+ public SpanContext context() {
+ return this.context;
+ }
+
public Span setBaggageItem(String key, String value) {
this.context.setBaggageItem(key, value);
return this;
@@ -115,8 +135,7 @@ public class DDSpan implements io.opentracing.Span {
}
public Span setOperationName(String operationName) {
- // FIXME: @renaud, the operationName (mandatory) is always set by the constructor
- // FIXME: should be an UnsupportedOperation if we don't want to update the operationName + final
+ // FIXME operationName is in each constructor --> always IAE
if (this.operationName != null) {
throw new IllegalArgumentException("The operationName is already assigned.");
}
@@ -133,7 +152,6 @@ public class DDSpan implements io.opentracing.Span {
}
//Getters and JSON serialisation instructions
-
@JsonGetter(value = "name")
public String getOperationName() {
return operationName;
@@ -175,7 +193,7 @@ public class DDSpan implements io.opentracing.Span {
@JsonGetter(value = "resource")
public String getResourceName() {
- return context.getResourceName() == null ? getOperationName() : context.getResourceName();
+ return context.getResourceName() == null ? this.operationName : context.getResourceName();
}
public String getType() {
@@ -186,8 +204,27 @@ public class DDSpan implements io.opentracing.Span {
return context.getErrorFlag() ? 1 : 0;
}
- @JsonIgnore
- public List getTrace() {
- return trace;
+ @Override
+ public String toString() {
+ return "Span{" +
+ "'operationName='" + operationName + '\'' +
+ ", tags=" + tags +
+ ", startTime=" + startTime +
+ ", startTimeNano=" + startTimeNano +
+ ", durationNano=" + durationNano +
+ ", context=" + context +
+ '}';
+ }
+
+
+ @Override
+ public int hashCode() {
+ int result = operationName != null ? operationName.hashCode() : 0;
+ result = 31 * result + (tags != null ? tags.hashCode() : 0);
+ result = 31 * result + (int) (startTime ^ (startTime >>> 32));
+ result = 31 * result + (int) (startTimeNano ^ (startTimeNano >>> 32));
+ result = 31 * result + (int) (durationNano ^ (durationNano >>> 32));
+ result = 31 * result + (context != null ? context.hashCode() : 0);
+ return result;
}
}
diff --git a/src/main/java/com/datadoghq/trace/impl/DDSpanContext.java b/src/main/java/com/datadoghq/trace/impl/DDSpanContext.java
index f8c5186cd8..044d864e3e 100644
--- a/src/main/java/com/datadoghq/trace/impl/DDSpanContext.java
+++ b/src/main/java/com/datadoghq/trace/impl/DDSpanContext.java
@@ -1,37 +1,33 @@
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 java.util.Optional;
public class DDSpanContext implements io.opentracing.SpanContext {
- // Public span attributes
- private final String serviceName;
- private final String resourceName;
+ private static final String SPAN_TYPE_DEFAULT = "custom";
+ // Opentracing attributes
private final long traceId;
private final long spanId;
private final long parentId;
- private final Map baggageItems; // know as 'meta' in dd-trace-py
+ private final Map baggageItems;
+ // DD attributes
+ private final String serviceName;
+ private final String resourceName;
private final boolean errorFlag;
private final Map metrics;
private final String spanType;
- // Sampler attributes
+ private final List trace;
+ // Others attributes
private boolean sampled;
+ private DDTracer tracer;
- // Testing purpose, @todo better mock
- DDSpanContext() {
- serviceName = null;
- resourceName = null;
- traceId = 0;
- spanId = 0;
- parentId = 0;
- baggageItems = new HashMap<>();
- errorFlag = false;
- metrics = null;
- spanType = null;
- }
public DDSpanContext(
long traceId,
@@ -43,29 +39,55 @@ public class DDSpanContext implements io.opentracing.SpanContext {
boolean errorFlag,
Map metrics,
String spanType,
- boolean sampled) { this.traceId = traceId;
+ boolean sampled,
+ List trace,
+ DDTracer tracer) {
+
+ this.traceId = traceId;
this.spanId = spanId;
this.parentId = parentId;
- Optional