diff --git a/exporters/zipkin/src/main/java/io/opentelemetry/exporters/zipkin/ZipkinSpanExporter.java b/exporters/zipkin/src/main/java/io/opentelemetry/exporters/zipkin/ZipkinSpanExporter.java index f1b1c42f35..c119bed367 100644 --- a/exporters/zipkin/src/main/java/io/opentelemetry/exporters/zipkin/ZipkinSpanExporter.java +++ b/exporters/zipkin/src/main/java/io/opentelemetry/exporters/zipkin/ZipkinSpanExporter.java @@ -127,7 +127,6 @@ public final class ZipkinSpanExporter implements SpanExporter { Endpoint endpoint = chooseEndpoint(spanData, localEndpoint); long startTimestamp = toEpochMicros(spanData.getStartEpochNanos()); - long endTimestamp = toEpochMicros(spanData.getEndEpochNanos()); final Span.Builder spanBuilder = @@ -137,7 +136,7 @@ public final class ZipkinSpanExporter implements SpanExporter { .kind(toSpanKind(spanData)) .name(spanData.getName()) .timestamp(toEpochMicros(spanData.getStartEpochNanos())) - .duration(endTimestamp - startTimestamp) + .duration(Math.max(1, endTimestamp - startTimestamp)) .localEndpoint(endpoint); if (SpanId.isValid(spanData.getParentSpanId())) { diff --git a/exporters/zipkin/src/test/java/io/opentelemetry/exporters/zipkin/ZipkinSpanExporterTest.java b/exporters/zipkin/src/test/java/io/opentelemetry/exporters/zipkin/ZipkinSpanExporterTest.java index 70ff8449f1..fbd19663bc 100644 --- a/exporters/zipkin/src/test/java/io/opentelemetry/exporters/zipkin/ZipkinSpanExporterTest.java +++ b/exporters/zipkin/src/test/java/io/opentelemetry/exporters/zipkin/ZipkinSpanExporterTest.java @@ -88,6 +88,18 @@ class ZipkinSpanExporterTest { .isEqualTo(buildZipkinSpan(Span.Kind.SERVER)); } + @Test + void generateSpan_subMicroDurations() { + SpanData data = + buildStandardSpan() + .setStartEpochNanos(1505855794_194009601L) + .setEndEpochNanos(1505855794_194009999L) + .build(); + + Span expected = standardZipkinSpanBuilder(Span.Kind.SERVER).duration(1).build(); + assertThat(ZipkinSpanExporter.generateSpan(data, localEndpoint)).isEqualTo(expected); + } + @Test void generateSpan_ServerKind() { SpanData data = buildStandardSpan().setKind(Kind.SERVER).build(); @@ -313,15 +325,19 @@ class ZipkinSpanExporterTest { .setHasRemoteParent(true) .setName("Recv.helloworld.Greeter.SayHello") .setStartEpochNanos(1505855794_194009601L) + .setEndEpochNanos(1505855799_465726528L) .setAttributes(attributes) .setTotalAttributeCount(attributes.size()) .setEvents(annotations) .setLinks(Collections.emptyList()) - .setEndEpochNanos(1505855799_465726528L) .setHasEnded(true); } private static Span buildZipkinSpan(Span.Kind kind) { + return standardZipkinSpanBuilder(kind).build(); + } + + private static Span.Builder standardZipkinSpanBuilder(Span.Kind kind) { return Span.newBuilder() .traceId(TRACE_ID) .parentId(PARENT_SPAN_ID) @@ -332,9 +348,7 @@ class ZipkinSpanExporterTest { .duration((1505855799000000L + 465726528L / 1000) - (1505855794000000L + 194009601L / 1000)) .localEndpoint(localEndpoint) .addAnnotation(1505855799000000L + 433901068L / 1000, "RECEIVED") - .addAnnotation(1505855799000000L + 459486280L / 1000, "SENT") - // .putTag(ZipkinSpanExporter.STATUS_CODE, status) - .build(); + .addAnnotation(1505855799000000L + 459486280L / 1000, "SENT"); } abstract static class ConfigBuilderTest extends ConfigBuilder {