diff options
author | Bogdan Drutu <bdrutu@google.com> | 2018-06-01 13:17:38 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-01 13:17:38 -0700 |
commit | bdbdfd2b4bd8580180a40d90aadd76fcf871544f (patch) | |
tree | 8985b5c5565d74b4854676fec975a436e0076c0e /exporters | |
parent | 2fd835b391e749745f0303c45d1affbe304b0974 (diff) | |
download | opencensus-java-bdbdfd2b4bd8580180a40d90aadd76fcf871544f.tar.gz |
Cleanup trace exporters. (#1225)
Diffstat (limited to 'exporters')
6 files changed, 384 insertions, 136 deletions
diff --git a/exporters/trace/instana/src/main/java/io/opencensus/exporter/trace/instana/InstanaExporterHandler.java b/exporters/trace/instana/src/main/java/io/opencensus/exporter/trace/instana/InstanaExporterHandler.java index 9897726b..5bb8c642 100644 --- a/exporters/trace/instana/src/main/java/io/opencensus/exporter/trace/instana/InstanaExporterHandler.java +++ b/exporters/trace/instana/src/main/java/io/opencensus/exporter/trace/instana/InstanaExporterHandler.java @@ -27,6 +27,7 @@ import io.opencensus.common.Scope; import io.opencensus.common.Timestamp; import io.opencensus.trace.AttributeValue; import io.opencensus.trace.Sampler; +import io.opencensus.trace.Span.Kind; import io.opencensus.trace.SpanContext; import io.opencensus.trace.SpanId; import io.opencensus.trace.Status; @@ -45,7 +46,6 @@ import java.nio.charset.Charset; import java.util.Collection; import java.util.Map; import java.util.Map.Entry; -import java.util.logging.Logger; /*>>> import org.checkerframework.checker.nullness.qual.Nullable; @@ -67,8 +67,6 @@ final class InstanaExporterHandler extends SpanExporter.Handler { private static final Tracer tracer = Tracing.getTracer(); private static final Sampler probabilitySpampler = Samplers.probabilitySampler(0.0001); - static final Logger logger = Logger.getLogger(InstanaExporterHandler.class.getName()); - private final URL agentEndpoint; InstanaExporterHandler(URL agentEndpoint) { @@ -88,13 +86,16 @@ final class InstanaExporterHandler extends SpanExporter.Handler { } private static String toSpanType(SpanData spanData) { - if (spanData.getParentSpanId() == null || Boolean.TRUE.equals(spanData.getHasRemoteParent())) { + if (spanData.getKind() == Kind.SERVER + || (spanData.getKind() == null + && (spanData.getParentSpanId() == null + || Boolean.TRUE.equals(spanData.getHasRemoteParent())))) { return "ENTRY"; } - // This is a hack because the v2 API does not have SpanKind. When switch to v2 this will be - // fixed. - if (spanData.getName().startsWith("Sent.")) { + // This is a hack because the Span API did not have SpanKind. + if (spanData.getKind() == Kind.CLIENT + || (spanData.getKind() == null && spanData.getName().startsWith("Sent."))) { return "EXIT"; } diff --git a/exporters/trace/instana/src/test/java/io/opencensus/exporter/trace/instana/InstanaExporterHandlerTest.java b/exporters/trace/instana/src/test/java/io/opencensus/exporter/trace/instana/InstanaExporterHandlerTest.java index 29d512d5..12915e41 100644 --- a/exporters/trace/instana/src/test/java/io/opencensus/exporter/trace/instana/InstanaExporterHandlerTest.java +++ b/exporters/trace/instana/src/test/java/io/opencensus/exporter/trace/instana/InstanaExporterHandlerTest.java @@ -19,12 +19,14 @@ package io.opencensus.exporter.trace.instana; import static com.google.common.truth.Truth.assertThat; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import io.opencensus.common.Timestamp; import io.opencensus.trace.Annotation; import io.opencensus.trace.AttributeValue; import io.opencensus.trace.Link; -import io.opencensus.trace.NetworkEvent; -import io.opencensus.trace.NetworkEvent.Type; +import io.opencensus.trace.MessageEvent; +import io.opencensus.trace.MessageEvent.Type; +import io.opencensus.trace.Span.Kind; import io.opencensus.trace.SpanContext; import io.opencensus.trace.SpanId; import io.opencensus.trace.Status; @@ -45,37 +47,37 @@ import org.junit.runners.JUnit4; /** Unit tests for {@link InstanaExporterHandler}. */ @RunWith(JUnit4.class) public class InstanaExporterHandlerTest { + private static final String TRACE_ID = "d239036e7d5cec116b562147388b35bf"; + private static final String SPAN_ID = "9cc1e3049173be09"; + private static final String PARENT_SPAN_ID = "8b03ab423da481c5"; + private static final Map<String, AttributeValue> attributes = + ImmutableMap.of("http.url", AttributeValue.stringAttributeValue("http://localhost/foo")); + private static final List<TimedEvent<Annotation>> annotations = Collections.emptyList(); + private static final List<TimedEvent<MessageEvent>> messageEvents = + ImmutableList.of( + TimedEvent.create( + Timestamp.create(1505855799, 433901068), + MessageEvent.builder(Type.RECEIVED, 0).setCompressedMessageSize(7).build()), + TimedEvent.create( + Timestamp.create(1505855799, 459486280), + MessageEvent.builder(Type.SENT, 0).setCompressedMessageSize(13).build())); @Test - public void generateSpan() { - String traceId = "d239036e7d5cec116b562147388b35bf"; - String spanId = "9cc1e3049173be09"; - String parentId = "8b03ab423da481c5"; - Map<String, AttributeValue> attributes = - Collections.singletonMap( - "http.url", AttributeValue.stringAttributeValue("http://localhost/foo")); - List<TimedEvent<Annotation>> annotations = Collections.emptyList(); - List<TimedEvent<NetworkEvent>> networkEvents = - ImmutableList.of( - TimedEvent.create( - Timestamp.create(1505855799, 433901068), - NetworkEvent.builder(Type.RECV, 0).setCompressedMessageSize(7).build()), - TimedEvent.create( - Timestamp.create(1505855799, 459486280), - NetworkEvent.builder(Type.SENT, 0).setCompressedMessageSize(13).build())); + public void generateSpan_NoKindAndRemoteParent() { SpanData data = SpanData.create( SpanContext.create( - TraceId.fromLowerBase16(traceId), - SpanId.fromLowerBase16(spanId), + TraceId.fromLowerBase16(TRACE_ID), + SpanId.fromLowerBase16(SPAN_ID), TraceOptions.fromBytes(new byte[] {1} /* sampled */)), - SpanId.fromLowerBase16(parentId), + SpanId.fromLowerBase16(PARENT_SPAN_ID), true, /* hasRemoteParent */ "SpanName", /* name */ + null, /* kind */ Timestamp.create(1505855794, 194009601) /* startTimestamp */, Attributes.create(attributes, 0 /* droppedAttributesCount */), TimedEvents.create(annotations, 0 /* droppedEventsCount */), - TimedEvents.create(networkEvents, 0 /* droppedEventsCount */), + TimedEvents.create(messageEvents, 0 /* droppedEventsCount */), Links.create(Collections.<Link>emptyList(), 0 /* droppedLinksCount */), null, /* childSpanCount */ Status.OK, @@ -97,4 +99,80 @@ public class InstanaExporterHandlerTest { + "}" + "]"); } + + @Test + public void generateSpan_ServerKind() { + SpanData data = + SpanData.create( + SpanContext.create( + TraceId.fromLowerBase16(TRACE_ID), + SpanId.fromLowerBase16(SPAN_ID), + TraceOptions.fromBytes(new byte[] {1} /* sampled */)), + SpanId.fromLowerBase16(PARENT_SPAN_ID), + true, /* hasRemoteParent */ + "SpanName", /* 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.<Link>emptyList(), 0 /* droppedLinksCount */), + null, /* childSpanCount */ + Status.OK, + Timestamp.create(1505855799, 465726528) /* endTimestamp */); + + assertThat(InstanaExporterHandler.convertToJson(Collections.singletonList(data))) + .isEqualTo( + "[" + + "{" + + "\"spanId\":\"9cc1e3049173be09\"," + + "\"traceId\":\"d239036e7d5cec11\"," + + "\"parentId\":\"8b03ab423da481c5\"," + + "\"timestamp\":1505855794194," + + "\"duration\":5271," + + "\"name\":\"SpanName\"," + + "\"type\":\"ENTRY\"," + + "\"data\":" + + "{\"http.url\":\"http://localhost/foo\"}" + + "}" + + "]"); + } + + @Test + public void generateSpan_ClientKind() { + SpanData data = + SpanData.create( + SpanContext.create( + TraceId.fromLowerBase16(TRACE_ID), + SpanId.fromLowerBase16(SPAN_ID), + TraceOptions.fromBytes(new byte[] {1} /* sampled */)), + SpanId.fromLowerBase16(PARENT_SPAN_ID), + true, /* hasRemoteParent */ + "SpanName", /* name */ + Kind.CLIENT, /* kind */ + Timestamp.create(1505855794, 194009601) /* startTimestamp */, + Attributes.create(attributes, 0 /* droppedAttributesCount */), + TimedEvents.create(annotations, 0 /* droppedEventsCount */), + TimedEvents.create(messageEvents, 0 /* droppedEventsCount */), + Links.create(Collections.<Link>emptyList(), 0 /* droppedLinksCount */), + null, /* childSpanCount */ + Status.OK, + Timestamp.create(1505855799, 465726528) /* endTimestamp */); + + assertThat(InstanaExporterHandler.convertToJson(Collections.singletonList(data))) + .isEqualTo( + "[" + + "{" + + "\"spanId\":\"9cc1e3049173be09\"," + + "\"traceId\":\"d239036e7d5cec11\"," + + "\"parentId\":\"8b03ab423da481c5\"," + + "\"timestamp\":1505855794194," + + "\"duration\":5271," + + "\"name\":\"SpanName\"," + + "\"type\":\"EXIT\"," + + "\"data\":" + + "{\"http.url\":\"http://localhost/foo\"}" + + "}" + + "]"); + } } diff --git a/exporters/trace/stackdriver/src/main/java/io/opencensus/exporter/trace/stackdriver/StackdriverV2ExporterHandler.java b/exporters/trace/stackdriver/src/main/java/io/opencensus/exporter/trace/stackdriver/StackdriverV2ExporterHandler.java index 4c0a6673..3c3f783c 100644 --- a/exporters/trace/stackdriver/src/main/java/io/opencensus/exporter/trace/stackdriver/StackdriverV2ExporterHandler.java +++ b/exporters/trace/stackdriver/src/main/java/io/opencensus/exporter/trace/stackdriver/StackdriverV2ExporterHandler.java @@ -43,7 +43,9 @@ import io.opencensus.common.OpenCensusLibraryInformation; import io.opencensus.common.Scope; import io.opencensus.common.Timestamp; import io.opencensus.trace.Annotation; +import io.opencensus.trace.MessageEvent.Type; import io.opencensus.trace.Sampler; +import io.opencensus.trace.Span.Kind; import io.opencensus.trace.SpanContext; import io.opencensus.trace.SpanId; import io.opencensus.trace.TraceId; @@ -65,7 +67,6 @@ import java.util.Map; import org.checkerframework.checker.nullness.qual.Nullable; */ -// TODO(hailongwen): remove the usage of `NetworkEvent` in the future. /** Exporter to Stackdriver Trace API v2. */ final class StackdriverV2ExporterHandler extends SpanExporter.Handler { private static final Tracer tracer = Tracing.getTracer(); @@ -73,6 +74,8 @@ final class StackdriverV2ExporterHandler extends SpanExporter.Handler { private static final String AGENT_LABEL_KEY = "g.co/agent"; private static final String AGENT_LABEL_VALUE_STRING = "opencensus-java [" + OpenCensusLibraryInformation.VERSION + "]"; + private static final String SERVER_PREFIX = "Recv."; + private static final String CLIENT_PREFIX = "Sent."; private static final AttributeValue AGENT_LABEL_VALUE = AttributeValue.newBuilder() .setStringValue(toTruncatableStringProto(AGENT_LABEL_VALUE_STRING)) @@ -125,16 +128,16 @@ final class StackdriverV2ExporterHandler extends SpanExporter.Handler { final String spanIdHex = encodeSpanId(context.getSpanId()); SpanName spanName = SpanName.newBuilder().setProject(projectId).setTrace(traceIdHex).setSpan(spanIdHex).build(); - @SuppressWarnings("deprecation") Span.Builder spanBuilder = Span.newBuilder() .setName(spanName.toString()) .setSpanId(encodeSpanId(context.getSpanId())) - .setDisplayName(toTruncatableStringProto(spanData.getName())) + .setDisplayName( + toTruncatableStringProto(toDisplayName(spanData.getName(), spanData.getKind()))) .setStartTime(toTimestampProto(spanData.getStartTimestamp())) .setAttributes(toAttributesProto(spanData.getAttributes())) .setTimeEvents( - toTimeEventsProto(spanData.getAnnotations(), spanData.getNetworkEvents())); + toTimeEventsProto(spanData.getAnnotations(), spanData.getMessageEvents())); io.opencensus.trace.Status status = spanData.getStatus(); if (status != null) { spanBuilder.setStatus(toStatusProto(status)); @@ -163,18 +166,17 @@ final class StackdriverV2ExporterHandler extends SpanExporter.Handler { return BaseEncoding.base16().lowerCase().encode(traceId.getBytes()); } - @SuppressWarnings("deprecation") private static Span.TimeEvents toTimeEventsProto( TimedEvents<Annotation> annotationTimedEvents, - TimedEvents<io.opencensus.trace.NetworkEvent> networkEventTimedEvents) { + TimedEvents<io.opencensus.trace.MessageEvent> messageEventTimedEvents) { Span.TimeEvents.Builder timeEventsBuilder = Span.TimeEvents.newBuilder(); timeEventsBuilder.setDroppedAnnotationsCount(annotationTimedEvents.getDroppedEventsCount()); for (TimedEvent<Annotation> annotation : annotationTimedEvents.getEvents()) { timeEventsBuilder.addTimeEvent(toTimeAnnotationProto(annotation)); } - timeEventsBuilder.setDroppedMessageEventsCount(networkEventTimedEvents.getDroppedEventsCount()); - for (TimedEvent<io.opencensus.trace.NetworkEvent> networkEvent : - networkEventTimedEvents.getEvents()) { + timeEventsBuilder.setDroppedMessageEventsCount(messageEventTimedEvents.getDroppedEventsCount()); + for (TimedEvent<io.opencensus.trace.MessageEvent> networkEvent : + messageEventTimedEvents.getEvents()) { timeEventsBuilder.addTimeEvent(toTimeMessageEventProto(networkEvent)); } return timeEventsBuilder.build(); @@ -192,26 +194,24 @@ final class StackdriverV2ExporterHandler extends SpanExporter.Handler { return timeEventBuilder.build(); } - @SuppressWarnings("deprecation") private static TimeEvent toTimeMessageEventProto( - TimedEvent<io.opencensus.trace.NetworkEvent> timedEvent) { + TimedEvent<io.opencensus.trace.MessageEvent> timedEvent) { TimeEvent.Builder timeEventBuilder = TimeEvent.newBuilder().setTime(toTimestampProto(timedEvent.getTimestamp())); - io.opencensus.trace.NetworkEvent networkEvent = timedEvent.getEvent(); + io.opencensus.trace.MessageEvent messageEvent = timedEvent.getEvent(); timeEventBuilder.setMessageEvent( TimeEvent.MessageEvent.newBuilder() - .setId(networkEvent.getMessageId()) - .setCompressedSizeBytes(networkEvent.getCompressedMessageSize()) - .setUncompressedSizeBytes(networkEvent.getUncompressedMessageSize()) - .setType(toMessageEventTypeProto(networkEvent)) + .setId(messageEvent.getMessageId()) + .setCompressedSizeBytes(messageEvent.getCompressedMessageSize()) + .setUncompressedSizeBytes(messageEvent.getUncompressedMessageSize()) + .setType(toMessageEventTypeProto(messageEvent)) .build()); return timeEventBuilder.build(); } - @SuppressWarnings("deprecation") private static TimeEvent.MessageEvent.Type toMessageEventTypeProto( - io.opencensus.trace.NetworkEvent networkEvent) { - if (networkEvent.getType() == io.opencensus.trace.NetworkEvent.Type.RECV) { + io.opencensus.trace.MessageEvent messageEvent) { + if (messageEvent.getType() == Type.RECEIVED) { return MessageEvent.Type.RECEIVED; } else { return MessageEvent.Type.SENT; @@ -303,6 +303,18 @@ final class StackdriverV2ExporterHandler extends SpanExporter.Handler { } } + private static String toDisplayName(String spanName, Kind spanKind) { + if (spanKind == Kind.SERVER && !spanName.startsWith(SERVER_PREFIX)) { + return SERVER_PREFIX + spanName; + } + + if (spanKind == Kind.CLIENT && !spanName.startsWith(CLIENT_PREFIX)) { + return CLIENT_PREFIX + spanName; + } + + return spanName; + } + private static Link toLinkProto(io.opencensus.trace.Link link) { checkNotNull(link); return Link.newBuilder() diff --git a/exporters/trace/stackdriver/src/test/java/io/opencensus/exporter/trace/stackdriver/StackdriverV2ExporterHandlerProtoTest.java b/exporters/trace/stackdriver/src/test/java/io/opencensus/exporter/trace/stackdriver/StackdriverV2ExporterHandlerProtoTest.java index 904de820..f20d1021 100644 --- a/exporters/trace/stackdriver/src/test/java/io/opencensus/exporter/trace/stackdriver/StackdriverV2ExporterHandlerProtoTest.java +++ b/exporters/trace/stackdriver/src/test/java/io/opencensus/exporter/trace/stackdriver/StackdriverV2ExporterHandlerProtoTest.java @@ -21,7 +21,8 @@ import static com.google.common.truth.Truth.assertThat; import com.google.auth.Credentials; import com.google.auth.oauth2.AccessToken; import com.google.auth.oauth2.GoogleCredentials; -import com.google.common.collect.Lists; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.devtools.cloudtrace.v2.AttributeValue; import com.google.devtools.cloudtrace.v2.Span; import com.google.devtools.cloudtrace.v2.Span.TimeEvent; @@ -32,7 +33,7 @@ import com.google.protobuf.Int32Value; import io.opencensus.common.Timestamp; import io.opencensus.trace.Annotation; import io.opencensus.trace.Link; -import io.opencensus.trace.NetworkEvent; +import io.opencensus.trace.Span.Kind; import io.opencensus.trace.SpanContext; import io.opencensus.trace.SpanId; import io.opencensus.trace.Status; @@ -81,10 +82,12 @@ public final class StackdriverV2ExporterHandlerProtoTest { private static final int CHILD_SPAN_COUNT = 13; private static final Annotation annotation = Annotation.fromDescription(ANNOTATION_TEXT); - private static final NetworkEvent recvNetworkEvent = - NetworkEvent.builder(NetworkEvent.Type.RECV, 1).build(); - private static final NetworkEvent sentNetworkEvent = - NetworkEvent.builder(NetworkEvent.Type.SENT, 1).build(); + private static final io.opencensus.trace.MessageEvent recvMessageEvent = + io.opencensus.trace.MessageEvent.builder(io.opencensus.trace.MessageEvent.Type.RECEIVED, 1) + .build(); + private static final io.opencensus.trace.MessageEvent sentMessageEvent = + io.opencensus.trace.MessageEvent.builder(io.opencensus.trace.MessageEvent.Type.SENT, 1) + .build(); private static final Status status = Status.DEADLINE_EXCEEDED.withDescription("TooSlow"); private static final SpanId parentSpanId = SpanId.fromLowerBase16(PARENT_SPAN_ID); private static final SpanId spanId = SpanId.fromLowerBase16(SPAN_ID); @@ -92,37 +95,35 @@ public final class StackdriverV2ExporterHandlerProtoTest { private static final TraceOptions traceOptions = TraceOptions.DEFAULT; private static final SpanContext spanContext = SpanContext.create(traceId, spanId, traceOptions); - private final List<TimedEvent<Annotation>> annotationsList = Lists.newArrayList(); - private final List<TimedEvent<NetworkEvent>> networkEventsList = Lists.newArrayList(); - private final List<Link> linksList = Lists.newArrayList(); + private static final List<TimedEvent<Annotation>> annotationsList = + ImmutableList.of( + SpanData.TimedEvent.create(eventTimestamp1, annotation), + SpanData.TimedEvent.create(eventTimestamp3, annotation)); + private static final List<TimedEvent<io.opencensus.trace.MessageEvent>> networkEventsList = + ImmutableList.of( + SpanData.TimedEvent.create(eventTimestamp1, recvMessageEvent), + SpanData.TimedEvent.create(eventTimestamp2, sentMessageEvent)); + private static final List<Link> linksList = + ImmutableList.of(Link.fromSpanContext(spanContext, Link.Type.CHILD_LINKED_SPAN)); - private SpanData.Attributes attributes; - private TimedEvents<Annotation> annotations; - private TimedEvents<NetworkEvent> networkEvents; - private SpanData.Links links; + private static final SpanData.Attributes attributes = + SpanData.Attributes.create( + ImmutableMap.of( + ATTRIBUTE_KEY_1, + io.opencensus.trace.AttributeValue.longAttributeValue(10L), + ATTRIBUTE_KEY_2, + io.opencensus.trace.AttributeValue.booleanAttributeValue(true)), + DROPPED_ATTRIBUTES_COUNT); + private static final TimedEvents<Annotation> annotations = + TimedEvents.create(annotationsList, DROPPED_ANNOTATIONS_COUNT); + private static final TimedEvents<io.opencensus.trace.MessageEvent> messageEvents = + TimedEvents.create(networkEventsList, DROPPED_NETWORKEVENTS_COUNT); + private static final SpanData.Links links = SpanData.Links.create(linksList, DROPPED_LINKS_COUNT); private StackdriverV2ExporterHandler handler; @Before public void setUp() throws IOException { - Map<String, io.opencensus.trace.AttributeValue> attributesMap = - new HashMap<String, io.opencensus.trace.AttributeValue>(); - attributesMap.put(ATTRIBUTE_KEY_1, io.opencensus.trace.AttributeValue.longAttributeValue(10L)); - attributesMap.put( - ATTRIBUTE_KEY_2, io.opencensus.trace.AttributeValue.booleanAttributeValue(true)); - attributes = SpanData.Attributes.create(attributesMap, DROPPED_ATTRIBUTES_COUNT); - - annotationsList.add(SpanData.TimedEvent.create(eventTimestamp1, annotation)); - annotationsList.add(SpanData.TimedEvent.create(eventTimestamp3, annotation)); - annotations = TimedEvents.create(annotationsList, DROPPED_ANNOTATIONS_COUNT); - - networkEventsList.add(SpanData.TimedEvent.create(eventTimestamp1, recvNetworkEvent)); - networkEventsList.add(SpanData.TimedEvent.create(eventTimestamp2, sentNetworkEvent)); - networkEvents = TimedEvents.create(networkEventsList, DROPPED_NETWORKEVENTS_COUNT); - - linksList.add(Link.fromSpanContext(spanContext, Link.Type.CHILD_LINKED_SPAN)); - links = SpanData.Links.create(linksList, DROPPED_LINKS_COUNT); - handler = StackdriverV2ExporterHandler.createWithCredentials(FAKE_CREDENTIALS, PROJECT_ID); } @@ -134,10 +135,11 @@ public final class StackdriverV2ExporterHandlerProtoTest { parentSpanId, /* hasRemoteParent= */ true, SPAN_NAME, + null, startTimestamp, attributes, annotations, - networkEvents, + messageEvents, links, CHILD_SPAN_COUNT, status, @@ -176,7 +178,7 @@ public final class StackdriverV2ExporterHandlerProtoTest { .setMessageEvent( TimeEvent.MessageEvent.newBuilder() .setType(MessageEvent.Type.SENT) - .setId(sentNetworkEvent.getMessageId())) + .setId(sentMessageEvent.getMessageId())) .setTime( com.google.protobuf.Timestamp.newBuilder() .setSeconds(eventTimestamp2.getSeconds()) @@ -188,7 +190,7 @@ public final class StackdriverV2ExporterHandlerProtoTest { .setMessageEvent( TimeEvent.MessageEvent.newBuilder() .setType(MessageEvent.Type.RECEIVED) - .setId(recvNetworkEvent.getMessageId())) + .setId(recvMessageEvent.getMessageId())) .setTime( com.google.protobuf.Timestamp.newBuilder() .setSeconds(eventTimestamp1.getSeconds()) @@ -282,7 +284,7 @@ public final class StackdriverV2ExporterHandlerProtoTest { startTimestamp, httpAttributes, annotations, - networkEvents, + messageEvents, links, CHILD_SPAN_COUNT, status, @@ -300,6 +302,90 @@ public final class StackdriverV2ExporterHandlerProtoTest { .containsEntry("/http/status_code", AttributeValue.newBuilder().setIntValue(200L).build()); } + @Test + public void generateSpanName_ForServer() { + SpanData spanData = + SpanData.create( + spanContext, + parentSpanId, + /* hasRemoteParent= */ true, + SPAN_NAME, + Kind.SERVER, + startTimestamp, + attributes, + annotations, + messageEvents, + links, + CHILD_SPAN_COUNT, + status, + endTimestamp); + assertThat(handler.generateSpan(spanData).getDisplayName().getValue()) + .isEqualTo("Recv." + SPAN_NAME); + } + + @Test + public void generateSpanName_ForServerWithRecv() { + SpanData spanData = + SpanData.create( + spanContext, + parentSpanId, + /* hasRemoteParent= */ true, + "Recv." + SPAN_NAME, + Kind.SERVER, + startTimestamp, + attributes, + annotations, + messageEvents, + links, + CHILD_SPAN_COUNT, + status, + endTimestamp); + assertThat(handler.generateSpan(spanData).getDisplayName().getValue()) + .isEqualTo("Recv." + SPAN_NAME); + } + + @Test + public void generateSpanName_ForClient() { + SpanData spanData = + SpanData.create( + spanContext, + parentSpanId, + /* hasRemoteParent= */ true, + SPAN_NAME, + Kind.CLIENT, + startTimestamp, + attributes, + annotations, + messageEvents, + links, + CHILD_SPAN_COUNT, + status, + endTimestamp); + assertThat(handler.generateSpan(spanData).getDisplayName().getValue()) + .isEqualTo("Sent." + SPAN_NAME); + } + + @Test + public void generateSpanName_ForClientWithSent() { + SpanData spanData = + SpanData.create( + spanContext, + parentSpanId, + /* hasRemoteParent= */ true, + "Sent." + SPAN_NAME, + Kind.CLIENT, + startTimestamp, + attributes, + annotations, + messageEvents, + links, + CHILD_SPAN_COUNT, + status, + endTimestamp); + assertThat(handler.generateSpan(spanData).getDisplayName().getValue()) + .isEqualTo("Sent." + SPAN_NAME); + } + private static AttributeValue toStringValue(String value) { return AttributeValue.newBuilder() .setStringValue( 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 eb4fc8cd..827dfd88 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,16 +19,14 @@ package io.opencensus.exporter.trace.zipkin; import static java.util.concurrent.TimeUnit.NANOSECONDS; import static java.util.concurrent.TimeUnit.SECONDS; -import com.google.common.io.BaseEncoding; import io.opencensus.common.Scope; import io.opencensus.common.Timestamp; import io.opencensus.trace.Annotation; import io.opencensus.trace.AttributeValue; import io.opencensus.trace.Sampler; +import io.opencensus.trace.Span.Kind; import io.opencensus.trace.SpanContext; -import io.opencensus.trace.SpanId; import io.opencensus.trace.Status; -import io.opencensus.trace.TraceId; import io.opencensus.trace.Tracer; import io.opencensus.trace.Tracing; import io.opencensus.trace.export.SpanData; @@ -51,11 +49,10 @@ import zipkin2.Span; import zipkin2.codec.SpanBytesEncoder; import zipkin2.reporter.Sender; -// TODO(hailongwen): remove the usage of `NetworkEvent` in the future. final class ZipkinExporterHandler extends SpanExporter.Handler { private static final Tracer tracer = Tracing.getTracer(); private static final Sampler probabilitySampler = Samplers.probabilitySampler(0.0001); - static final Logger logger = Logger.getLogger(ZipkinExporterHandler.class.getName()); + private static final Logger logger = Logger.getLogger(ZipkinExporterHandler.class.getName()); private static final String STATUS_CODE = "census.status_code"; private static final String STATUS_DESCRIPTION = "census.status_description"; @@ -110,8 +107,8 @@ final class ZipkinExporterHandler extends SpanExporter.Handler { @SuppressWarnings("nullness") Span.Builder spanBuilder = Span.newBuilder() - .traceId(encodeTraceId(context.getTraceId())) - .id(encodeSpanId(context.getSpanId())) + .traceId(context.getTraceId().toLowerBase16()) + .id(context.getSpanId().toLowerBase16()) .kind(toSpanKind(spanData)) .name(spanData.getName()) .timestamp(toEpochMicros(spanData.getStartTimestamp())) @@ -119,7 +116,7 @@ final class ZipkinExporterHandler extends SpanExporter.Handler { .localEndpoint(localEndpoint); if (spanData.getParentSpanId() != null && spanData.getParentSpanId().isValid()) { - spanBuilder.parentId(encodeSpanId(spanData.getParentSpanId())); + spanBuilder.parentId(spanData.getParentSpanId().toLowerBase16()); } for (Map.Entry<String, AttributeValue> label : @@ -139,32 +136,25 @@ final class ZipkinExporterHandler extends SpanExporter.Handler { toEpochMicros(annotation.getTimestamp()), annotation.getEvent().getDescription()); } - for (TimedEvent<io.opencensus.trace.NetworkEvent> networkEvent : - spanData.getNetworkEvents().getEvents()) { + for (TimedEvent<io.opencensus.trace.MessageEvent> messageEvent : + spanData.getMessageEvents().getEvents()) { spanBuilder.addAnnotation( - toEpochMicros(networkEvent.getTimestamp()), networkEvent.getEvent().getType().name()); + toEpochMicros(messageEvent.getTimestamp()), messageEvent.getEvent().getType().name()); } return spanBuilder.build(); } - private static String encodeTraceId(TraceId traceId) { - return BaseEncoding.base16().lowerCase().encode(traceId.getBytes()); - } - - private static String encodeSpanId(SpanId spanId) { - return BaseEncoding.base16().lowerCase().encode(spanId.getBytes()); - } - @Nullable private static Span.Kind toSpanKind(SpanData spanData) { - if (Boolean.TRUE.equals(spanData.getHasRemoteParent())) { + // This is a hack because the Span API did not have SpanKind. + if (spanData.getKind() == Kind.SERVER + || (spanData.getKind() == null && Boolean.TRUE.equals(spanData.getHasRemoteParent()))) { return Span.Kind.SERVER; } - // This is a hack because the v2 API does not have SpanKind. When switch to v2 this will be - // fixed. - if (spanData.getName().startsWith("Sent.")) { + // This is a hack because the Span API did not have SpanKind. + if (spanData.getKind() == Kind.CLIENT || spanData.getName().startsWith("Sent.")) { return Span.Kind.CLIENT; } 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 6476aadb..636ffc95 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 @@ -19,13 +19,13 @@ package io.opencensus.exporter.trace.zipkin; import static com.google.common.truth.Truth.assertThat; import com.google.common.collect.ImmutableList; -import com.google.common.io.BaseEncoding; import io.opencensus.common.Timestamp; import io.opencensus.trace.Annotation; import io.opencensus.trace.AttributeValue; import io.opencensus.trace.Link; -import io.opencensus.trace.NetworkEvent; -import io.opencensus.trace.NetworkEvent.Type; +import io.opencensus.trace.MessageEvent; +import io.opencensus.trace.MessageEvent.Type; +import io.opencensus.trace.Span.Kind; import io.opencensus.trace.SpanContext; import io.opencensus.trace.SpanId; import io.opencensus.trace.Status; @@ -44,44 +44,43 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import zipkin2.Endpoint; import zipkin2.Span; -import zipkin2.Span.Kind; /** Unit tests for {@link ZipkinExporterHandler}. */ @RunWith(JUnit4.class) public class ZipkinExporterHandlerTest { + private static final Endpoint localEndpoint = + Endpoint.newBuilder().serviceName("tweetiebird").build(); + private static final String TRACE_ID = "d239036e7d5cec116b562147388b35bf"; + private static final String SPAN_ID = "9cc1e3049173be09"; + private static final String PARENT_SPAN_ID = "8b03ab423da481c5"; + private static final Map<String, AttributeValue> attributes = Collections.emptyMap(); + private static final List<TimedEvent<Annotation>> annotations = Collections.emptyList(); + private static final List<TimedEvent<MessageEvent>> messageEvents = + ImmutableList.of( + TimedEvent.create( + Timestamp.create(1505855799, 433901068), + MessageEvent.builder(Type.RECEIVED, 0).setCompressedMessageSize(7).build()), + TimedEvent.create( + Timestamp.create(1505855799, 459486280), + MessageEvent.builder(Type.SENT, 0).setCompressedMessageSize(13).build())); @Test - public void generateSpan() { - Endpoint localEndpoint = Endpoint.newBuilder().serviceName("tweetiebird").build(); - String traceId = "d239036e7d5cec116b562147388b35bf"; - String spanId = "9cc1e3049173be09"; - String parentId = "8b03ab423da481c5"; - Map<String, AttributeValue> attributes = Collections.emptyMap(); - List<TimedEvent<Annotation>> annotations = Collections.emptyList(); - List<TimedEvent<NetworkEvent>> networkEvents = - ImmutableList.of( - TimedEvent.create( - Timestamp.create(1505855799, 433901068), - NetworkEvent.builder(Type.RECV, 0).setCompressedMessageSize(7).build()), - TimedEvent.create( - Timestamp.create(1505855799, 459486280), - NetworkEvent.builder(Type.SENT, 0).setCompressedMessageSize(13).build())); + public void generateSpan_NoKindAndRemoteParent() { SpanData data = SpanData.create( SpanContext.create( - // TODO SpanId.fromLowerBase16 - TraceId.fromBytes(BaseEncoding.base16().lowerCase().decode(traceId)), - // TODO SpanId.fromLowerBase16 - SpanId.fromBytes(BaseEncoding.base16().lowerCase().decode(spanId)), + TraceId.fromLowerBase16(TRACE_ID), + SpanId.fromLowerBase16(SPAN_ID), TraceOptions.fromBytes(new byte[] {1} /* sampled */)), // TODO SpanId.fromLowerBase16 - SpanId.fromBytes(BaseEncoding.base16().lowerCase().decode(parentId)), + SpanId.fromLowerBase16(PARENT_SPAN_ID), true, /* hasRemoteParent */ "Recv.helloworld.Greeter.SayHello", /* name */ + null, /* kind */ Timestamp.create(1505855794, 194009601) /* startTimestamp */, Attributes.create(attributes, 0 /* droppedAttributesCount */), TimedEvents.create(annotations, 0 /* droppedEventsCount */), - TimedEvents.create(networkEvents, 0 /* droppedEventsCount */), + TimedEvents.create(messageEvents, 0 /* droppedEventsCount */), Links.create(Collections.<Link>emptyList(), 0 /* droppedLinksCount */), null, /* childSpanCount */ Status.OK, @@ -90,17 +89,99 @@ public class ZipkinExporterHandlerTest { assertThat(ZipkinExporterHandler.generateSpan(data, localEndpoint)) .isEqualTo( Span.newBuilder() - .traceId(traceId) - .parentId(parentId) - .id(spanId) - .kind(Kind.SERVER) + .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, "RECV") + .addAnnotation(1505855799000000L + 433901068L / 1000, "RECEIVED") + .addAnnotation(1505855799000000L + 459486280L / 1000, "SENT") + .putTag("census.status_code", "OK") + .build()); + } + + @Test + public void generateSpan_ServerKind() { + SpanData data = + SpanData.create( + SpanContext.create( + TraceId.fromLowerBase16(TRACE_ID), + SpanId.fromLowerBase16(SPAN_ID), + TraceOptions.fromBytes(new byte[] {1} /* sampled */)), + // TODO SpanId.fromLowerBase16 + 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.<Link>emptyList(), 0 /* droppedLinksCount */), + null, /* childSpanCount */ + Status.OK, + 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("census.status_code", "OK") + .build()); + } + + @Test + public void generateSpan_ClientKind() { + SpanData data = + SpanData.create( + SpanContext.create( + TraceId.fromLowerBase16(TRACE_ID), + SpanId.fromLowerBase16(SPAN_ID), + TraceOptions.fromBytes(new byte[] {1} /* sampled */)), + // TODO SpanId.fromLowerBase16 + SpanId.fromLowerBase16(PARENT_SPAN_ID), + true, /* hasRemoteParent */ + "Sent.helloworld.Greeter.SayHello", /* name */ + Kind.CLIENT, /* kind */ + Timestamp.create(1505855794, 194009601) /* startTimestamp */, + Attributes.create(attributes, 0 /* droppedAttributesCount */), + TimedEvents.create(annotations, 0 /* droppedEventsCount */), + TimedEvents.create(messageEvents, 0 /* droppedEventsCount */), + Links.create(Collections.<Link>emptyList(), 0 /* droppedLinksCount */), + null, /* childSpanCount */ + Status.OK, + 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.CLIENT) + .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("census.status_code", "OK") .build()); |