Stats: Map deprecated RPC tags when record against new tags. (#1854)
diff --git a/impl_core/src/main/java/io/opencensus/implcore/stats/RecordUtils.java b/impl_core/src/main/java/io/opencensus/implcore/stats/RecordUtils.java index e97c107..a9bba2c 100644 --- a/impl_core/src/main/java/io/opencensus/implcore/stats/RecordUtils.java +++ b/impl_core/src/main/java/io/opencensus/implcore/stats/RecordUtils.java
@@ -17,6 +17,7 @@ package io.opencensus.implcore.stats; import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import io.opencensus.common.Function; import io.opencensus.common.Functions; @@ -62,6 +63,19 @@ @javax.annotation.Nullable @VisibleForTesting static final TagValue UNKNOWN_TAG_VALUE = null; + // TODO(songy23): remove the mapping once we completely remove the deprecated RPC constants. + @VisibleForTesting static final TagKey RPC_STATUS = TagKey.create("canonical_status"); + @VisibleForTesting static final TagKey RPC_METHOD = TagKey.create("method"); + @VisibleForTesting static final TagKey GRPC_CLIENT_STATUS = TagKey.create("grpc_client_status"); + @VisibleForTesting static final TagKey GRPC_CLIENT_METHOD = TagKey.create("grpc_client_method"); + @VisibleForTesting static final TagKey GRPC_SERVER_STATUS = TagKey.create("grpc_server_status"); + @VisibleForTesting static final TagKey GRPC_SERVER_METHOD = TagKey.create("grpc_server_method"); + private static final Map<TagKey, TagKey[]> RPC_TAG_MAPPINGS = + ImmutableMap.<TagKey, TagKey[]>builder() + .put(RPC_STATUS, new TagKey[] {GRPC_CLIENT_STATUS, GRPC_SERVER_STATUS}) + .put(RPC_METHOD, new TagKey[] {GRPC_CLIENT_METHOD, GRPC_SERVER_METHOD}) + .build(); + static Map<TagKey, TagValueWithMetadata> getTagMap(TagContext ctx) { if (ctx instanceof TagMapImpl) { return ((TagMapImpl) ctx).getTags(); @@ -83,8 +97,12 @@ for (int i = 0; i < columns.size(); ++i) { TagKey tagKey = columns.get(i); if (!tags.containsKey(tagKey)) { - // replace not found key values by null. - tagValues.add(UNKNOWN_TAG_VALUE); + @javax.annotation.Nullable TagValue tagValue = UNKNOWN_TAG_VALUE; + TagKey[] newKeys = RPC_TAG_MAPPINGS.get(tagKey); + if (newKeys != null) { + tagValue = getTagValueForDeprecatedRpcTag(tags, newKeys); + } + tagValues.add(tagValue); } else { tagValues.add(tags.get(tagKey).getTagValue()); } @@ -92,6 +110,19 @@ return tagValues; } + // TODO(songy23): remove the mapping once we completely remove the deprecated RPC constants. + @javax.annotation.Nullable + private static TagValue getTagValueForDeprecatedRpcTag( + Map<? extends TagKey, TagValueWithMetadata> tags, TagKey[] newKeys) { + for (TagKey newKey : newKeys) { + TagValueWithMetadata valueWithMetadata = tags.get(newKey); + if (valueWithMetadata != null) { + return valueWithMetadata.getTagValue(); + } + } + return UNKNOWN_TAG_VALUE; + } + /** * Create an empty {@link MutableAggregation} based on the given {@link Aggregation}. *
diff --git a/impl_core/src/test/java/io/opencensus/implcore/stats/RecordUtilsTest.java b/impl_core/src/test/java/io/opencensus/implcore/stats/RecordUtilsTest.java index 5a70a19..3328166 100644 --- a/impl_core/src/test/java/io/opencensus/implcore/stats/RecordUtilsTest.java +++ b/impl_core/src/test/java/io/opencensus/implcore/stats/RecordUtilsTest.java
@@ -62,10 +62,22 @@ private static final TagKey METHOD = TagKey.create("method"); private static final TagValue CALLER_V = TagValue.create("some caller"); private static final TagValue METHOD_V = TagValue.create("some method"); + private static final TagValue METHOD_V_2 = TagValue.create("some other method"); + private static final TagValue METHOD_V_3 = TagValue.create("the third method"); + private static final TagValue STATUS_V = TagValue.create("ok"); + private static final TagValue STATUS_V_2 = TagValue.create("error"); private static final TagValueWithMetadata CALLER_V_WITH_MD = TagValueWithMetadata.create(CALLER_V, METADATA_UNLIMITED_PROPAGATION); private static final TagValueWithMetadata METHOD_V_WITH_MD = TagValueWithMetadata.create(METHOD_V, METADATA_UNLIMITED_PROPAGATION); + private static final TagValueWithMetadata METHOD_V_2_WITH_MD = + TagValueWithMetadata.create(METHOD_V_2, METADATA_UNLIMITED_PROPAGATION); + private static final TagValueWithMetadata METHOD_V_3_WITH_MD = + TagValueWithMetadata.create(METHOD_V_3, METADATA_UNLIMITED_PROPAGATION); + private static final TagValueWithMetadata STATUS_V_WITH_MD = + TagValueWithMetadata.create(STATUS_V, METADATA_UNLIMITED_PROPAGATION); + private static final TagValueWithMetadata STATUS_V_2_WITH_MD = + TagValueWithMetadata.create(STATUS_V_2, METADATA_UNLIMITED_PROPAGATION); @Test public void testConstants() { @@ -84,6 +96,75 @@ } @Test + public void testGetTagValues_MapDeprecatedRpcTag() { + List<TagKey> columns = Arrays.asList(RecordUtils.RPC_STATUS, RecordUtils.RPC_METHOD); + Map<TagKey, TagValueWithMetadata> tags = + ImmutableMap.of( + RecordUtils.GRPC_CLIENT_METHOD, METHOD_V_WITH_MD, + RecordUtils.GRPC_CLIENT_STATUS, STATUS_V_WITH_MD); + + assertThat(RecordUtils.getTagValues(tags, columns)) + .containsExactly(STATUS_V, METHOD_V) + .inOrder(); + } + + @Test + public void testGetTagValues_MapDeprecatedRpcTag_WithServerTag() { + List<TagKey> columns = Arrays.asList(RecordUtils.RPC_STATUS, RecordUtils.RPC_METHOD); + Map<TagKey, TagValueWithMetadata> tags = + ImmutableMap.of( + RecordUtils.GRPC_SERVER_METHOD, METHOD_V_WITH_MD, + RecordUtils.GRPC_SERVER_STATUS, STATUS_V_WITH_MD); + + assertThat(RecordUtils.getTagValues(tags, columns)) + .containsExactly(STATUS_V, METHOD_V) + .inOrder(); + } + + @Test + public void testGetTagValues_MapDeprecatedRpcTag_PreferClientTag() { + List<TagKey> columns = Arrays.asList(RecordUtils.RPC_STATUS, RecordUtils.RPC_METHOD); + Map<TagKey, TagValueWithMetadata> tags = + ImmutableMap.of( + RecordUtils.GRPC_SERVER_METHOD, METHOD_V_WITH_MD, + RecordUtils.GRPC_SERVER_STATUS, STATUS_V_WITH_MD, + RecordUtils.GRPC_CLIENT_METHOD, METHOD_V_2_WITH_MD, + RecordUtils.GRPC_CLIENT_STATUS, STATUS_V_2_WITH_MD); + + // When both client and server new tags are present, client values take precedence. + assertThat(RecordUtils.getTagValues(tags, columns)) + .containsExactly(STATUS_V_2, METHOD_V_2) + .inOrder(); + } + + @Test + public void testGetTagValues_WithOldMethodTag() { + List<TagKey> columns = Arrays.asList(RecordUtils.RPC_METHOD); + Map<TagKey, TagValueWithMetadata> tags = + ImmutableMap.of( + RecordUtils.GRPC_SERVER_METHOD, METHOD_V_WITH_MD, + RecordUtils.GRPC_CLIENT_METHOD, METHOD_V_2_WITH_MD, + RecordUtils.RPC_METHOD, METHOD_V_3_WITH_MD); + + // When the old "method" tag is set, it always takes precedence. + assertThat(RecordUtils.getTagValues(tags, columns)).containsExactly(METHOD_V_3).inOrder(); + } + + @Test + public void testGetTagValues_WithNewTags() { + List<TagKey> columns = + Arrays.asList(RecordUtils.GRPC_CLIENT_METHOD, RecordUtils.GRPC_SERVER_METHOD); + Map<TagKey, TagValueWithMetadata> tags = + ImmutableMap.of( + RecordUtils.GRPC_SERVER_METHOD, METHOD_V_WITH_MD, + RecordUtils.GRPC_CLIENT_METHOD, METHOD_V_2_WITH_MD); + + assertThat(RecordUtils.getTagValues(tags, columns)) + .containsExactly(METHOD_V_2, METHOD_V) + .inOrder(); + } + + @Test public void createMutableAggregation() { BucketBoundaries bucketBoundaries = BucketBoundaries.create(Arrays.asList(-1.0, 0.0, 1.0));
diff --git a/impl_core/src/test/java/io/opencensus/implcore/stats/StatsRecorderImplTest.java b/impl_core/src/test/java/io/opencensus/implcore/stats/StatsRecorderImplTest.java index c87140c..1f1e470 100644 --- a/impl_core/src/test/java/io/opencensus/implcore/stats/StatsRecorderImplTest.java +++ b/impl_core/src/test/java/io/opencensus/implcore/stats/StatsRecorderImplTest.java
@@ -296,6 +296,30 @@ } @Test + public void record_MapDeprecatedRpcConstants() { + View view = + View.create( + VIEW_NAME, + "description", + MEASURE_DOUBLE, + Sum.create(), + Arrays.asList(RecordUtils.RPC_METHOD)); + + viewManager.registerView(view); + MeasureMap statsRecord = statsRecorder.newMeasureMap().put(MEASURE_DOUBLE, 1.0); + statsRecord.record(new SimpleTagContext(Tag.create(RecordUtils.GRPC_CLIENT_METHOD, VALUE))); + ViewData viewData = viewManager.getView(VIEW_NAME); + + // There should be two entries. + StatsTestUtil.assertAggregationMapEquals( + viewData.getAggregationMap(), + ImmutableMap.of( + Arrays.asList(VALUE), + StatsTestUtil.createAggregationData(Sum.create(), MEASURE_DOUBLE, 1.0)), + 1e-6); + } + + @Test @SuppressWarnings("deprecation") public void record_StatsDisabled() { View view =