aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/zpages/src/main/java/io/opencensus/contrib/zpages/TracezZPageHandler.java26
-rw-r--r--impl_core/src/main/java/io/opencensus/implcore/trace/export/SampledSpanStoreImpl.java47
-rw-r--r--impl_core/src/test/java/io/opencensus/implcore/trace/export/SampledSpanStoreImplTest.java82
3 files changed, 120 insertions, 35 deletions
diff --git a/contrib/zpages/src/main/java/io/opencensus/contrib/zpages/TracezZPageHandler.java b/contrib/zpages/src/main/java/io/opencensus/contrib/zpages/TracezZPageHandler.java
index 40e858e9..e8ed9b9f 100644
--- a/contrib/zpages/src/main/java/io/opencensus/contrib/zpages/TracezZPageHandler.java
+++ b/contrib/zpages/src/main/java/io/opencensus/contrib/zpages/TracezZPageHandler.java
@@ -29,6 +29,7 @@ import io.opencensus.trace.Annotation;
import io.opencensus.trace.AttributeValue;
import io.opencensus.trace.NetworkEvent;
import io.opencensus.trace.NetworkEvent.Type;
+import io.opencensus.trace.SpanContext;
import io.opencensus.trace.SpanId;
import io.opencensus.trace.Status;
import io.opencensus.trace.Status.CanonicalCode;
@@ -107,6 +108,10 @@ final class TracezZPageHandler extends ZPageHandler {
private static final Tracer tracer = Tracing.getTracer();
// Color to use for zebra-striping.
private static final String ZEBRA_STRIPE_COLOR = "#eee";
+ // Color for sampled traceIds.
+ private static final String SAMPLED_TRACE_ID_COLOR = "blue";
+ // Color for not sampled traceIds
+ private static final String NOT_SAMPLED_TRACE_ID_COLOR = "black";
// The header for span name.
private static final String HEADER_SPAN_NAME = "zspanname";
// The header for type (running = 0, latency = 1, error = 2) to display.
@@ -233,6 +238,7 @@ final class TracezZPageHandler extends ZPageHandler {
if (spans != null) {
emitSpans(out, formatter, spans);
+ emitLegend(out);
}
}
}
@@ -286,9 +292,10 @@ final class TracezZPageHandler extends ZPageHandler {
* 1.0e-9)
: String.format("%13s", " ");
+ SpanContext spanContext = span.getContext();
formatter.format(
- "<b>%04d/%02d/%02d-%02d:%02d:%02d.%06d %s TraceId: %s SpanId: %s "
- + "ParentSpanId: %s</b>%n",
+ "<b>%04d/%02d/%02d-%02d:%02d:%02d.%06d %s TraceId: <b style=\"color:%s;\">%s</b> "
+ + "SpanId: %s ParentSpanId: %s</b>%n",
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH) + 1,
calendar.get(Calendar.DAY_OF_MONTH),
@@ -297,8 +304,11 @@ final class TracezZPageHandler extends ZPageHandler {
calendar.get(Calendar.SECOND),
microsField,
elapsedSecondsStr,
- BaseEncoding.base16().lowerCase().encode(span.getContext().getTraceId().getBytes()),
- BaseEncoding.base16().lowerCase().encode(span.getContext().getSpanId().getBytes()),
+ spanContext.getTraceOptions().isSampled()
+ ? SAMPLED_TRACE_ID_COLOR
+ : NOT_SAMPLED_TRACE_ID_COLOR,
+ BaseEncoding.base16().lowerCase().encode(spanContext.getTraceId().getBytes()),
+ BaseEncoding.base16().lowerCase().encode(spanContext.getSpanId().getBytes()),
BaseEncoding.base16()
.lowerCase()
.encode(
@@ -511,6 +521,14 @@ final class TracezZPageHandler extends ZPageHandler {
}
}
+ private static void emitLegend(PrintWriter out) {
+ out.write("<br>\n");
+ out.printf("<p><b style=\"color:%s;\">TraceId</b> means sampled request. "
+ + "<b style=\"color:%s;\">TraceId</b> means not sampled request.</p>%n",
+ SAMPLED_TRACE_ID_COLOR,
+ NOT_SAMPLED_TRACE_ID_COLOR);
+ }
+
private static Map<LatencyBucketBoundaries, String> buildLatencyBucketBoundariesStringMap() {
Map<LatencyBucketBoundaries, String> ret = new HashMap<>();
for (LatencyBucketBoundaries latencyBucketBoundaries : LatencyBucketBoundaries.values()) {
diff --git a/impl_core/src/main/java/io/opencensus/implcore/trace/export/SampledSpanStoreImpl.java b/impl_core/src/main/java/io/opencensus/implcore/trace/export/SampledSpanStoreImpl.java
index 554666bd..fc77a09a 100644
--- a/impl_core/src/main/java/io/opencensus/implcore/trace/export/SampledSpanStoreImpl.java
+++ b/impl_core/src/main/java/io/opencensus/implcore/trace/export/SampledSpanStoreImpl.java
@@ -51,25 +51,44 @@ public final class SampledSpanStoreImpl extends SampledSpanStore {
private static final class Bucket {
- private final EvictingQueue<SpanImpl> queue;
- private long lastSampleNanoTime;
+ private final EvictingQueue<SpanImpl> sampledSpansQueue;
+ private final EvictingQueue<SpanImpl> notSampledSpansQueue;
+ private long lastSampledNanoTime;
+ private long lastNotSampledNanoTime;
private Bucket(int numSamples) {
- queue = EvictingQueue.create(numSamples);
+ sampledSpansQueue = EvictingQueue.create(numSamples);
+ notSampledSpansQueue = EvictingQueue.create(numSamples);
}
private void considerForSampling(SpanImpl span) {
long spanEndNanoTime = span.getEndNanoTime();
- // Need to compare by doing the subtraction all the time because in case of an overflow,
- // this may never sample again (at least for the next ~200 years). No real chance to
- // overflow two times because that means the process runs for ~200 years.
- if (spanEndNanoTime - lastSampleNanoTime > TIME_BETWEEN_SAMPLES) {
- queue.add(span);
- lastSampleNanoTime = spanEndNanoTime;
+ if (span.getContext().getTraceOptions().isSampled()) {
+ // Need to compare by doing the subtraction all the time because in case of an overflow,
+ // this may never sample again (at least for the next ~200 years). No real chance to
+ // overflow two times because that means the process runs for ~200 years.
+ if (spanEndNanoTime - lastSampledNanoTime > TIME_BETWEEN_SAMPLES) {
+ sampledSpansQueue.add(span);
+ lastSampledNanoTime = spanEndNanoTime;
+ }
+ } else {
+ // Need to compare by doing the subtraction all the time because in case of an overflow,
+ // this may never sample again (at least for the next ~200 years). No real chance to
+ // overflow two times because that means the process runs for ~200 years.
+ if (spanEndNanoTime - lastNotSampledNanoTime > TIME_BETWEEN_SAMPLES) {
+ notSampledSpansQueue.add(span);
+ lastNotSampledNanoTime = spanEndNanoTime;
+ }
}
}
private void getSamples(int maxSpansToReturn, List<SpanImpl> output) {
+ getSamples(sampledSpansQueue, maxSpansToReturn, output);
+ getSamples(notSampledSpansQueue, maxSpansToReturn, output);
+ }
+
+ private static void getSamples(EvictingQueue<SpanImpl> queue, int maxSpansToReturn,
+ List<SpanImpl> output) {
for (SpanImpl span : queue) {
if (output.size() >= maxSpansToReturn) {
break;
@@ -80,6 +99,14 @@ public final class SampledSpanStoreImpl extends SampledSpanStore {
private void getSamplesFilteredByLatency(
long latencyLowerNs, long latencyUpperNs, int maxSpansToReturn, List<SpanImpl> output) {
+ getSamplesFilteredByLatency(sampledSpansQueue, latencyLowerNs, latencyUpperNs,
+ maxSpansToReturn, output);
+ getSamplesFilteredByLatency(notSampledSpansQueue, latencyLowerNs, latencyUpperNs,
+ maxSpansToReturn, output);
+ }
+
+ private static void getSamplesFilteredByLatency(EvictingQueue<SpanImpl> queue,
+ long latencyLowerNs, long latencyUpperNs, int maxSpansToReturn, List<SpanImpl> output) {
for (SpanImpl span : queue) {
if (output.size() >= maxSpansToReturn) {
break;
@@ -92,7 +119,7 @@ public final class SampledSpanStoreImpl extends SampledSpanStore {
}
private int getNumSamples() {
- return queue.size();
+ return sampledSpansQueue.size() + notSampledSpansQueue.size();
}
}
diff --git a/impl_core/src/test/java/io/opencensus/implcore/trace/export/SampledSpanStoreImplTest.java b/impl_core/src/test/java/io/opencensus/implcore/trace/export/SampledSpanStoreImplTest.java
index 694e2e2e..87b3bdbe 100644
--- a/impl_core/src/test/java/io/opencensus/implcore/trace/export/SampledSpanStoreImplTest.java
+++ b/impl_core/src/test/java/io/opencensus/implcore/trace/export/SampledSpanStoreImplTest.java
@@ -61,6 +61,11 @@ public class SampledSpanStoreImplTest {
TraceId.generateRandomId(random),
SpanId.generateRandomId(random),
TraceOptions.builder().setIsSampled().build());
+ private final SpanContext notSampledSpanContext =
+ SpanContext.create(
+ TraceId.generateRandomId(random),
+ SpanId.generateRandomId(random),
+ TraceOptions.DEFAULT);
private final SpanId parentSpanId = SpanId.generateRandomId(random);
private final EnumSet<Options> recordSpanOptions = EnumSet.of(Options.RECORD_EVENTS);
private final TestClock testClock = TestClock.create(Timestamp.create(12345, 54321));
@@ -83,7 +88,7 @@ public class SampledSpanStoreImplTest {
sampleStore.registerSpanNamesForCollection(Arrays.asList(REGISTERED_SPAN_NAME));
}
- SpanImpl createSpan(String spanName) {
+ SpanImpl createSampledSpan(String spanName) {
SpanImpl span =
SpanImpl.startSpan(
sampledSpanContext,
@@ -98,9 +103,25 @@ public class SampledSpanStoreImplTest {
return span;
}
+ SpanImpl createNotSampledSpan(String spanName) {
+ SpanImpl span =
+ SpanImpl.startSpan(
+ notSampledSpanContext,
+ recordSpanOptions,
+ spanName,
+ parentSpanId,
+ false,
+ TraceParams.DEFAULT,
+ startEndHandler,
+ null,
+ testClock);
+ return span;
+ }
+
private void addSpanNameToAllLatencyBuckets(String spanName) {
for (LatencyBucketBoundaries boundaries : LatencyBucketBoundaries.values()) {
- Span span = createSpan(spanName);
+ Span sampledSpan = createSampledSpan(spanName);
+ Span notSampledSpan = createNotSampledSpan(spanName);
if (boundaries.getLatencyLowerNs() < NUM_NANOS_PER_SECOND) {
testClock.advanceTime(Duration.create(0, (int) boundaries.getLatencyLowerNs()));
} else {
@@ -109,16 +130,19 @@ public class SampledSpanStoreImplTest {
boundaries.getLatencyLowerNs() / NUM_NANOS_PER_SECOND,
(int) (boundaries.getLatencyLowerNs() % NUM_NANOS_PER_SECOND)));
}
- span.end();
+ sampledSpan.end();
+ notSampledSpan.end();
}
}
private void addSpanNameToAllErrorBuckets(String spanName) {
for (CanonicalCode code : CanonicalCode.values()) {
if (code != CanonicalCode.OK) {
- Span span = createSpan(spanName);
+ Span sampledSpan = createSampledSpan(spanName);
+ Span notSampledSpan = createNotSampledSpan(spanName);
testClock.advanceTime(Duration.create(0, 1000));
- span.end(EndSpanOptions.builder().setStatus(code.toStatus()).build());
+ sampledSpan.end(EndSpanOptions.builder().setStatus(code.toStatus()).build());
+ notSampledSpan.end(EndSpanOptions.builder().setStatus(code.toStatus()).build());
}
}
}
@@ -133,7 +157,7 @@ public class SampledSpanStoreImplTest {
perSpanNameSummary.get(REGISTERED_SPAN_NAME).getNumbersOfLatencySampledSpans();
assertThat(latencyBucketsSummaries.size()).isEqualTo(LatencyBucketBoundaries.values().length);
for (Map.Entry<LatencyBucketBoundaries, Integer> it : latencyBucketsSummaries.entrySet()) {
- assertThat(it.getValue()).isEqualTo(1);
+ assertThat(it.getValue()).isEqualTo(2);
}
}
@@ -173,7 +197,7 @@ public class SampledSpanStoreImplTest {
perSpanNameSummary.get(REGISTERED_SPAN_NAME).getNumbersOfErrorSampledSpans();
assertThat(errorBucketsSummaries.size()).isEqualTo(CanonicalCode.values().length - 1);
for (Map.Entry<CanonicalCode, Integer> it : errorBucketsSummaries.entrySet()) {
- assertThat(it.getValue()).isEqualTo(1);
+ assertThat(it.getValue()).isEqualTo(2);
}
}
@@ -188,7 +212,7 @@ public class SampledSpanStoreImplTest {
@Test
public void getErrorSampledSpans() {
- SpanImpl span = createSpan(REGISTERED_SPAN_NAME);
+ SpanImpl span = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, 1000));
span.end(EndSpanOptions.builder().setStatus(Status.CANCELLED).build());
Collection<SpanData> samples =
@@ -200,12 +224,12 @@ public class SampledSpanStoreImplTest {
@Test
public void getErrorSampledSpans_MaxSpansToReturn() {
- SpanImpl span1 = createSpan(REGISTERED_SPAN_NAME);
+ SpanImpl span1 = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, 1000));
span1.end(EndSpanOptions.builder().setStatus(Status.CANCELLED).build());
// Advance time to allow other spans to be sampled.
testClock.advanceTime(Duration.create(5, 0));
- SpanImpl span2 = createSpan(REGISTERED_SPAN_NAME);
+ SpanImpl span2 = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, 1000));
span2.end(EndSpanOptions.builder().setStatus(Status.CANCELLED).build());
Collection<SpanData> samples =
@@ -218,10 +242,10 @@ public class SampledSpanStoreImplTest {
@Test
public void getErrorSampledSpans_NullCode() {
- SpanImpl span1 = createSpan(REGISTERED_SPAN_NAME);
+ SpanImpl span1 = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, 1000));
span1.end(EndSpanOptions.builder().setStatus(Status.CANCELLED).build());
- SpanImpl span2 = createSpan(REGISTERED_SPAN_NAME);
+ SpanImpl span2 = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, 1000));
span2.end(EndSpanOptions.builder().setStatus(Status.UNKNOWN).build());
Collection<SpanData> samples =
@@ -232,10 +256,10 @@ public class SampledSpanStoreImplTest {
@Test
public void getErrorSampledSpans_NullCode_MaxSpansToReturn() {
- SpanImpl span1 = createSpan(REGISTERED_SPAN_NAME);
+ SpanImpl span1 = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, 1000));
span1.end(EndSpanOptions.builder().setStatus(Status.CANCELLED).build());
- SpanImpl span2 = createSpan(REGISTERED_SPAN_NAME);
+ SpanImpl span2 = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, 1000));
span2.end(EndSpanOptions.builder().setStatus(Status.UNKNOWN).build());
Collection<SpanData> samples =
@@ -246,7 +270,7 @@ public class SampledSpanStoreImplTest {
@Test
public void getLatencySampledSpans() {
- SpanImpl span = createSpan(REGISTERED_SPAN_NAME);
+ SpanImpl span = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, (int) TimeUnit.MICROSECONDS.toNanos(20)));
span.end();
Collection<SpanData> samples =
@@ -262,7 +286,7 @@ public class SampledSpanStoreImplTest {
@Test
public void getLatencySampledSpans_ExclusiveUpperBound() {
- SpanImpl span = createSpan(REGISTERED_SPAN_NAME);
+ SpanImpl span = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, (int) TimeUnit.MICROSECONDS.toNanos(20)));
span.end();
Collection<SpanData> samples =
@@ -277,7 +301,7 @@ public class SampledSpanStoreImplTest {
@Test
public void getLatencySampledSpans_InclusiveLowerBound() {
- SpanImpl span = createSpan(REGISTERED_SPAN_NAME);
+ SpanImpl span = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, (int) TimeUnit.MICROSECONDS.toNanos(20)));
span.end();
Collection<SpanData> samples =
@@ -293,12 +317,12 @@ public class SampledSpanStoreImplTest {
@Test
public void getLatencySampledSpans_QueryBetweenMultipleBuckets() {
- SpanImpl span1 = createSpan(REGISTERED_SPAN_NAME);
+ SpanImpl span1 = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, (int) TimeUnit.MICROSECONDS.toNanos(20)));
span1.end();
// Advance time to allow other spans to be sampled.
testClock.advanceTime(Duration.create(5, 0));
- SpanImpl span2 = createSpan(REGISTERED_SPAN_NAME);
+ SpanImpl span2 = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, (int) TimeUnit.MICROSECONDS.toNanos(200)));
span2.end();
Collection<SpanData> samples =
@@ -313,12 +337,12 @@ public class SampledSpanStoreImplTest {
@Test
public void getLatencySampledSpans_MaxSpansToReturn() {
- SpanImpl span1 = createSpan(REGISTERED_SPAN_NAME);
+ SpanImpl span1 = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, (int) TimeUnit.MICROSECONDS.toNanos(20)));
span1.end();
// Advance time to allow other spans to be sampled.
testClock.advanceTime(Duration.create(5, 0));
- SpanImpl span2 = createSpan(REGISTERED_SPAN_NAME);
+ SpanImpl span2 = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, (int) TimeUnit.MICROSECONDS.toNanos(200)));
span2.end();
Collection<SpanData> samples =
@@ -331,4 +355,20 @@ public class SampledSpanStoreImplTest {
assertThat(samples.size()).isEqualTo(1);
assertThat(samples.contains(span1.toSpanData())).isTrue();
}
+
+ @Test
+ public void ignoreNegativeSpanLatency() {
+ SpanImpl span = createSampledSpan(REGISTERED_SPAN_NAME);
+ testClock.advanceTime(Duration.create(0, (int) TimeUnit.MICROSECONDS.toNanos(-20)));
+ span.end();
+ Collection<SpanData> samples =
+ sampleStore.getLatencySampledSpans(
+ LatencyFilter.create(
+ REGISTERED_SPAN_NAME,
+ 0,
+ Long.MAX_VALUE,
+ 0));
+ assertThat(samples.size()).isEqualTo(0);
+ }
+
}