From d3c6cf5e794aac75dcffaff4f38a2f0cde39c7ad Mon Sep 17 00:00:00 2001 From: Yang Song Date: Tue, 11 Jun 2019 18:56:31 -0700 Subject: [PATCH] Exporter/Zipkin: Add a note about status tags. (#1931) * Exporter/Zipkin: Add a note about status tags. * Set error tag when status is not OK. --- .../trace/zipkin/ZipkinExporterHandler.java | 13 ++++- .../zipkin/ZipkinExporterHandlerTest.java | 51 +++++++++++++++++-- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/exporters/trace/zipkin/src/main/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterHandler.java b/exporters/trace/zipkin/src/main/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterHandler.java index 6e60352f7c..fd6a731d1a 100644 --- a/exporters/trace/zipkin/src/main/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterHandler.java +++ b/exporters/trace/zipkin/src/main/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterHandler.java @@ -19,6 +19,7 @@ import static java.util.concurrent.TimeUnit.NANOSECONDS; import static java.util.concurrent.TimeUnit.SECONDS; +import com.google.common.annotations.VisibleForTesting; import io.opencensus.common.Duration; import io.opencensus.common.Function; import io.opencensus.common.Functions; @@ -53,8 +54,13 @@ final class ZipkinExporterHandler extends TimeLimitedHandler { private static final Logger logger = Logger.getLogger(ZipkinExporterHandler.class.getName()); private static final String EXPORT_SPAN_NAME = "SendZipkinSpans"; - private static final String STATUS_CODE = "census.status_code"; - private static final String STATUS_DESCRIPTION = "census.status_description"; + + // The naming follows Zipkin convention. As an example see: + // https://github.com/apache/incubator-zipkin-brave/blob/643b7245c462dc14d47afcdb076b2603fd421497/instrumentation/grpc/src/main/java/brave/grpc/GrpcParser.java#L67-L73 + @VisibleForTesting static final String STATUS_CODE = "census.status_code"; + @VisibleForTesting static final String STATUS_DESCRIPTION = "census.status_description"; + @VisibleForTesting static final String STATUS_ERROR = "error"; + private final SpanBytesEncoder encoder; private final Sender sender; private final Endpoint localEndpoint; @@ -130,6 +136,9 @@ static Span generateSpan(SpanData spanData, Endpoint localEndpoint) { if (status.getDescription() != null) { spanBuilder.putTag(STATUS_DESCRIPTION, status.getDescription()); } + if (!status.isOk()) { + spanBuilder.putTag(STATUS_ERROR, status.getCanonicalCode().toString()); + } } for (TimedEvent annotation : spanData.getAnnotations().getEvents()) { diff --git a/exporters/trace/zipkin/src/test/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterHandlerTest.java b/exporters/trace/zipkin/src/test/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterHandlerTest.java index 7e29300319..aa731b42ab 100644 --- a/exporters/trace/zipkin/src/test/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterHandlerTest.java +++ b/exporters/trace/zipkin/src/test/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterHandlerTest.java @@ -102,7 +102,7 @@ public void generateSpan_NoKindAndRemoteParent() { .localEndpoint(localEndpoint) .addAnnotation(1505855799000000L + 433901068L / 1000, "RECEIVED") .addAnnotation(1505855799000000L + 459486280L / 1000, "SENT") - .putTag("census.status_code", "OK") + .putTag(ZipkinExporterHandler.STATUS_CODE, "OK") .build()); } @@ -143,7 +143,7 @@ public void generateSpan_ServerKind() { .localEndpoint(localEndpoint) .addAnnotation(1505855799000000L + 433901068L / 1000, "RECEIVED") .addAnnotation(1505855799000000L + 459486280L / 1000, "SENT") - .putTag("census.status_code", "OK") + .putTag(ZipkinExporterHandler.STATUS_CODE, "OK") .build()); } @@ -184,7 +184,7 @@ public void generateSpan_ClientKind() { .localEndpoint(localEndpoint) .addAnnotation(1505855799000000L + 433901068L / 1000, "RECEIVED") .addAnnotation(1505855799000000L + 459486280L / 1000, "SENT") - .putTag("census.status_code", "OK") + .putTag(ZipkinExporterHandler.STATUS_CODE, "OK") .build()); } @@ -229,10 +229,53 @@ public void generateSpan_WithAttributes() { .localEndpoint(localEndpoint) .addAnnotation(1505855799000000L + 433901068L / 1000, "RECEIVED") .addAnnotation(1505855799000000L + 459486280L / 1000, "SENT") - .putTag("census.status_code", "OK") + .putTag(ZipkinExporterHandler.STATUS_CODE, "OK") .putTag("string", "string value") .putTag("boolean", "false") .putTag("long", "9999") .build()); } + + @Test + public void generateSpan_WithErrorStatus() { + String errorMessage = "timeout"; + SpanData data = + SpanData.create( + SpanContext.create( + TraceId.fromLowerBase16(TRACE_ID), + SpanId.fromLowerBase16(SPAN_ID), + TraceOptions.builder().setIsSampled(true).build()), + SpanId.fromLowerBase16(PARENT_SPAN_ID), + true, /* hasRemoteParent */ + "Recv.helloworld.Greeter.SayHello", /* name */ + Kind.SERVER, /* kind */ + Timestamp.create(1505855794, 194009601) /* startTimestamp */, + Attributes.create(attributes, 0 /* droppedAttributesCount */), + TimedEvents.create(annotations, 0 /* droppedEventsCount */), + TimedEvents.create(messageEvents, 0 /* droppedEventsCount */), + Links.create(Collections.emptyList(), 0 /* droppedLinksCount */), + null, /* childSpanCount */ + Status.DEADLINE_EXCEEDED.withDescription(errorMessage), + Timestamp.create(1505855799, 465726528) /* endTimestamp */); + + assertThat(ZipkinExporterHandler.generateSpan(data, localEndpoint)) + .isEqualTo( + Span.newBuilder() + .traceId(TRACE_ID) + .parentId(PARENT_SPAN_ID) + .id(SPAN_ID) + .kind(Span.Kind.SERVER) + .name(data.getName()) + .timestamp(1505855794000000L + 194009601L / 1000) + .duration( + (1505855799000000L + 465726528L / 1000) + - (1505855794000000L + 194009601L / 1000)) + .localEndpoint(localEndpoint) + .addAnnotation(1505855799000000L + 433901068L / 1000, "RECEIVED") + .addAnnotation(1505855799000000L + 459486280L / 1000, "SENT") + .putTag(ZipkinExporterHandler.STATUS_CODE, "DEADLINE_EXCEEDED") + .putTag(ZipkinExporterHandler.STATUS_DESCRIPTION, errorMessage) + .putTag(ZipkinExporterHandler.STATUS_ERROR, "DEADLINE_EXCEEDED") + .build()); + } }