From 0696e3bf2cf6379201d61bf68cf8e889764d2c61 Mon Sep 17 00:00:00 2001 From: songy23 Date: Thu, 7 Jun 2018 14:28:57 -0700 Subject: [PATCH 1/7] Stackdriver Trace Exporter: add resource labels to Spans. --- buildscripts/import-control.xml | 1 + exporters/trace/stackdriver/build.gradle | 1 + .../StackdriverV2ExporterHandler.java | 94 +++++++++++++++++++ ...StackdriverV2ExporterHandlerProtoTest.java | 51 +++++++--- 4 files changed, 135 insertions(+), 12 deletions(-) diff --git a/buildscripts/import-control.xml b/buildscripts/import-control.xml index 4fb0eac8a9..59c3e20558 100644 --- a/buildscripts/import-control.xml +++ b/buildscripts/import-control.xml @@ -141,6 +141,7 @@ General guidelines on imports: + diff --git a/exporters/trace/stackdriver/build.gradle b/exporters/trace/stackdriver/build.gradle index fa4865616c..fc8bfef4b2 100644 --- a/exporters/trace/stackdriver/build.gradle +++ b/exporters/trace/stackdriver/build.gradle @@ -9,6 +9,7 @@ dependencies { compileOnly libraries.auto_value compile project(':opencensus-api'), + project(':opencensus-contrib-monitored-resource-util'), libraries.google_auth compile (libraries.google_cloud_trace) { 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 3c3f783c07..4bd24f2e1e 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 @@ -42,6 +42,12 @@ import io.opencensus.common.OpenCensusLibraryInformation; import io.opencensus.common.Scope; import io.opencensus.common.Timestamp; +import io.opencensus.contrib.monitoredresource.util.MonitoredResource; +import io.opencensus.contrib.monitoredresource.util.MonitoredResource.AwsEc2InstanceMonitoredResource; +import io.opencensus.contrib.monitoredresource.util.MonitoredResource.GcpGceInstanceMonitoredResource; +import io.opencensus.contrib.monitoredresource.util.MonitoredResource.GcpGkeContainerMonitoredResource; +import io.opencensus.contrib.monitoredresource.util.MonitoredResourceUtils; +import io.opencensus.contrib.monitoredresource.util.ResourceType; import io.opencensus.trace.Annotation; import io.opencensus.trace.MessageEvent.Type; import io.opencensus.trace.Sampler; @@ -91,6 +97,9 @@ final class StackdriverV2ExporterHandler extends SpanExporter.Handler { .put("http.status_code", "/http/status_code") .build(); + @VisibleForTesting @javax.annotation.Nullable + static final MonitoredResource RESOURCE = MonitoredResourceUtils.getDefaultResource(); + private final String projectId; private final TraceServiceClient traceServiceClient; private final ProjectName projectName; @@ -225,6 +234,7 @@ private static Attributes toAttributesProto( toAttributesBuilderProto( attributes.getAttributeMap(), attributes.getDroppedAttributesCount()); attributesBuilder.putAttributeMap(AGENT_LABEL_KEY, AGENT_LABEL_VALUE); + putResourceLabels(attributesBuilder, RESOURCE); return attributesBuilder.build(); } @@ -239,6 +249,90 @@ private static Attributes.Builder toAttributesBuilderProto( return attributesBuilder; } + @SuppressWarnings("unchecked") + private static void putResourceLabels( + Attributes.Builder attributesBuilder, MonitoredResource resource) { + if (resource == null) { + return; + } + ResourceType resourceType = resource.getResourceType(); + switch (resourceType) { + case AWS_EC2_INSTANCE: + AwsEc2InstanceMonitoredResource awsEc2InstanceMonitoredResource = + (AwsEc2InstanceMonitoredResource) resource; + attributesBuilder.putAttributeMap( + createResourceLabelKey(resourceType, "aws_account"), + toStringAttributeValueProto(awsEc2InstanceMonitoredResource.getAccount())); + attributesBuilder.putAttributeMap( + createResourceLabelKey(resourceType, "instance_id"), + toStringAttributeValueProto(awsEc2InstanceMonitoredResource.getInstanceId())); + attributesBuilder.putAttributeMap( + createResourceLabelKey(resourceType, "region"), + toStringAttributeValueProto("aws:" + awsEc2InstanceMonitoredResource.getAccount())); + return; + case GCP_GCE_INSTANCE: + GcpGceInstanceMonitoredResource gcpGceInstanceMonitoredResource = + (GcpGceInstanceMonitoredResource) resource; + attributesBuilder.putAttributeMap( + createResourceLabelKey(resourceType, "project_id"), + toStringAttributeValueProto(gcpGceInstanceMonitoredResource.getAccount())); + attributesBuilder.putAttributeMap( + createResourceLabelKey(resourceType, "instance_id"), + toStringAttributeValueProto(gcpGceInstanceMonitoredResource.getInstanceId())); + attributesBuilder.putAttributeMap( + createResourceLabelKey(resourceType, "zone"), + toStringAttributeValueProto(gcpGceInstanceMonitoredResource.getZone())); + return; + case GCP_GKE_CONTAINER: + GcpGkeContainerMonitoredResource gcpGkeContainerMonitoredResource = + (GcpGkeContainerMonitoredResource) resource; + attributesBuilder.putAttributeMap( + createResourceLabelKey(resourceType, "project_id"), + toStringAttributeValueProto(gcpGkeContainerMonitoredResource.getAccount())); + attributesBuilder.putAttributeMap( + createResourceLabelKey(resourceType, "instance_id"), + toStringAttributeValueProto(gcpGkeContainerMonitoredResource.getInstanceId())); + attributesBuilder.putAttributeMap( + createResourceLabelKey(resourceType, "zone"), + toStringAttributeValueProto(gcpGkeContainerMonitoredResource.getZone())); + attributesBuilder.putAttributeMap( + createResourceLabelKey(resourceType, "cluster_name"), + toStringAttributeValueProto(gcpGkeContainerMonitoredResource.getClusterName())); + attributesBuilder.putAttributeMap( + createResourceLabelKey(resourceType, "container_name"), + toStringAttributeValueProto(gcpGkeContainerMonitoredResource.getContainerName())); + attributesBuilder.putAttributeMap( + createResourceLabelKey(resourceType, "namespace_id"), + toStringAttributeValueProto(gcpGkeContainerMonitoredResource.getNamespaceId())); + attributesBuilder.putAttributeMap( + createResourceLabelKey(resourceType, "pod_id"), + toStringAttributeValueProto(gcpGkeContainerMonitoredResource.getPodId())); + return; + } + } + + @VisibleForTesting + static String createResourceLabelKey(ResourceType resourceType, String resourceAttribute) { + return String.format("g.co/r/%s/%s", mapToStringResourceType(resourceType), resourceAttribute); + } + + private static String mapToStringResourceType(ResourceType resourceType) { + switch (resourceType) { + case GCP_GCE_INSTANCE: + return "gce_instance"; + case GCP_GKE_CONTAINER: + return "gke_container"; + case AWS_EC2_INSTANCE: + return "aws_ec2_instance"; + } + throw new IllegalArgumentException("Unknown resource type."); + } + + @VisibleForTesting + static AttributeValue toStringAttributeValueProto(String value) { + return AttributeValue.newBuilder().setStringValue(toTruncatableStringProto(value)).build(); + } + private static String mapKey(String key) { if (HTTP_ATTRIBUTE_MAPPING.containsKey(key)) { return HTTP_ATTRIBUTE_MAPPING.get(key); 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 f20d1021af..e5888ec15c 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 @@ -17,6 +17,8 @@ package io.opencensus.exporter.trace.stackdriver; import static com.google.common.truth.Truth.assertThat; +import static io.opencensus.exporter.trace.stackdriver.StackdriverV2ExporterHandler.createResourceLabelKey; +import static io.opencensus.exporter.trace.stackdriver.StackdriverV2ExporterHandler.toStringAttributeValueProto; import com.google.auth.Credentials; import com.google.auth.oauth2.AccessToken; @@ -31,6 +33,7 @@ import com.google.devtools.cloudtrace.v2.TruncatableString; import com.google.protobuf.Int32Value; import io.opencensus.common.Timestamp; +import io.opencensus.contrib.monitoredresource.util.ResourceType; import io.opencensus.trace.Annotation; import io.opencensus.trace.Link; import io.opencensus.trace.Span.Kind; @@ -242,6 +245,7 @@ public void generateSpan() { .containsEntry(ATTRIBUTE_KEY_1, AttributeValue.newBuilder().setIntValue(10L).build()); assertThat(span.getAttributes().getAttributeMapMap()) .containsEntry(ATTRIBUTE_KEY_2, AttributeValue.newBuilder().setBoolValue(true).build()); + verifyResourceLabels(span.getAttributes().getAttributeMapMap()); // TODO(@Hailong): add stack trace test in the future. assertThat(span.getStackTrace()).isEqualTo(StackTrace.newBuilder().build()); assertThat(span.getTimeEvents().getDroppedMessageEventsCount()) @@ -258,6 +262,35 @@ public void generateSpan() { .isEqualTo(Int32Value.newBuilder().setValue(CHILD_SPAN_COUNT).build()); } + private static void verifyResourceLabels(Map attributeMap) { + if (StackdriverV2ExporterHandler.RESOURCE == null) { + return; + } + ResourceType resourceType = StackdriverV2ExporterHandler.RESOURCE.getResourceType(); + switch (resourceType) { + case AWS_EC2_INSTANCE: + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "aws_account")); + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "instance_id")); + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "region")); + return; + case GCP_GCE_INSTANCE: + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "project_id")); + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "instance_id")); + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "zone")); + return; + case GCP_GKE_CONTAINER: + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "project_id")); + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "instance_id")); + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "zone")); + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "cluster_name")); + assertThat(attributeMap) + .containsKey(createResourceLabelKey(resourceType, "container_name")); + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "namespace_id")); + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "pod_id")); + return; + } + } + @Test public void mapHttpAttributes() { Map attributesMap = @@ -293,11 +326,12 @@ public void mapHttpAttributes() { Span span = handler.generateSpan(spanData); Map attributes = span.getAttributes().getAttributeMapMap(); - assertThat(attributes).containsEntry("/http/host", toStringValue("host")); - assertThat(attributes).containsEntry("/http/method", toStringValue("method")); - assertThat(attributes).containsEntry("/http/path", toStringValue("path")); - assertThat(attributes).containsEntry("/http/route", toStringValue("route")); - assertThat(attributes).containsEntry("/http/user_agent", toStringValue("user_agent")); + assertThat(attributes).containsEntry("/http/host", toStringAttributeValueProto("host")); + assertThat(attributes).containsEntry("/http/method", toStringAttributeValueProto("method")); + assertThat(attributes).containsEntry("/http/path", toStringAttributeValueProto("path")); + assertThat(attributes).containsEntry("/http/route", toStringAttributeValueProto("route")); + assertThat(attributes) + .containsEntry("/http/user_agent", toStringAttributeValueProto("user_agent")); assertThat(attributes) .containsEntry("/http/status_code", AttributeValue.newBuilder().setIntValue(200L).build()); } @@ -385,11 +419,4 @@ public void generateSpanName_ForClientWithSent() { assertThat(handler.generateSpan(spanData).getDisplayName().getValue()) .isEqualTo("Sent." + SPAN_NAME); } - - private static AttributeValue toStringValue(String value) { - return AttributeValue.newBuilder() - .setStringValue( - TruncatableString.newBuilder().setValue(value).setTruncatedByteCount(0).build()) - .build(); - } } From 57765e8cea76cf612fda1251a8f99bba750c12ff Mon Sep 17 00:00:00 2001 From: songy23 Date: Fri, 8 Jun 2018 11:41:50 -0700 Subject: [PATCH 2/7] Fix review comments. --- .../StackdriverV2ExporterHandler.java | 122 ++++++++------ ...StackdriverV2ExporterHandlerProtoTest.java | 153 ++++++++++++++---- 2 files changed, 194 insertions(+), 81 deletions(-) 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 4bd24f2e1e..556416a69e 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 @@ -131,7 +131,7 @@ static StackdriverV2ExporterHandler create(String projectId) throws IOException } @VisibleForTesting - Span generateSpan(SpanData spanData) { + Span generateSpan(SpanData spanData, @javax.annotation.Nullable MonitoredResource resource) { SpanContext context = spanData.getContext(); final String traceIdHex = encodeTraceId(context.getTraceId()); final String spanIdHex = encodeSpanId(context.getSpanId()); @@ -144,7 +144,7 @@ Span generateSpan(SpanData spanData) { .setDisplayName( toTruncatableStringProto(toDisplayName(spanData.getName(), spanData.getKind()))) .setStartTime(toTimestampProto(spanData.getStartTimestamp())) - .setAttributes(toAttributesProto(spanData.getAttributes())) + .setAttributes(toAttributesProto(spanData.getAttributes(), resource)) .setTimeEvents( toTimeEventsProto(spanData.getAnnotations(), spanData.getMessageEvents())); io.opencensus.trace.Status status = spanData.getStatus(); @@ -229,12 +229,13 @@ private static TimeEvent.MessageEvent.Type toMessageEventTypeProto( // These are the attributes of the Span, where usually we may add more attributes like the agent. private static Attributes toAttributesProto( - io.opencensus.trace.export.SpanData.Attributes attributes) { + io.opencensus.trace.export.SpanData.Attributes attributes, + @javax.annotation.Nullable MonitoredResource resource) { Attributes.Builder attributesBuilder = toAttributesBuilderProto( attributes.getAttributeMap(), attributes.getDroppedAttributesCount()); attributesBuilder.putAttributeMap(AGENT_LABEL_KEY, AGENT_LABEL_VALUE); - putResourceLabels(attributesBuilder, RESOURCE); + putResourceLabels(attributesBuilder, resource); return attributesBuilder.build(); } @@ -249,68 +250,97 @@ private static Attributes.Builder toAttributesBuilderProto( return attributesBuilder; } - @SuppressWarnings("unchecked") private static void putResourceLabels( - Attributes.Builder attributesBuilder, MonitoredResource resource) { + Attributes.Builder attributesBuilder, @javax.annotation.Nullable MonitoredResource resource) { if (resource == null) { return; } ResourceType resourceType = resource.getResourceType(); switch (resourceType) { case AWS_EC2_INSTANCE: + @SuppressWarnings("unchecked") AwsEc2InstanceMonitoredResource awsEc2InstanceMonitoredResource = (AwsEc2InstanceMonitoredResource) resource; - attributesBuilder.putAttributeMap( - createResourceLabelKey(resourceType, "aws_account"), - toStringAttributeValueProto(awsEc2InstanceMonitoredResource.getAccount())); - attributesBuilder.putAttributeMap( - createResourceLabelKey(resourceType, "instance_id"), - toStringAttributeValueProto(awsEc2InstanceMonitoredResource.getInstanceId())); - attributesBuilder.putAttributeMap( - createResourceLabelKey(resourceType, "region"), - toStringAttributeValueProto("aws:" + awsEc2InstanceMonitoredResource.getAccount())); + putResourceAttributeMapToBuilder( + attributesBuilder, + resourceType, + "aws_account", + awsEc2InstanceMonitoredResource.getAccount()); + putResourceAttributeMapToBuilder( + attributesBuilder, + resourceType, + "instance_id", + awsEc2InstanceMonitoredResource.getInstanceId()); + putResourceAttributeMapToBuilder( + attributesBuilder, + resourceType, + "region", + "aws:" + awsEc2InstanceMonitoredResource.getRegion()); return; case GCP_GCE_INSTANCE: + @SuppressWarnings("unchecked") GcpGceInstanceMonitoredResource gcpGceInstanceMonitoredResource = (GcpGceInstanceMonitoredResource) resource; - attributesBuilder.putAttributeMap( - createResourceLabelKey(resourceType, "project_id"), - toStringAttributeValueProto(gcpGceInstanceMonitoredResource.getAccount())); - attributesBuilder.putAttributeMap( - createResourceLabelKey(resourceType, "instance_id"), - toStringAttributeValueProto(gcpGceInstanceMonitoredResource.getInstanceId())); - attributesBuilder.putAttributeMap( - createResourceLabelKey(resourceType, "zone"), - toStringAttributeValueProto(gcpGceInstanceMonitoredResource.getZone())); + putResourceAttributeMapToBuilder( + attributesBuilder, + resourceType, + "project_id", + gcpGceInstanceMonitoredResource.getAccount()); + putResourceAttributeMapToBuilder( + attributesBuilder, + resourceType, + "instance_id", + gcpGceInstanceMonitoredResource.getInstanceId()); + putResourceAttributeMapToBuilder( + attributesBuilder, resourceType, "zone", gcpGceInstanceMonitoredResource.getZone()); return; case GCP_GKE_CONTAINER: + @SuppressWarnings("unchecked") GcpGkeContainerMonitoredResource gcpGkeContainerMonitoredResource = (GcpGkeContainerMonitoredResource) resource; - attributesBuilder.putAttributeMap( - createResourceLabelKey(resourceType, "project_id"), - toStringAttributeValueProto(gcpGkeContainerMonitoredResource.getAccount())); - attributesBuilder.putAttributeMap( - createResourceLabelKey(resourceType, "instance_id"), - toStringAttributeValueProto(gcpGkeContainerMonitoredResource.getInstanceId())); - attributesBuilder.putAttributeMap( - createResourceLabelKey(resourceType, "zone"), - toStringAttributeValueProto(gcpGkeContainerMonitoredResource.getZone())); - attributesBuilder.putAttributeMap( - createResourceLabelKey(resourceType, "cluster_name"), - toStringAttributeValueProto(gcpGkeContainerMonitoredResource.getClusterName())); - attributesBuilder.putAttributeMap( - createResourceLabelKey(resourceType, "container_name"), - toStringAttributeValueProto(gcpGkeContainerMonitoredResource.getContainerName())); - attributesBuilder.putAttributeMap( - createResourceLabelKey(resourceType, "namespace_id"), - toStringAttributeValueProto(gcpGkeContainerMonitoredResource.getNamespaceId())); - attributesBuilder.putAttributeMap( - createResourceLabelKey(resourceType, "pod_id"), - toStringAttributeValueProto(gcpGkeContainerMonitoredResource.getPodId())); + putResourceAttributeMapToBuilder( + attributesBuilder, + resourceType, + "project_id", + gcpGkeContainerMonitoredResource.getAccount()); + putResourceAttributeMapToBuilder( + attributesBuilder, + resourceType, + "instance_id", + gcpGkeContainerMonitoredResource.getInstanceId()); + putResourceAttributeMapToBuilder( + attributesBuilder, resourceType, "zone", gcpGkeContainerMonitoredResource.getZone()); + putResourceAttributeMapToBuilder( + attributesBuilder, + resourceType, + "cluster_name", + gcpGkeContainerMonitoredResource.getClusterName()); + putResourceAttributeMapToBuilder( + attributesBuilder, + resourceType, + "container_name", + gcpGkeContainerMonitoredResource.getContainerName()); + putResourceAttributeMapToBuilder( + attributesBuilder, + resourceType, + "namespace_id", + gcpGkeContainerMonitoredResource.getNamespaceId()); + putResourceAttributeMapToBuilder( + attributesBuilder, resourceType, "pod_id", gcpGkeContainerMonitoredResource.getPodId()); return; } } + private static void putResourceAttributeMapToBuilder( + Attributes.Builder attributesBuilder, + ResourceType resourceType, + String attributeName, + String attributeValue) { + attributesBuilder.putAttributeMap( + createResourceLabelKey(resourceType, attributeName), + toStringAttributeValueProto(attributeValue)); + } + @VisibleForTesting static String createResourceLabelKey(ResourceType resourceType, String resourceAttribute) { return String.format("g.co/r/%s/%s", mapToStringResourceType(resourceType), resourceAttribute); @@ -441,7 +471,7 @@ public void export(Collection spanDataList) { .startScopedSpan()) { List spans = new ArrayList<>(spanDataList.size()); for (SpanData spanData : spanDataList) { - spans.add(generateSpan(spanData)); + spans.add(generateSpan(spanData, RESOURCE)); } // Sync call because it is already called for a batch of data, and on a separate thread. // TODO(bdrutu): Consider to make this async in the future. 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 e5888ec15c..0c4c3b74fe 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 @@ -17,8 +17,12 @@ package io.opencensus.exporter.trace.stackdriver; import static com.google.common.truth.Truth.assertThat; +import static io.opencensus.contrib.monitoredresource.util.ResourceType.AWS_EC2_INSTANCE; +import static io.opencensus.contrib.monitoredresource.util.ResourceType.GCP_GCE_INSTANCE; +import static io.opencensus.contrib.monitoredresource.util.ResourceType.GCP_GKE_CONTAINER; import static io.opencensus.exporter.trace.stackdriver.StackdriverV2ExporterHandler.createResourceLabelKey; import static io.opencensus.exporter.trace.stackdriver.StackdriverV2ExporterHandler.toStringAttributeValueProto; +import static org.mockito.Mockito.when; import com.google.auth.Credentials; import com.google.auth.oauth2.AccessToken; @@ -33,7 +37,9 @@ import com.google.devtools.cloudtrace.v2.TruncatableString; import com.google.protobuf.Int32Value; import io.opencensus.common.Timestamp; -import io.opencensus.contrib.monitoredresource.util.ResourceType; +import io.opencensus.contrib.monitoredresource.util.MonitoredResource.AwsEc2InstanceMonitoredResource; +import io.opencensus.contrib.monitoredresource.util.MonitoredResource.GcpGceInstanceMonitoredResource; +import io.opencensus.contrib.monitoredresource.util.MonitoredResource.GcpGkeContainerMonitoredResource; import io.opencensus.trace.Annotation; import io.opencensus.trace.Link; import io.opencensus.trace.Span.Kind; @@ -54,6 +60,8 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.Mockito; @RunWith(JUnit4.class) public final class StackdriverV2ExporterHandlerProtoTest { @@ -125,6 +133,18 @@ public final class StackdriverV2ExporterHandlerProtoTest { private StackdriverV2ExporterHandler handler; + @Mock + private final AwsEc2InstanceMonitoredResource mockAwsEc2Resource = + Mockito.mock(AwsEc2InstanceMonitoredResource.class); + + @Mock + private final GcpGceInstanceMonitoredResource mockGcpGceResource = + Mockito.mock(GcpGceInstanceMonitoredResource.class); + + @Mock + private final GcpGkeContainerMonitoredResource mockGcpGkeResource = + Mockito.mock(GcpGkeContainerMonitoredResource.class); + @Before public void setUp() throws IOException { handler = StackdriverV2ExporterHandler.createWithCredentials(FAKE_CREDENTIALS, PROJECT_ID); @@ -230,7 +250,7 @@ public void generateSpan() { .setNanos(endTimestamp.getNanos()) .build(); - Span span = handler.generateSpan(spanData); + Span span = handler.generateSpan(spanData, null); assertThat(span.getName()).isEqualTo(SD_SPAN_NAME); assertThat(span.getSpanId()).isEqualTo(SPAN_ID); assertThat(span.getParentSpanId()).isEqualTo(PARENT_SPAN_ID); @@ -245,7 +265,6 @@ public void generateSpan() { .containsEntry(ATTRIBUTE_KEY_1, AttributeValue.newBuilder().setIntValue(10L).build()); assertThat(span.getAttributes().getAttributeMapMap()) .containsEntry(ATTRIBUTE_KEY_2, AttributeValue.newBuilder().setBoolValue(true).build()); - verifyResourceLabels(span.getAttributes().getAttributeMapMap()); // TODO(@Hailong): add stack trace test in the future. assertThat(span.getStackTrace()).isEqualTo(StackTrace.newBuilder().build()); assertThat(span.getTimeEvents().getDroppedMessageEventsCount()) @@ -262,33 +281,97 @@ public void generateSpan() { .isEqualTo(Int32Value.newBuilder().setValue(CHILD_SPAN_COUNT).build()); } - private static void verifyResourceLabels(Map attributeMap) { - if (StackdriverV2ExporterHandler.RESOURCE == null) { - return; - } - ResourceType resourceType = StackdriverV2ExporterHandler.RESOURCE.getResourceType(); - switch (resourceType) { - case AWS_EC2_INSTANCE: - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "aws_account")); - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "instance_id")); - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "region")); - return; - case GCP_GCE_INSTANCE: - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "project_id")); - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "instance_id")); - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "zone")); - return; - case GCP_GKE_CONTAINER: - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "project_id")); - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "instance_id")); - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "zone")); - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "cluster_name")); - assertThat(attributeMap) - .containsKey(createResourceLabelKey(resourceType, "container_name")); - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "namespace_id")); - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "pod_id")); - return; - } + @Test + public void generateSpan_AwsEc2Resource() { + when(mockAwsEc2Resource.getResourceType()).thenReturn(AWS_EC2_INSTANCE); + when(mockAwsEc2Resource.getAccount()).thenReturn(""); + when(mockAwsEc2Resource.getInstanceId()).thenReturn(""); + when(mockAwsEc2Resource.getRegion()).thenReturn(""); + SpanData spanData = + SpanData.create( + spanContext, + parentSpanId, + /* hasRemoteParent= */ true, + SPAN_NAME, + null, + startTimestamp, + attributes, + annotations, + messageEvents, + links, + CHILD_SPAN_COUNT, + status, + endTimestamp); + Span span = handler.generateSpan(spanData, mockAwsEc2Resource); + Map attributeMap = span.getAttributes().getAttributeMapMap(); + assertThat(attributeMap).containsKey(createResourceLabelKey(AWS_EC2_INSTANCE, "aws_account")); + assertThat(attributeMap).containsKey(createResourceLabelKey(AWS_EC2_INSTANCE, "instance_id")); + assertThat(attributeMap).containsKey(createResourceLabelKey(AWS_EC2_INSTANCE, "region")); + } + + @Test + public void generateSpan_GcpGceResource() { + when(mockGcpGceResource.getResourceType()).thenReturn(GCP_GCE_INSTANCE); + when(mockGcpGceResource.getAccount()).thenReturn(""); + when(mockGcpGceResource.getInstanceId()).thenReturn(""); + when(mockGcpGceResource.getZone()).thenReturn(""); + SpanData spanData = + SpanData.create( + spanContext, + parentSpanId, + /* hasRemoteParent= */ true, + SPAN_NAME, + null, + startTimestamp, + attributes, + annotations, + messageEvents, + links, + CHILD_SPAN_COUNT, + status, + endTimestamp); + Span span = handler.generateSpan(spanData, mockGcpGceResource); + Map attributeMap = span.getAttributes().getAttributeMapMap(); + assertThat(attributeMap).containsKey(createResourceLabelKey(GCP_GCE_INSTANCE, "project_id")); + assertThat(attributeMap).containsKey(createResourceLabelKey(GCP_GCE_INSTANCE, "instance_id")); + assertThat(attributeMap).containsKey(createResourceLabelKey(GCP_GCE_INSTANCE, "zone")); + } + + @Test + public void generateSpan_GcpGkeResource() { + when(mockGcpGkeResource.getResourceType()).thenReturn(GCP_GKE_CONTAINER); + when(mockGcpGkeResource.getAccount()).thenReturn(""); + when(mockGcpGkeResource.getInstanceId()).thenReturn(""); + when(mockGcpGkeResource.getZone()).thenReturn(""); + when(mockGcpGkeResource.getClusterName()).thenReturn(""); + when(mockGcpGkeResource.getContainerName()).thenReturn(""); + when(mockGcpGkeResource.getNamespaceId()).thenReturn(""); + when(mockGcpGkeResource.getPodId()).thenReturn(""); + SpanData spanData = + SpanData.create( + spanContext, + parentSpanId, + /* hasRemoteParent= */ true, + SPAN_NAME, + null, + startTimestamp, + attributes, + annotations, + messageEvents, + links, + CHILD_SPAN_COUNT, + status, + endTimestamp); + Span span = handler.generateSpan(spanData, mockGcpGkeResource); + Map attributeMap = span.getAttributes().getAttributeMapMap(); + assertThat(attributeMap).containsKey(createResourceLabelKey(GCP_GKE_CONTAINER, "project_id")); + assertThat(attributeMap).containsKey(createResourceLabelKey(GCP_GKE_CONTAINER, "instance_id")); + assertThat(attributeMap).containsKey(createResourceLabelKey(GCP_GKE_CONTAINER, "zone")); + assertThat(attributeMap).containsKey(createResourceLabelKey(GCP_GKE_CONTAINER, "cluster_name")); + assertThat(attributeMap) + .containsKey(createResourceLabelKey(GCP_GKE_CONTAINER, "container_name")); + assertThat(attributeMap).containsKey(createResourceLabelKey(GCP_GKE_CONTAINER, "namespace_id")); + assertThat(attributeMap).containsKey(createResourceLabelKey(GCP_GKE_CONTAINER, "pod_id")); } @Test @@ -323,7 +406,7 @@ public void mapHttpAttributes() { status, endTimestamp); - Span span = handler.generateSpan(spanData); + Span span = handler.generateSpan(spanData, null); Map attributes = span.getAttributes().getAttributeMapMap(); assertThat(attributes).containsEntry("/http/host", toStringAttributeValueProto("host")); @@ -353,7 +436,7 @@ public void generateSpanName_ForServer() { CHILD_SPAN_COUNT, status, endTimestamp); - assertThat(handler.generateSpan(spanData).getDisplayName().getValue()) + assertThat(handler.generateSpan(spanData, null).getDisplayName().getValue()) .isEqualTo("Recv." + SPAN_NAME); } @@ -374,7 +457,7 @@ public void generateSpanName_ForServerWithRecv() { CHILD_SPAN_COUNT, status, endTimestamp); - assertThat(handler.generateSpan(spanData).getDisplayName().getValue()) + assertThat(handler.generateSpan(spanData, null).getDisplayName().getValue()) .isEqualTo("Recv." + SPAN_NAME); } @@ -395,7 +478,7 @@ public void generateSpanName_ForClient() { CHILD_SPAN_COUNT, status, endTimestamp); - assertThat(handler.generateSpan(spanData).getDisplayName().getValue()) + assertThat(handler.generateSpan(spanData, null).getDisplayName().getValue()) .isEqualTo("Sent." + SPAN_NAME); } @@ -416,7 +499,7 @@ public void generateSpanName_ForClientWithSent() { CHILD_SPAN_COUNT, status, endTimestamp); - assertThat(handler.generateSpan(spanData).getDisplayName().getValue()) + assertThat(handler.generateSpan(spanData, null).getDisplayName().getValue()) .isEqualTo("Sent." + SPAN_NAME); } } From 73c9f5ea3dad71a56523fd0741f786c745a5d6ff Mon Sep 17 00:00:00 2001 From: songy23 Date: Fri, 8 Jun 2018 16:06:45 -0700 Subject: [PATCH 3/7] Make resource labels static and only initialize once. --- .../StackdriverV2ExporterHandler.java | 91 ++++++----- ...StackdriverV2ExporterHandlerProtoTest.java | 153 ++++-------------- 2 files changed, 85 insertions(+), 159 deletions(-) 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 556416a69e..4121916535 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 @@ -66,8 +66,10 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; /*>>> import org.checkerframework.checker.nullness.qual.Nullable; @@ -100,6 +102,9 @@ final class StackdriverV2ExporterHandler extends SpanExporter.Handler { @VisibleForTesting @javax.annotation.Nullable static final MonitoredResource RESOURCE = MonitoredResourceUtils.getDefaultResource(); + // Only initialize once. + private static final Map RESOURCE_LABELS = getResourceLabels(RESOURCE); + private final String projectId; private final TraceServiceClient traceServiceClient; private final ProjectName projectName; @@ -131,7 +136,7 @@ static StackdriverV2ExporterHandler create(String projectId) throws IOException } @VisibleForTesting - Span generateSpan(SpanData spanData, @javax.annotation.Nullable MonitoredResource resource) { + Span generateSpan(SpanData spanData) { SpanContext context = spanData.getContext(); final String traceIdHex = encodeTraceId(context.getTraceId()); final String spanIdHex = encodeSpanId(context.getSpanId()); @@ -144,7 +149,7 @@ Span generateSpan(SpanData spanData, @javax.annotation.Nullable MonitoredResourc .setDisplayName( toTruncatableStringProto(toDisplayName(spanData.getName(), spanData.getKind()))) .setStartTime(toTimestampProto(spanData.getStartTimestamp())) - .setAttributes(toAttributesProto(spanData.getAttributes(), resource)) + .setAttributes(toAttributesProto(spanData.getAttributes())) .setTimeEvents( toTimeEventsProto(spanData.getAnnotations(), spanData.getMessageEvents())); io.opencensus.trace.Status status = spanData.getStatus(); @@ -229,13 +234,14 @@ private static TimeEvent.MessageEvent.Type toMessageEventTypeProto( // These are the attributes of the Span, where usually we may add more attributes like the agent. private static Attributes toAttributesProto( - io.opencensus.trace.export.SpanData.Attributes attributes, - @javax.annotation.Nullable MonitoredResource resource) { + io.opencensus.trace.export.SpanData.Attributes attributes) { Attributes.Builder attributesBuilder = toAttributesBuilderProto( attributes.getAttributeMap(), attributes.getDroppedAttributesCount()); attributesBuilder.putAttributeMap(AGENT_LABEL_KEY, AGENT_LABEL_VALUE); - putResourceLabels(attributesBuilder, resource); + for (Entry entry : RESOURCE_LABELS.entrySet()) { + attributesBuilder.putAttributeMap(entry.getKey(), entry.getValue()); + } return attributesBuilder.build(); } @@ -250,93 +256,96 @@ private static Attributes.Builder toAttributesBuilderProto( return attributesBuilder; } - private static void putResourceLabels( - Attributes.Builder attributesBuilder, @javax.annotation.Nullable MonitoredResource resource) { + private static Map getResourceLabels( + @javax.annotation.Nullable MonitoredResource resource) { if (resource == null) { - return; + return Collections.emptyMap(); } + Map resourceLabels = new HashMap(); ResourceType resourceType = resource.getResourceType(); switch (resourceType) { case AWS_EC2_INSTANCE: @SuppressWarnings("unchecked") AwsEc2InstanceMonitoredResource awsEc2InstanceMonitoredResource = (AwsEc2InstanceMonitoredResource) resource; - putResourceAttributeMapToBuilder( - attributesBuilder, + putToResourceAttributeMap( + resourceLabels, resourceType, "aws_account", awsEc2InstanceMonitoredResource.getAccount()); - putResourceAttributeMapToBuilder( - attributesBuilder, + putToResourceAttributeMap( + resourceLabels, resourceType, "instance_id", awsEc2InstanceMonitoredResource.getInstanceId()); - putResourceAttributeMapToBuilder( - attributesBuilder, + putToResourceAttributeMap( + resourceLabels, resourceType, "region", "aws:" + awsEc2InstanceMonitoredResource.getRegion()); - return; + return Collections.unmodifiableMap(resourceLabels); case GCP_GCE_INSTANCE: @SuppressWarnings("unchecked") GcpGceInstanceMonitoredResource gcpGceInstanceMonitoredResource = (GcpGceInstanceMonitoredResource) resource; - putResourceAttributeMapToBuilder( - attributesBuilder, + putToResourceAttributeMap( + resourceLabels, resourceType, "project_id", gcpGceInstanceMonitoredResource.getAccount()); - putResourceAttributeMapToBuilder( - attributesBuilder, + putToResourceAttributeMap( + resourceLabels, resourceType, "instance_id", gcpGceInstanceMonitoredResource.getInstanceId()); - putResourceAttributeMapToBuilder( - attributesBuilder, resourceType, "zone", gcpGceInstanceMonitoredResource.getZone()); - return; + putToResourceAttributeMap( + resourceLabels, resourceType, "zone", gcpGceInstanceMonitoredResource.getZone()); + return Collections.unmodifiableMap(resourceLabels); case GCP_GKE_CONTAINER: @SuppressWarnings("unchecked") GcpGkeContainerMonitoredResource gcpGkeContainerMonitoredResource = (GcpGkeContainerMonitoredResource) resource; - putResourceAttributeMapToBuilder( - attributesBuilder, + putToResourceAttributeMap( + resourceLabels, resourceType, "project_id", gcpGkeContainerMonitoredResource.getAccount()); - putResourceAttributeMapToBuilder( - attributesBuilder, + putToResourceAttributeMap( + resourceLabels, resourceType, "instance_id", gcpGkeContainerMonitoredResource.getInstanceId()); - putResourceAttributeMapToBuilder( - attributesBuilder, resourceType, "zone", gcpGkeContainerMonitoredResource.getZone()); - putResourceAttributeMapToBuilder( - attributesBuilder, + putToResourceAttributeMap( + resourceLabels, resourceType, "zone", gcpGkeContainerMonitoredResource.getZone()); + putToResourceAttributeMap( + resourceLabels, resourceType, "cluster_name", gcpGkeContainerMonitoredResource.getClusterName()); - putResourceAttributeMapToBuilder( - attributesBuilder, + putToResourceAttributeMap( + resourceLabels, resourceType, "container_name", gcpGkeContainerMonitoredResource.getContainerName()); - putResourceAttributeMapToBuilder( - attributesBuilder, + putToResourceAttributeMap( + resourceLabels, resourceType, "namespace_id", gcpGkeContainerMonitoredResource.getNamespaceId()); - putResourceAttributeMapToBuilder( - attributesBuilder, resourceType, "pod_id", gcpGkeContainerMonitoredResource.getPodId()); - return; + putToResourceAttributeMap( + resourceLabels, resourceType, "pod_id", gcpGkeContainerMonitoredResource.getPodId()); + return Collections.unmodifiableMap(resourceLabels); + default: + return Collections.emptyMap(); } } - private static void putResourceAttributeMapToBuilder( - Attributes.Builder attributesBuilder, + private static void putToResourceAttributeMap( + Map map, ResourceType resourceType, String attributeName, String attributeValue) { - attributesBuilder.putAttributeMap( + map.put( createResourceLabelKey(resourceType, attributeName), toStringAttributeValueProto(attributeValue)); } @@ -471,7 +480,7 @@ public void export(Collection spanDataList) { .startScopedSpan()) { List spans = new ArrayList<>(spanDataList.size()); for (SpanData spanData : spanDataList) { - spans.add(generateSpan(spanData, RESOURCE)); + spans.add(generateSpan(spanData)); } // Sync call because it is already called for a batch of data, and on a separate thread. // TODO(bdrutu): Consider to make this async in the future. 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 0c4c3b74fe..e5888ec15c 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 @@ -17,12 +17,8 @@ package io.opencensus.exporter.trace.stackdriver; import static com.google.common.truth.Truth.assertThat; -import static io.opencensus.contrib.monitoredresource.util.ResourceType.AWS_EC2_INSTANCE; -import static io.opencensus.contrib.monitoredresource.util.ResourceType.GCP_GCE_INSTANCE; -import static io.opencensus.contrib.monitoredresource.util.ResourceType.GCP_GKE_CONTAINER; import static io.opencensus.exporter.trace.stackdriver.StackdriverV2ExporterHandler.createResourceLabelKey; import static io.opencensus.exporter.trace.stackdriver.StackdriverV2ExporterHandler.toStringAttributeValueProto; -import static org.mockito.Mockito.when; import com.google.auth.Credentials; import com.google.auth.oauth2.AccessToken; @@ -37,9 +33,7 @@ import com.google.devtools.cloudtrace.v2.TruncatableString; import com.google.protobuf.Int32Value; import io.opencensus.common.Timestamp; -import io.opencensus.contrib.monitoredresource.util.MonitoredResource.AwsEc2InstanceMonitoredResource; -import io.opencensus.contrib.monitoredresource.util.MonitoredResource.GcpGceInstanceMonitoredResource; -import io.opencensus.contrib.monitoredresource.util.MonitoredResource.GcpGkeContainerMonitoredResource; +import io.opencensus.contrib.monitoredresource.util.ResourceType; import io.opencensus.trace.Annotation; import io.opencensus.trace.Link; import io.opencensus.trace.Span.Kind; @@ -60,8 +54,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -import org.mockito.Mock; -import org.mockito.Mockito; @RunWith(JUnit4.class) public final class StackdriverV2ExporterHandlerProtoTest { @@ -133,18 +125,6 @@ public final class StackdriverV2ExporterHandlerProtoTest { private StackdriverV2ExporterHandler handler; - @Mock - private final AwsEc2InstanceMonitoredResource mockAwsEc2Resource = - Mockito.mock(AwsEc2InstanceMonitoredResource.class); - - @Mock - private final GcpGceInstanceMonitoredResource mockGcpGceResource = - Mockito.mock(GcpGceInstanceMonitoredResource.class); - - @Mock - private final GcpGkeContainerMonitoredResource mockGcpGkeResource = - Mockito.mock(GcpGkeContainerMonitoredResource.class); - @Before public void setUp() throws IOException { handler = StackdriverV2ExporterHandler.createWithCredentials(FAKE_CREDENTIALS, PROJECT_ID); @@ -250,7 +230,7 @@ public void generateSpan() { .setNanos(endTimestamp.getNanos()) .build(); - Span span = handler.generateSpan(spanData, null); + Span span = handler.generateSpan(spanData); assertThat(span.getName()).isEqualTo(SD_SPAN_NAME); assertThat(span.getSpanId()).isEqualTo(SPAN_ID); assertThat(span.getParentSpanId()).isEqualTo(PARENT_SPAN_ID); @@ -265,6 +245,7 @@ public void generateSpan() { .containsEntry(ATTRIBUTE_KEY_1, AttributeValue.newBuilder().setIntValue(10L).build()); assertThat(span.getAttributes().getAttributeMapMap()) .containsEntry(ATTRIBUTE_KEY_2, AttributeValue.newBuilder().setBoolValue(true).build()); + verifyResourceLabels(span.getAttributes().getAttributeMapMap()); // TODO(@Hailong): add stack trace test in the future. assertThat(span.getStackTrace()).isEqualTo(StackTrace.newBuilder().build()); assertThat(span.getTimeEvents().getDroppedMessageEventsCount()) @@ -281,97 +262,33 @@ public void generateSpan() { .isEqualTo(Int32Value.newBuilder().setValue(CHILD_SPAN_COUNT).build()); } - @Test - public void generateSpan_AwsEc2Resource() { - when(mockAwsEc2Resource.getResourceType()).thenReturn(AWS_EC2_INSTANCE); - when(mockAwsEc2Resource.getAccount()).thenReturn(""); - when(mockAwsEc2Resource.getInstanceId()).thenReturn(""); - when(mockAwsEc2Resource.getRegion()).thenReturn(""); - SpanData spanData = - SpanData.create( - spanContext, - parentSpanId, - /* hasRemoteParent= */ true, - SPAN_NAME, - null, - startTimestamp, - attributes, - annotations, - messageEvents, - links, - CHILD_SPAN_COUNT, - status, - endTimestamp); - Span span = handler.generateSpan(spanData, mockAwsEc2Resource); - Map attributeMap = span.getAttributes().getAttributeMapMap(); - assertThat(attributeMap).containsKey(createResourceLabelKey(AWS_EC2_INSTANCE, "aws_account")); - assertThat(attributeMap).containsKey(createResourceLabelKey(AWS_EC2_INSTANCE, "instance_id")); - assertThat(attributeMap).containsKey(createResourceLabelKey(AWS_EC2_INSTANCE, "region")); - } - - @Test - public void generateSpan_GcpGceResource() { - when(mockGcpGceResource.getResourceType()).thenReturn(GCP_GCE_INSTANCE); - when(mockGcpGceResource.getAccount()).thenReturn(""); - when(mockGcpGceResource.getInstanceId()).thenReturn(""); - when(mockGcpGceResource.getZone()).thenReturn(""); - SpanData spanData = - SpanData.create( - spanContext, - parentSpanId, - /* hasRemoteParent= */ true, - SPAN_NAME, - null, - startTimestamp, - attributes, - annotations, - messageEvents, - links, - CHILD_SPAN_COUNT, - status, - endTimestamp); - Span span = handler.generateSpan(spanData, mockGcpGceResource); - Map attributeMap = span.getAttributes().getAttributeMapMap(); - assertThat(attributeMap).containsKey(createResourceLabelKey(GCP_GCE_INSTANCE, "project_id")); - assertThat(attributeMap).containsKey(createResourceLabelKey(GCP_GCE_INSTANCE, "instance_id")); - assertThat(attributeMap).containsKey(createResourceLabelKey(GCP_GCE_INSTANCE, "zone")); - } - - @Test - public void generateSpan_GcpGkeResource() { - when(mockGcpGkeResource.getResourceType()).thenReturn(GCP_GKE_CONTAINER); - when(mockGcpGkeResource.getAccount()).thenReturn(""); - when(mockGcpGkeResource.getInstanceId()).thenReturn(""); - when(mockGcpGkeResource.getZone()).thenReturn(""); - when(mockGcpGkeResource.getClusterName()).thenReturn(""); - when(mockGcpGkeResource.getContainerName()).thenReturn(""); - when(mockGcpGkeResource.getNamespaceId()).thenReturn(""); - when(mockGcpGkeResource.getPodId()).thenReturn(""); - SpanData spanData = - SpanData.create( - spanContext, - parentSpanId, - /* hasRemoteParent= */ true, - SPAN_NAME, - null, - startTimestamp, - attributes, - annotations, - messageEvents, - links, - CHILD_SPAN_COUNT, - status, - endTimestamp); - Span span = handler.generateSpan(spanData, mockGcpGkeResource); - Map attributeMap = span.getAttributes().getAttributeMapMap(); - assertThat(attributeMap).containsKey(createResourceLabelKey(GCP_GKE_CONTAINER, "project_id")); - assertThat(attributeMap).containsKey(createResourceLabelKey(GCP_GKE_CONTAINER, "instance_id")); - assertThat(attributeMap).containsKey(createResourceLabelKey(GCP_GKE_CONTAINER, "zone")); - assertThat(attributeMap).containsKey(createResourceLabelKey(GCP_GKE_CONTAINER, "cluster_name")); - assertThat(attributeMap) - .containsKey(createResourceLabelKey(GCP_GKE_CONTAINER, "container_name")); - assertThat(attributeMap).containsKey(createResourceLabelKey(GCP_GKE_CONTAINER, "namespace_id")); - assertThat(attributeMap).containsKey(createResourceLabelKey(GCP_GKE_CONTAINER, "pod_id")); + private static void verifyResourceLabels(Map attributeMap) { + if (StackdriverV2ExporterHandler.RESOURCE == null) { + return; + } + ResourceType resourceType = StackdriverV2ExporterHandler.RESOURCE.getResourceType(); + switch (resourceType) { + case AWS_EC2_INSTANCE: + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "aws_account")); + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "instance_id")); + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "region")); + return; + case GCP_GCE_INSTANCE: + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "project_id")); + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "instance_id")); + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "zone")); + return; + case GCP_GKE_CONTAINER: + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "project_id")); + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "instance_id")); + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "zone")); + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "cluster_name")); + assertThat(attributeMap) + .containsKey(createResourceLabelKey(resourceType, "container_name")); + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "namespace_id")); + assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "pod_id")); + return; + } } @Test @@ -406,7 +323,7 @@ public void mapHttpAttributes() { status, endTimestamp); - Span span = handler.generateSpan(spanData, null); + Span span = handler.generateSpan(spanData); Map attributes = span.getAttributes().getAttributeMapMap(); assertThat(attributes).containsEntry("/http/host", toStringAttributeValueProto("host")); @@ -436,7 +353,7 @@ public void generateSpanName_ForServer() { CHILD_SPAN_COUNT, status, endTimestamp); - assertThat(handler.generateSpan(spanData, null).getDisplayName().getValue()) + assertThat(handler.generateSpan(spanData).getDisplayName().getValue()) .isEqualTo("Recv." + SPAN_NAME); } @@ -457,7 +374,7 @@ public void generateSpanName_ForServerWithRecv() { CHILD_SPAN_COUNT, status, endTimestamp); - assertThat(handler.generateSpan(spanData, null).getDisplayName().getValue()) + assertThat(handler.generateSpan(spanData).getDisplayName().getValue()) .isEqualTo("Recv." + SPAN_NAME); } @@ -478,7 +395,7 @@ public void generateSpanName_ForClient() { CHILD_SPAN_COUNT, status, endTimestamp); - assertThat(handler.generateSpan(spanData, null).getDisplayName().getValue()) + assertThat(handler.generateSpan(spanData).getDisplayName().getValue()) .isEqualTo("Sent." + SPAN_NAME); } @@ -499,7 +416,7 @@ public void generateSpanName_ForClientWithSent() { CHILD_SPAN_COUNT, status, endTimestamp); - assertThat(handler.generateSpan(spanData, null).getDisplayName().getValue()) + assertThat(handler.generateSpan(spanData).getDisplayName().getValue()) .isEqualTo("Sent." + SPAN_NAME); } } From d62d5baa74c1767dffd34f68cdf773d052b2feba Mon Sep 17 00:00:00 2001 From: songy23 Date: Mon, 11 Jun 2018 17:57:05 -0700 Subject: [PATCH 4/7] Remove SuppressWarnings("unchecked") --- .../trace/stackdriver/StackdriverV2ExporterHandler.java | 3 --- 1 file changed, 3 deletions(-) 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 4121916535..3ff3932442 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 @@ -265,7 +265,6 @@ private static Map getResourceLabels( ResourceType resourceType = resource.getResourceType(); switch (resourceType) { case AWS_EC2_INSTANCE: - @SuppressWarnings("unchecked") AwsEc2InstanceMonitoredResource awsEc2InstanceMonitoredResource = (AwsEc2InstanceMonitoredResource) resource; putToResourceAttributeMap( @@ -285,7 +284,6 @@ private static Map getResourceLabels( "aws:" + awsEc2InstanceMonitoredResource.getRegion()); return Collections.unmodifiableMap(resourceLabels); case GCP_GCE_INSTANCE: - @SuppressWarnings("unchecked") GcpGceInstanceMonitoredResource gcpGceInstanceMonitoredResource = (GcpGceInstanceMonitoredResource) resource; putToResourceAttributeMap( @@ -302,7 +300,6 @@ private static Map getResourceLabels( resourceLabels, resourceType, "zone", gcpGceInstanceMonitoredResource.getZone()); return Collections.unmodifiableMap(resourceLabels); case GCP_GKE_CONTAINER: - @SuppressWarnings("unchecked") GcpGkeContainerMonitoredResource gcpGkeContainerMonitoredResource = (GcpGkeContainerMonitoredResource) resource; putToResourceAttributeMap( From 64abe59eac3e6b8820c06637998558c30a936559 Mon Sep 17 00:00:00 2001 From: songy23 Date: Mon, 11 Jun 2018 18:25:36 -0700 Subject: [PATCH 5/7] Passing resource_label map to generateSpan(). --- .../StackdriverV2ExporterHandler.java | 16 ++-- ...StackdriverV2ExporterHandlerProtoTest.java | 83 +++++++++++-------- 2 files changed, 57 insertions(+), 42 deletions(-) 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 3ff3932442..bba92373e3 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 @@ -99,8 +99,8 @@ final class StackdriverV2ExporterHandler extends SpanExporter.Handler { .put("http.status_code", "/http/status_code") .build(); - @VisibleForTesting @javax.annotation.Nullable - static final MonitoredResource RESOURCE = MonitoredResourceUtils.getDefaultResource(); + @javax.annotation.Nullable + private static final MonitoredResource RESOURCE = MonitoredResourceUtils.getDefaultResource(); // Only initialize once. private static final Map RESOURCE_LABELS = getResourceLabels(RESOURCE); @@ -136,7 +136,7 @@ static StackdriverV2ExporterHandler create(String projectId) throws IOException } @VisibleForTesting - Span generateSpan(SpanData spanData) { + Span generateSpan(SpanData spanData, Map resourceLabels) { SpanContext context = spanData.getContext(); final String traceIdHex = encodeTraceId(context.getTraceId()); final String spanIdHex = encodeSpanId(context.getSpanId()); @@ -149,7 +149,7 @@ Span generateSpan(SpanData spanData) { .setDisplayName( toTruncatableStringProto(toDisplayName(spanData.getName(), spanData.getKind()))) .setStartTime(toTimestampProto(spanData.getStartTimestamp())) - .setAttributes(toAttributesProto(spanData.getAttributes())) + .setAttributes(toAttributesProto(spanData.getAttributes(), resourceLabels)) .setTimeEvents( toTimeEventsProto(spanData.getAnnotations(), spanData.getMessageEvents())); io.opencensus.trace.Status status = spanData.getStatus(); @@ -234,12 +234,13 @@ private static TimeEvent.MessageEvent.Type toMessageEventTypeProto( // These are the attributes of the Span, where usually we may add more attributes like the agent. private static Attributes toAttributesProto( - io.opencensus.trace.export.SpanData.Attributes attributes) { + io.opencensus.trace.export.SpanData.Attributes attributes, + Map resourceLabels) { Attributes.Builder attributesBuilder = toAttributesBuilderProto( attributes.getAttributeMap(), attributes.getDroppedAttributesCount()); attributesBuilder.putAttributeMap(AGENT_LABEL_KEY, AGENT_LABEL_VALUE); - for (Entry entry : RESOURCE_LABELS.entrySet()) { + for (Entry entry : resourceLabels.entrySet()) { attributesBuilder.putAttributeMap(entry.getKey(), entry.getValue()); } return attributesBuilder.build(); @@ -256,6 +257,7 @@ private static Attributes.Builder toAttributesBuilderProto( return attributesBuilder; } + // TODO(songya): make constructor of MonitoredResource public, and add unit tests for this method. private static Map getResourceLabels( @javax.annotation.Nullable MonitoredResource resource) { if (resource == null) { @@ -477,7 +479,7 @@ public void export(Collection spanDataList) { .startScopedSpan()) { List spans = new ArrayList<>(spanDataList.size()); for (SpanData spanData : spanDataList) { - spans.add(generateSpan(spanData)); + spans.add(generateSpan(spanData, RESOURCE_LABELS)); } // Sync call because it is already called for a batch of data, and on a separate thread. // TODO(bdrutu): Consider to make this async in the future. 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 e5888ec15c..f6e05a1750 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 @@ -17,6 +17,7 @@ package io.opencensus.exporter.trace.stackdriver; import static com.google.common.truth.Truth.assertThat; +import static io.opencensus.contrib.monitoredresource.util.ResourceType.GCP_GCE_INSTANCE; import static io.opencensus.exporter.trace.stackdriver.StackdriverV2ExporterHandler.createResourceLabelKey; import static io.opencensus.exporter.trace.stackdriver.StackdriverV2ExporterHandler.toStringAttributeValueProto; @@ -33,7 +34,6 @@ import com.google.devtools.cloudtrace.v2.TruncatableString; import com.google.protobuf.Int32Value; import io.opencensus.common.Timestamp; -import io.opencensus.contrib.monitoredresource.util.ResourceType; import io.opencensus.trace.Annotation; import io.opencensus.trace.Link; import io.opencensus.trace.Span.Kind; @@ -46,6 +46,7 @@ import io.opencensus.trace.export.SpanData.TimedEvent; import io.opencensus.trace.export.SpanData.TimedEvents; import java.io.IOException; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -122,6 +123,15 @@ public final class StackdriverV2ExporterHandlerProtoTest { private static final TimedEvents messageEvents = TimedEvents.create(networkEventsList, DROPPED_NETWORKEVENTS_COUNT); private static final SpanData.Links links = SpanData.Links.create(linksList, DROPPED_LINKS_COUNT); + private static final Map EMPTY_RESOURCE_LABELS = Collections.emptyMap(); + private static final ImmutableMap GCE_RESOURCE_LABELS = + ImmutableMap.of( + createResourceLabelKey(GCP_GCE_INSTANCE, "project-id"), + toStringAttributeValueProto("my-project"), + createResourceLabelKey(GCP_GCE_INSTANCE, "instance-id"), + toStringAttributeValueProto("my-instance"), + createResourceLabelKey(GCP_GCE_INSTANCE, "zone"), + toStringAttributeValueProto("us-east1")); private StackdriverV2ExporterHandler handler; @@ -230,7 +240,7 @@ public void generateSpan() { .setNanos(endTimestamp.getNanos()) .build(); - Span span = handler.generateSpan(spanData); + Span span = handler.generateSpan(spanData, EMPTY_RESOURCE_LABELS); assertThat(span.getName()).isEqualTo(SD_SPAN_NAME); assertThat(span.getSpanId()).isEqualTo(SPAN_ID); assertThat(span.getParentSpanId()).isEqualTo(PARENT_SPAN_ID); @@ -245,7 +255,6 @@ public void generateSpan() { .containsEntry(ATTRIBUTE_KEY_1, AttributeValue.newBuilder().setIntValue(10L).build()); assertThat(span.getAttributes().getAttributeMapMap()) .containsEntry(ATTRIBUTE_KEY_2, AttributeValue.newBuilder().setBoolValue(true).build()); - verifyResourceLabels(span.getAttributes().getAttributeMapMap()); // TODO(@Hailong): add stack trace test in the future. assertThat(span.getStackTrace()).isEqualTo(StackTrace.newBuilder().build()); assertThat(span.getTimeEvents().getDroppedMessageEventsCount()) @@ -262,33 +271,37 @@ public void generateSpan() { .isEqualTo(Int32Value.newBuilder().setValue(CHILD_SPAN_COUNT).build()); } - private static void verifyResourceLabels(Map attributeMap) { - if (StackdriverV2ExporterHandler.RESOURCE == null) { - return; - } - ResourceType resourceType = StackdriverV2ExporterHandler.RESOURCE.getResourceType(); - switch (resourceType) { - case AWS_EC2_INSTANCE: - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "aws_account")); - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "instance_id")); - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "region")); - return; - case GCP_GCE_INSTANCE: - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "project_id")); - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "instance_id")); - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "zone")); - return; - case GCP_GKE_CONTAINER: - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "project_id")); - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "instance_id")); - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "zone")); - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "cluster_name")); - assertThat(attributeMap) - .containsKey(createResourceLabelKey(resourceType, "container_name")); - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "namespace_id")); - assertThat(attributeMap).containsKey(createResourceLabelKey(resourceType, "pod_id")); - return; - } + @Test + public void generateSpan_WithResourceLabels() { + SpanData spanData = + SpanData.create( + spanContext, + parentSpanId, + /* hasRemoteParent= */ true, + SPAN_NAME, + null, + startTimestamp, + attributes, + annotations, + messageEvents, + links, + CHILD_SPAN_COUNT, + status, + endTimestamp); + Span span = handler.generateSpan(spanData, GCE_RESOURCE_LABELS); + Map attributeMap = span.getAttributes().getAttributeMapMap(); + assertThat(attributeMap) + .containsEntry( + createResourceLabelKey(GCP_GCE_INSTANCE, "project-id"), + toStringAttributeValueProto("my-project")); + assertThat(attributeMap) + .containsEntry( + createResourceLabelKey(GCP_GCE_INSTANCE, "instance-id"), + toStringAttributeValueProto("my-instance")); + assertThat(attributeMap) + .containsEntry( + createResourceLabelKey(GCP_GCE_INSTANCE, "zone"), + toStringAttributeValueProto("us-east1")); } @Test @@ -323,7 +336,7 @@ public void mapHttpAttributes() { status, endTimestamp); - Span span = handler.generateSpan(spanData); + Span span = handler.generateSpan(spanData, EMPTY_RESOURCE_LABELS); Map attributes = span.getAttributes().getAttributeMapMap(); assertThat(attributes).containsEntry("/http/host", toStringAttributeValueProto("host")); @@ -353,7 +366,7 @@ public void generateSpanName_ForServer() { CHILD_SPAN_COUNT, status, endTimestamp); - assertThat(handler.generateSpan(spanData).getDisplayName().getValue()) + assertThat(handler.generateSpan(spanData, EMPTY_RESOURCE_LABELS).getDisplayName().getValue()) .isEqualTo("Recv." + SPAN_NAME); } @@ -374,7 +387,7 @@ public void generateSpanName_ForServerWithRecv() { CHILD_SPAN_COUNT, status, endTimestamp); - assertThat(handler.generateSpan(spanData).getDisplayName().getValue()) + assertThat(handler.generateSpan(spanData, EMPTY_RESOURCE_LABELS).getDisplayName().getValue()) .isEqualTo("Recv." + SPAN_NAME); } @@ -395,7 +408,7 @@ public void generateSpanName_ForClient() { CHILD_SPAN_COUNT, status, endTimestamp); - assertThat(handler.generateSpan(spanData).getDisplayName().getValue()) + assertThat(handler.generateSpan(spanData, EMPTY_RESOURCE_LABELS).getDisplayName().getValue()) .isEqualTo("Sent." + SPAN_NAME); } @@ -416,7 +429,7 @@ public void generateSpanName_ForClientWithSent() { CHILD_SPAN_COUNT, status, endTimestamp); - assertThat(handler.generateSpan(spanData).getDisplayName().getValue()) + assertThat(handler.generateSpan(spanData, EMPTY_RESOURCE_LABELS).getDisplayName().getValue()) .isEqualTo("Sent." + SPAN_NAME); } } From 55c13af8b8565ce5b7e2bd054c5f8ab022c0a023 Mon Sep 17 00:00:00 2001 From: songy23 Date: Mon, 11 Jun 2018 19:11:50 -0700 Subject: [PATCH 6/7] Fix a checkstyle error. --- .../trace/stackdriver/StackdriverV2ExporterHandler.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 bba92373e3..0993fd8005 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 @@ -334,9 +334,8 @@ private static Map getResourceLabels( putToResourceAttributeMap( resourceLabels, resourceType, "pod_id", gcpGkeContainerMonitoredResource.getPodId()); return Collections.unmodifiableMap(resourceLabels); - default: - return Collections.emptyMap(); } + return Collections.emptyMap(); } private static void putToResourceAttributeMap( From f1e2bdb04d237852810275fde41579cca6b1a496 Mon Sep 17 00:00:00 2001 From: songy23 Date: Mon, 11 Jun 2018 21:07:14 -0700 Subject: [PATCH 7/7] Add more unit tests on resource labels. --- ...StackdriverV2ExporterHandlerProtoTest.java | 69 ++++++++++++++----- 1 file changed, 53 insertions(+), 16 deletions(-) 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 f6e05a1750..6674dd9153 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 @@ -17,7 +17,9 @@ package io.opencensus.exporter.trace.stackdriver; import static com.google.common.truth.Truth.assertThat; +import static io.opencensus.contrib.monitoredresource.util.ResourceType.AWS_EC2_INSTANCE; import static io.opencensus.contrib.monitoredresource.util.ResourceType.GCP_GCE_INSTANCE; +import static io.opencensus.contrib.monitoredresource.util.ResourceType.GCP_GKE_CONTAINER; import static io.opencensus.exporter.trace.stackdriver.StackdriverV2ExporterHandler.createResourceLabelKey; import static io.opencensus.exporter.trace.stackdriver.StackdriverV2ExporterHandler.toStringAttributeValueProto; @@ -124,14 +126,46 @@ public final class StackdriverV2ExporterHandlerProtoTest { TimedEvents.create(networkEventsList, DROPPED_NETWORKEVENTS_COUNT); private static final SpanData.Links links = SpanData.Links.create(linksList, DROPPED_LINKS_COUNT); private static final Map EMPTY_RESOURCE_LABELS = Collections.emptyMap(); + private static final ImmutableMap AWS_RESOURCE_LABELS = + ImmutableMap.of( + createResourceLabelKey(AWS_EC2_INSTANCE, "aws_account"), + toStringAttributeValueProto("my-project"), + createResourceLabelKey(AWS_EC2_INSTANCE, "instance_id"), + toStringAttributeValueProto("my-instance"), + createResourceLabelKey(AWS_EC2_INSTANCE, "region"), + toStringAttributeValueProto("us-east-1")); private static final ImmutableMap GCE_RESOURCE_LABELS = ImmutableMap.of( - createResourceLabelKey(GCP_GCE_INSTANCE, "project-id"), + createResourceLabelKey(GCP_GCE_INSTANCE, "project_id"), toStringAttributeValueProto("my-project"), - createResourceLabelKey(GCP_GCE_INSTANCE, "instance-id"), + createResourceLabelKey(GCP_GCE_INSTANCE, "instance_id"), toStringAttributeValueProto("my-instance"), createResourceLabelKey(GCP_GCE_INSTANCE, "zone"), toStringAttributeValueProto("us-east1")); + private static final ImmutableMap GKE_RESOURCE_LABELS = + ImmutableMap.builder() + .put( + createResourceLabelKey(GCP_GKE_CONTAINER, "project_id"), + toStringAttributeValueProto("my-project")) + .put( + createResourceLabelKey(GCP_GKE_CONTAINER, "cluster_name"), + toStringAttributeValueProto("cluster")) + .put( + createResourceLabelKey(GCP_GKE_CONTAINER, "container_name"), + toStringAttributeValueProto("container")) + .put( + createResourceLabelKey(GCP_GKE_CONTAINER, "namespace_id"), + toStringAttributeValueProto("namespace")) + .put( + createResourceLabelKey(GCP_GKE_CONTAINER, "instance_id"), + toStringAttributeValueProto("my-instance")) + .put( + createResourceLabelKey(GCP_GKE_CONTAINER, "pod_id"), + toStringAttributeValueProto("pod")) + .put( + createResourceLabelKey(GCP_GKE_CONTAINER, "zone"), + toStringAttributeValueProto("us-east1")) + .build(); private StackdriverV2ExporterHandler handler; @@ -272,7 +306,21 @@ public void generateSpan() { } @Test - public void generateSpan_WithResourceLabels() { + public void generateSpan_WithAwsEc2ResourceLabels() { + generateSpan_WithResourceLabels(AWS_RESOURCE_LABELS); + } + + @Test + public void generateSpan_WithGceResourceLabels() { + generateSpan_WithResourceLabels(GCE_RESOURCE_LABELS); + } + + @Test + public void generateSpan_WithGkeResourceLabels() { + generateSpan_WithResourceLabels(GKE_RESOURCE_LABELS); + } + + private void generateSpan_WithResourceLabels(Map resourceLabels) { SpanData spanData = SpanData.create( spanContext, @@ -288,20 +336,9 @@ public void generateSpan_WithResourceLabels() { CHILD_SPAN_COUNT, status, endTimestamp); - Span span = handler.generateSpan(spanData, GCE_RESOURCE_LABELS); + Span span = handler.generateSpan(spanData, resourceLabels); Map attributeMap = span.getAttributes().getAttributeMapMap(); - assertThat(attributeMap) - .containsEntry( - createResourceLabelKey(GCP_GCE_INSTANCE, "project-id"), - toStringAttributeValueProto("my-project")); - assertThat(attributeMap) - .containsEntry( - createResourceLabelKey(GCP_GCE_INSTANCE, "instance-id"), - toStringAttributeValueProto("my-instance")); - assertThat(attributeMap) - .containsEntry( - createResourceLabelKey(GCP_GCE_INSTANCE, "zone"), - toStringAttributeValueProto("us-east1")); + assertThat(attributeMap.entrySet()).containsAllIn(resourceLabels.entrySet()); } @Test