From d3260243f5ecae35bcd51b8772d992139612490c Mon Sep 17 00:00:00 2001 From: Guillaume Polaert Date: Wed, 26 Jul 2017 12:47:16 +0200 Subject: [PATCH] make thread safe for nanoTime() --- .../java/com/datadoghq/trace/DDBaseSpan.java | 9 ++-- .../java/com/datadoghq/trace/DDTracer.java | 49 ++++++++++--------- .../java/com/datadoghq/trace/util/Clock.java | 8 +++ 3 files changed, 38 insertions(+), 28 deletions(-) create mode 100644 dd-trace/src/main/java/com/datadoghq/trace/util/Clock.java diff --git a/dd-trace/src/main/java/com/datadoghq/trace/DDBaseSpan.java b/dd-trace/src/main/java/com/datadoghq/trace/DDBaseSpan.java index 20c828a131..cd65b1d741 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/DDBaseSpan.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/DDBaseSpan.java @@ -1,5 +1,6 @@ package com.datadoghq.trace; +import com.datadoghq.trace.util.Clock; import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonIgnore; import io.opentracing.BaseSpan; @@ -13,14 +14,14 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public abstract class DDBaseSpan implements BaseSpan { + /** The context attached to the span */ + protected final DDSpanContext context; /** 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; /** * A simple constructor. Currently, users have @@ -38,14 +39,14 @@ public abstract class DDBaseSpan implements BaseSpan { } else { this.startTimeMicro = timestampMicro; } - this.startTimeNano = System.nanoTime(); + this.startTimeNano = Clock.nowNanos(); // track each span of the trace this.context.getTrace().add(this); } public final void finish() { - this.durationNano = System.nanoTime() - startTimeNano; + this.durationNano = Clock.nowNanos() - startTimeNano; afterFinish(); } diff --git a/dd-trace/src/main/java/com/datadoghq/trace/DDTracer.java b/dd-trace/src/main/java/com/datadoghq/trace/DDTracer.java index f560b8b1fe..4fa24d8e06 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/DDTracer.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/DDTracer.java @@ -5,6 +5,7 @@ import com.datadoghq.trace.propagation.Codec; import com.datadoghq.trace.propagation.HTTPCodec; import com.datadoghq.trace.sampling.AllSampler; import com.datadoghq.trace.sampling.Sampler; +import com.datadoghq.trace.util.Clock; import com.datadoghq.trace.writer.LoggingWriter; import com.datadoghq.trace.writer.Writer; import io.opentracing.ActiveSpan; @@ -136,6 +137,24 @@ public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentrac writer.close(); } + @Override + public String toString() { + return "DDTracer{" + "writer=" + writer + ", sampler=" + sampler + '}'; + } + + private static class CodecRegistry { + + private final Map, Codec> codecs = new HashMap<>(); + + Codec get(final Format format) { + return (Codec) codecs.get(format); + } + + public void register(final Format format, final Codec codec) { + codecs.put(format, codec); + } + } + /** Spans are built using this builder */ public class DDSpanBuilder implements SpanBuilder { private final ActiveSpanSource spanSource; @@ -153,6 +172,11 @@ public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentrac private String spanType; private boolean ignoreActiveSpan = false; + public DDSpanBuilder(final String operationName, final ActiveSpanSource spanSource) { + this.operationName = operationName; + this.spanSource = spanSource; + } + @Override public SpanBuilder ignoreActiveSpan() { this.ignoreActiveSpan = true; @@ -206,11 +230,6 @@ public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentrac return withTag(tag, (Object) bool); } - public DDSpanBuilder(final String operationName, final ActiveSpanSource spanSource) { - this.operationName = operationName; - this.spanSource = spanSource; - } - @Override public DDSpanBuilder withStartTimestamp(final long timestampMillis) { this.timestamp = timestampMillis; @@ -271,7 +290,7 @@ public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentrac } private long generateNewId() { - return System.nanoTime(); + return Clock.nowNanos(); } /** @@ -344,22 +363,4 @@ public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentrac return context; } } - - private static class CodecRegistry { - - private final Map, Codec> codecs = new HashMap<>(); - - Codec get(final Format format) { - return (Codec) codecs.get(format); - } - - public void register(final Format format, final Codec codec) { - codecs.put(format, codec); - } - } - - @Override - public String toString() { - return "DDTracer{" + "writer=" + writer + ", sampler=" + sampler + '}'; - } } diff --git a/dd-trace/src/main/java/com/datadoghq/trace/util/Clock.java b/dd-trace/src/main/java/com/datadoghq/trace/util/Clock.java new file mode 100644 index 0000000000..2c2186428b --- /dev/null +++ b/dd-trace/src/main/java/com/datadoghq/trace/util/Clock.java @@ -0,0 +1,8 @@ +package com.datadoghq.trace.util; + +public class Clock { + + public synchronized static long nowNanos() { + return System.nanoTime(); + } +}