Преглед изворни кода

Emit both old and new metrics under dup setting (#9320)

Trask Stalnaker пре 1 година
родитељ
комит
e243da4cad

+ 2 - 2
instrumentation-api-semconv/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpClientExperimentalMetrics.java

@@ -7,7 +7,7 @@ package io.opentelemetry.instrumentation.api.instrumenter.http;
 
 import static io.opentelemetry.instrumentation.api.instrumenter.http.HttpMessageBodySizeUtil.getHttpRequestBodySize;
 import static io.opentelemetry.instrumentation.api.instrumenter.http.HttpMessageBodySizeUtil.getHttpResponseBodySize;
-import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyClientDurationAndSizeView;
+import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyClientRequestSizeView;
 import static java.util.logging.Level.FINE;
 
 import io.opentelemetry.api.common.Attributes;
@@ -81,7 +81,7 @@ public final class HttpClientExperimentalMetrics implements OperationListener {
       return;
     }
 
-    Attributes sizeAttributes = applyClientDurationAndSizeView(startAttributes, endAttributes);
+    Attributes sizeAttributes = applyClientRequestSizeView(startAttributes, endAttributes);
 
     Long requestBodySize = getHttpRequestBodySize(endAttributes, startAttributes);
     if (requestBodySize != null) {

+ 41 - 15
instrumentation-api-semconv/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpClientMetrics.java

@@ -5,9 +5,9 @@
 
 package io.opentelemetry.instrumentation.api.instrumenter.http;
 
-import static io.opentelemetry.instrumentation.api.instrumenter.http.HttpMetricsUtil.createDurationHistogram;
-import static io.opentelemetry.instrumentation.api.instrumenter.http.HttpMetricsUtil.nanosToUnit;
-import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyClientDurationAndSizeView;
+import static io.opentelemetry.instrumentation.api.instrumenter.http.HttpMetricsUtil.createStableDurationHistogram;
+import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyOldClientDurationView;
+import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyStableClientDurationView;
 import static java.util.logging.Level.FINE;
 
 import com.google.auto.value.AutoValue;
@@ -18,7 +18,10 @@ import io.opentelemetry.context.Context;
 import io.opentelemetry.context.ContextKey;
 import io.opentelemetry.instrumentation.api.instrumenter.OperationListener;
 import io.opentelemetry.instrumentation.api.instrumenter.OperationMetrics;
+import io.opentelemetry.instrumentation.api.internal.SemconvStability;
+import java.util.concurrent.TimeUnit;
 import java.util.logging.Logger;
+import javax.annotation.Nullable;
 
 /**
  * {@link OperationListener} which keeps track of <a
@@ -27,6 +30,9 @@ import java.util.logging.Logger;
  */
 public final class HttpClientMetrics implements OperationListener {
 
+  private static final double NANOS_PER_MS = TimeUnit.MILLISECONDS.toNanos(1);
+  private static final double NANOS_PER_S = TimeUnit.SECONDS.toNanos(1);
+
   private static final ContextKey<State> HTTP_CLIENT_REQUEST_METRICS_STATE =
       ContextKey.named("http-client-metrics-state");
 
@@ -41,16 +47,27 @@ public final class HttpClientMetrics implements OperationListener {
     return HttpClientMetrics::new;
   }
 
-  private final DoubleHistogram duration;
+  @Nullable private final DoubleHistogram stableDuration;
+  @Nullable private final DoubleHistogram oldDuration;
 
   private HttpClientMetrics(Meter meter) {
-    String durationInstrumentName =
-        HttpMetricsUtil.emitNewSemconvMetrics
-            ? "http.client.request.duration"
-            : "http.client.duration";
-    duration =
-        createDurationHistogram(
-            meter, durationInstrumentName, "The duration of the outbound HTTP request");
+    if (SemconvStability.emitStableHttpSemconv()) {
+      stableDuration =
+          createStableDurationHistogram(
+              meter, "http.client.request.duration", "The duration of the outbound HTTP request");
+    } else {
+      stableDuration = null;
+    }
+    if (SemconvStability.emitOldHttpSemconv()) {
+      oldDuration =
+          meter
+              .histogramBuilder("http.client.duration")
+              .setUnit("ms")
+              .setDescription("The duration of the outbound HTTP request")
+              .build();
+    } else {
+      oldDuration = null;
+    }
   }
 
   @Override
@@ -71,10 +88,19 @@ public final class HttpClientMetrics implements OperationListener {
       return;
     }
 
-    Attributes durationAndSizeAttributes =
-        applyClientDurationAndSizeView(state.startAttributes(), endAttributes);
-    duration.record(
-        nanosToUnit(endNanos - state.startTimeNanos()), durationAndSizeAttributes, context);
+    if (stableDuration != null) {
+      Attributes stableDurationAttributes =
+          applyStableClientDurationView(state.startAttributes(), endAttributes);
+      stableDuration.record(
+          (endNanos - state.startTimeNanos()) / NANOS_PER_S, stableDurationAttributes, context);
+    }
+
+    if (oldDuration != null) {
+      Attributes stableDurationAttributes =
+          applyOldClientDurationView(state.startAttributes(), endAttributes);
+      oldDuration.record(
+          (endNanos - state.startTimeNanos()) / NANOS_PER_MS, stableDurationAttributes, context);
+    }
   }
 
   @AutoValue

+ 4 - 19
instrumentation-api-semconv/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpMetricsUtil.java

@@ -12,42 +12,27 @@ import io.opentelemetry.api.metrics.DoubleHistogram;
 import io.opentelemetry.api.metrics.DoubleHistogramBuilder;
 import io.opentelemetry.api.metrics.Meter;
 import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleHistogramBuilder;
-import io.opentelemetry.instrumentation.api.internal.SemconvStability;
 import java.util.List;
-import java.util.concurrent.TimeUnit;
 
 final class HttpMetricsUtil {
 
-  // we'll use the old unit if the old semconv is in use
-  static final boolean emitNewSemconvMetrics =
-      SemconvStability.emitStableHttpSemconv() && !SemconvStability.emitOldHttpSemconv();
-
   static final List<Double> DURATION_SECONDS_BUCKETS =
       unmodifiableList(
           asList(
               0.0, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1.0, 2.5, 5.0, 7.5,
               10.0));
 
-  private static final double NANOS_PER_MS = TimeUnit.MILLISECONDS.toNanos(1);
-  private static final double NANOS_PER_S = TimeUnit.SECONDS.toNanos(1);
-
-  static DoubleHistogram createDurationHistogram(Meter meter, String name, String description) {
+  static DoubleHistogram createStableDurationHistogram(
+      Meter meter, String name, String description) {
     DoubleHistogramBuilder durationBuilder =
-        meter
-            .histogramBuilder(name)
-            .setUnit(emitNewSemconvMetrics ? "s" : "ms")
-            .setDescription(description);
+        meter.histogramBuilder(name).setUnit("s").setDescription(description);
     // don't set custom buckets if milliseconds are still used
-    if (emitNewSemconvMetrics && durationBuilder instanceof ExtendedDoubleHistogramBuilder) {
+    if (durationBuilder instanceof ExtendedDoubleHistogramBuilder) {
       ((ExtendedDoubleHistogramBuilder) durationBuilder)
           .setAdvice(advice -> advice.setExplicitBucketBoundaries(DURATION_SECONDS_BUCKETS));
     }
     return durationBuilder.build();
   }
 
-  static double nanosToUnit(long durationNanos) {
-    return durationNanos / (emitNewSemconvMetrics ? NANOS_PER_S : NANOS_PER_MS);
-  }
-
   private HttpMetricsUtil() {}
 }

+ 2 - 2
instrumentation-api-semconv/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpServerExperimentalMetrics.java

@@ -8,7 +8,7 @@ package io.opentelemetry.instrumentation.api.instrumenter.http;
 import static io.opentelemetry.instrumentation.api.instrumenter.http.HttpMessageBodySizeUtil.getHttpRequestBodySize;
 import static io.opentelemetry.instrumentation.api.instrumenter.http.HttpMessageBodySizeUtil.getHttpResponseBodySize;
 import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyActiveRequestsView;
-import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyServerDurationAndSizeView;
+import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyServerRequestSizeView;
 import static java.util.logging.Level.FINE;
 
 import io.opentelemetry.api.common.Attributes;
@@ -97,7 +97,7 @@ public final class HttpServerExperimentalMetrics implements OperationListener {
     // request count (otherwise it will split the timeseries)
     activeRequests.add(-1, applyActiveRequestsView(startAttributes), context);
 
-    Attributes sizeAttributes = applyServerDurationAndSizeView(startAttributes, endAttributes);
+    Attributes sizeAttributes = applyServerRequestSizeView(startAttributes, endAttributes);
 
     Long requestBodySize = getHttpRequestBodySize(endAttributes, startAttributes);
     if (requestBodySize != null) {

+ 42 - 15
instrumentation-api-semconv/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpServerMetrics.java

@@ -5,9 +5,9 @@
 
 package io.opentelemetry.instrumentation.api.instrumenter.http;
 
-import static io.opentelemetry.instrumentation.api.instrumenter.http.HttpMetricsUtil.createDurationHistogram;
-import static io.opentelemetry.instrumentation.api.instrumenter.http.HttpMetricsUtil.nanosToUnit;
-import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyServerDurationAndSizeView;
+import static io.opentelemetry.instrumentation.api.instrumenter.http.HttpMetricsUtil.createStableDurationHistogram;
+import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyOldServerDurationView;
+import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyStableServerDurationView;
 import static java.util.logging.Level.FINE;
 
 import com.google.auto.value.AutoValue;
@@ -18,7 +18,10 @@ import io.opentelemetry.context.Context;
 import io.opentelemetry.context.ContextKey;
 import io.opentelemetry.instrumentation.api.instrumenter.OperationListener;
 import io.opentelemetry.instrumentation.api.instrumenter.OperationMetrics;
+import io.opentelemetry.instrumentation.api.internal.SemconvStability;
+import java.util.concurrent.TimeUnit;
 import java.util.logging.Logger;
+import javax.annotation.Nullable;
 
 /**
  * {@link OperationListener} which keeps track of <a
@@ -27,6 +30,9 @@ import java.util.logging.Logger;
  */
 public final class HttpServerMetrics implements OperationListener {
 
+  private static final double NANOS_PER_MS = TimeUnit.MILLISECONDS.toNanos(1);
+  private static final double NANOS_PER_S = TimeUnit.SECONDS.toNanos(1);
+
   private static final ContextKey<State> HTTP_SERVER_METRICS_STATE =
       ContextKey.named("http-server-metrics-state");
 
@@ -41,16 +47,27 @@ public final class HttpServerMetrics implements OperationListener {
     return HttpServerMetrics::new;
   }
 
-  private final DoubleHistogram duration;
+  @Nullable private final DoubleHistogram stableDuration;
+  @Nullable private final DoubleHistogram oldDuration;
 
   private HttpServerMetrics(Meter meter) {
-    String durationInstrumentName =
-        HttpMetricsUtil.emitNewSemconvMetrics
-            ? "http.server.request.duration"
-            : "http.server.duration";
-    duration =
-        createDurationHistogram(
-            meter, durationInstrumentName, "The duration of the inbound HTTP request");
+    if (SemconvStability.emitStableHttpSemconv()) {
+      stableDuration =
+          createStableDurationHistogram(
+              meter, "http.server.request.duration", "The duration of the inbound HTTP request");
+    } else {
+      stableDuration = null;
+    }
+    if (SemconvStability.emitOldHttpSemconv()) {
+      oldDuration =
+          meter
+              .histogramBuilder("http.server.duration")
+              .setUnit("ms")
+              .setDescription("The duration of the inbound HTTP request")
+              .build();
+    } else {
+      oldDuration = null;
+    }
   }
 
   @Override
@@ -70,10 +87,20 @@ public final class HttpServerMetrics implements OperationListener {
           context);
       return;
     }
-    Attributes durationAndSizeAttributes =
-        applyServerDurationAndSizeView(state.startAttributes(), endAttributes);
-    duration.record(
-        nanosToUnit(endNanos - state.startTimeNanos()), durationAndSizeAttributes, context);
+
+    if (stableDuration != null) {
+      Attributes stableDurationAttributes =
+          applyStableServerDurationView(state.startAttributes(), endAttributes);
+      stableDuration.record(
+          (endNanos - state.startTimeNanos()) / NANOS_PER_S, stableDurationAttributes, context);
+    }
+
+    if (oldDuration != null) {
+      Attributes stableDurationAttributes =
+          applyOldServerDurationView(state.startAttributes(), endAttributes);
+      oldDuration.record(
+          (endNanos - state.startTimeNanos()) / NANOS_PER_MS, stableDurationAttributes, context);
+    }
   }
 
   @AutoValue

+ 82 - 39
instrumentation-api-semconv/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/TemporaryMetricsView.java

@@ -21,85 +21,128 @@ import java.util.function.BiConsumer;
 @SuppressWarnings("rawtypes")
 final class TemporaryMetricsView {
 
-  private static final Set<AttributeKey> durationAlwaysInclude = buildDurationAlwaysInclude();
-  private static final Set<AttributeKey> durationClientView = buildDurationClientView();
-  private static final Set<AttributeKey> durationServerView = buildDurationServerView();
+  private static final Set<AttributeKey> stableDurationClientView = buildStableDurationClientView();
+  private static final Set<AttributeKey> stableDurationServerView = buildStableDurationServerView();
+
+  private static final Set<AttributeKey> oldDurationClientView = buildOldDurationClientView();
+  private static final Set<AttributeKey> oldDurationServerView = buildOldDurationServerView();
+
   private static final Set<AttributeKey> activeRequestsView = buildActiveRequestsView();
 
-  private static Set<AttributeKey> buildDurationAlwaysInclude() {
-    // the list of included metrics is from
-    // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#attributes
+  private static Set<AttributeKey> buildStableDurationClientView() {
+    // https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-metrics.md#metric-httpclientrequestduration
     Set<AttributeKey> view = new HashSet<>();
-    view.add(SemanticAttributes.HTTP_METHOD);
-    view.add(SemanticAttributes.HTTP_STATUS_CODE); // Optional
-    view.add(SemanticAttributes.NET_PROTOCOL_NAME); // Optional
-    view.add(SemanticAttributes.NET_PROTOCOL_VERSION); // Optional
-    // stable semconv
     view.add(HttpAttributes.HTTP_REQUEST_METHOD);
     view.add(HttpAttributes.HTTP_RESPONSE_STATUS_CODE);
     view.add(NetworkAttributes.NETWORK_PROTOCOL_NAME);
     view.add(NetworkAttributes.NETWORK_PROTOCOL_VERSION);
+    view.add(NetworkAttributes.SERVER_ADDRESS);
+    view.add(NetworkAttributes.SERVER_PORT);
+    view.add(NetworkAttributes.SERVER_SOCKET_ADDRESS);
     return view;
   }
 
-  private static Set<AttributeKey> buildDurationClientView() {
-    // We pull identifying attributes according to:
-    // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#attribute-alternatives
-    // We only pull net.peer.name and net.peer.port because http.url has too high cardinality
-    Set<AttributeKey> view = new HashSet<>(durationAlwaysInclude);
+  private static Set<AttributeKey> buildOldDurationClientView() {
+    // https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/metrics/semantic_conventions/http-metrics.md#metric-httpclientduration
+    Set<AttributeKey> view = new HashSet<>();
+    view.add(SemanticAttributes.HTTP_METHOD);
+    view.add(SemanticAttributes.HTTP_STATUS_CODE);
     view.add(SemanticAttributes.NET_PEER_NAME);
     view.add(SemanticAttributes.NET_PEER_PORT);
+    view.add(SemanticAttributes.NET_PROTOCOL_NAME);
+    view.add(SemanticAttributes.NET_PROTOCOL_VERSION);
     view.add(SemanticAttributes.NET_SOCK_PEER_ADDR);
-    // stable semconv
-    view.add(NetworkAttributes.SERVER_SOCKET_ADDRESS);
-    view.add(NetworkAttributes.SERVER_ADDRESS);
-    view.add(NetworkAttributes.SERVER_PORT);
     return view;
   }
 
-  private static Set<AttributeKey> buildDurationServerView() {
-    // We pull identifying attributes according to:
-    // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#attribute-alternatives
-    // With the following caveat:
-    // - we always rely on http.route + http.host in this repository.
-    // - we prefer http.route (which is scrubbed) over http.target (which is not scrubbed).
-    Set<AttributeKey> view = new HashSet<>(durationAlwaysInclude);
+  private static Set<AttributeKey> buildStableDurationServerView() {
+    // https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-metrics.md#metric-httpserverrequestduration
+    Set<AttributeKey> view = new HashSet<>();
+    view.add(SemanticAttributes.HTTP_ROUTE);
+    view.add(HttpAttributes.HTTP_REQUEST_METHOD);
+    view.add(HttpAttributes.HTTP_RESPONSE_STATUS_CODE);
+    view.add(NetworkAttributes.NETWORK_PROTOCOL_NAME);
+    view.add(NetworkAttributes.NETWORK_PROTOCOL_VERSION);
+    view.add(UrlAttributes.URL_SCHEME);
+    return view;
+  }
+
+  private static Set<AttributeKey> buildOldDurationServerView() {
+    // https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/metrics/semantic_conventions/http-metrics.md#metric-httpserverduration
+    Set<AttributeKey> view = new HashSet<>();
     view.add(SemanticAttributes.HTTP_SCHEME);
+    view.add(SemanticAttributes.HTTP_ROUTE);
+    view.add(SemanticAttributes.HTTP_METHOD);
+    view.add(SemanticAttributes.HTTP_STATUS_CODE);
     view.add(SemanticAttributes.NET_HOST_NAME);
     view.add(SemanticAttributes.NET_HOST_PORT);
-    view.add(SemanticAttributes.HTTP_ROUTE);
-    // stable semconv
-    view.add(UrlAttributes.URL_SCHEME);
+    view.add(SemanticAttributes.NET_PROTOCOL_NAME);
+    view.add(SemanticAttributes.NET_PROTOCOL_VERSION);
     return view;
   }
 
   private static Set<AttributeKey> buildActiveRequestsView() {
-    // the list of included metrics is from
-    // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#attributes
     Set<AttributeKey> view = new HashSet<>();
+    // https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/metrics/semantic_conventions/http-metrics.md#metric-httpserveractive_requests
     view.add(SemanticAttributes.HTTP_METHOD);
     view.add(SemanticAttributes.HTTP_SCHEME);
     view.add(SemanticAttributes.NET_HOST_NAME);
     view.add(SemanticAttributes.NET_HOST_PORT);
-    // stable semconv
+    // https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-metrics.md#metric-httpserveractive_requests
     view.add(HttpAttributes.HTTP_REQUEST_METHOD);
     view.add(UrlAttributes.URL_SCHEME);
     return view;
   }
 
-  static Attributes applyClientDurationAndSizeView(
+  static Attributes applyStableClientDurationView(
+      Attributes startAttributes, Attributes endAttributes) {
+    AttributesBuilder filtered = Attributes.builder();
+    applyView(filtered, startAttributes, stableDurationClientView);
+    applyView(filtered, endAttributes, stableDurationClientView);
+    return filtered.build();
+  }
+
+  static Attributes applyOldClientDurationView(
+      Attributes startAttributes, Attributes endAttributes) {
+    AttributesBuilder filtered = Attributes.builder();
+    applyView(filtered, startAttributes, oldDurationClientView);
+    applyView(filtered, endAttributes, oldDurationClientView);
+    return filtered.build();
+  }
+
+  static Attributes applyStableServerDurationView(
+      Attributes startAttributes, Attributes endAttributes) {
+    AttributesBuilder filtered = Attributes.builder();
+    applyView(filtered, startAttributes, stableDurationServerView);
+    applyView(filtered, endAttributes, stableDurationServerView);
+    return filtered.build();
+  }
+
+  static Attributes applyOldServerDurationView(
+      Attributes startAttributes, Attributes endAttributes) {
+    AttributesBuilder filtered = Attributes.builder();
+    applyView(filtered, startAttributes, oldDurationServerView);
+    applyView(filtered, endAttributes, oldDurationServerView);
+    return filtered.build();
+  }
+
+  static Attributes applyServerRequestSizeView(
       Attributes startAttributes, Attributes endAttributes) {
     AttributesBuilder filtered = Attributes.builder();
-    applyView(filtered, startAttributes, durationClientView);
-    applyView(filtered, endAttributes, durationClientView);
+    applyView(filtered, startAttributes, stableDurationServerView);
+    applyView(filtered, startAttributes, oldDurationServerView);
+    applyView(filtered, endAttributes, stableDurationServerView);
+    applyView(filtered, endAttributes, oldDurationServerView);
     return filtered.build();
   }
 
-  static Attributes applyServerDurationAndSizeView(
+  static Attributes applyClientRequestSizeView(
       Attributes startAttributes, Attributes endAttributes) {
     AttributesBuilder filtered = Attributes.builder();
-    applyView(filtered, startAttributes, durationServerView);
-    applyView(filtered, endAttributes, durationServerView);
+    applyView(filtered, startAttributes, stableDurationClientView);
+    applyView(filtered, startAttributes, oldDurationClientView);
+    applyView(filtered, endAttributes, stableDurationClientView);
+    applyView(filtered, endAttributes, oldDurationClientView);
     return filtered.build();
   }
 

+ 170 - 10
instrumentation-api-semconv/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/http/TemporaryMetricsViewTest.java

@@ -6,8 +6,12 @@
 package io.opentelemetry.instrumentation.api.instrumenter.http;
 
 import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyActiveRequestsView;
-import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyClientDurationAndSizeView;
-import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyServerDurationAndSizeView;
+import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyClientRequestSizeView;
+import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyOldClientDurationView;
+import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyOldServerDurationView;
+import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyServerRequestSizeView;
+import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyStableClientDurationView;
+import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyStableServerDurationView;
 import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
 import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NetTransportValues.IP_TCP;
 import static org.assertj.core.api.Assertions.entry;
@@ -22,7 +26,7 @@ import org.junit.jupiter.api.Test;
 class TemporaryMetricsViewTest {
 
   @Test
-  void shouldApplyClientDurationAndSizeView() {
+  void shouldApplyClientDurationView() {
     Attributes startAttributes =
         Attributes.builder()
             .put(
@@ -47,7 +51,7 @@ class TemporaryMetricsViewTest {
             .put(SemanticAttributes.NET_SOCK_PEER_PORT, 8080)
             .build();
 
-    assertThat(applyClientDurationAndSizeView(startAttributes, endAttributes))
+    assertThat(applyOldClientDurationView(startAttributes, endAttributes))
         .containsOnly(
             entry(SemanticAttributes.HTTP_METHOD, "GET"),
             entry(SemanticAttributes.HTTP_STATUS_CODE, 500L),
@@ -59,7 +63,7 @@ class TemporaryMetricsViewTest {
   }
 
   @Test
-  void shouldApplyClientDurationAndSizeView_stableSemconv() {
+  void shouldApplyClientDurationView_stableSemconv() {
     Attributes startAttributes =
         Attributes.builder()
             .put(
@@ -84,7 +88,7 @@ class TemporaryMetricsViewTest {
             .put(NetworkAttributes.SERVER_SOCKET_PORT, 8080)
             .build();
 
-    assertThat(applyClientDurationAndSizeView(startAttributes, endAttributes))
+    assertThat(applyStableClientDurationView(startAttributes, endAttributes))
         .containsOnly(
             entry(HttpAttributes.HTTP_REQUEST_METHOD, "GET"),
             entry(HttpAttributes.HTTP_RESPONSE_STATUS_CODE, 500L),
@@ -96,7 +100,7 @@ class TemporaryMetricsViewTest {
   }
 
   @Test
-  void shouldApplyServerDurationAndSizeView() {
+  void shouldApplyServerDurationView() {
     Attributes startAttributes =
         Attributes.builder()
             .put(SemanticAttributes.HTTP_METHOD, "GET")
@@ -125,7 +129,7 @@ class TemporaryMetricsViewTest {
             .put(SemanticAttributes.NET_PEER_PORT, 443)
             .build();
 
-    assertThat(applyServerDurationAndSizeView(startAttributes, endAttributes))
+    assertThat(applyOldServerDurationView(startAttributes, endAttributes))
         .containsOnly(
             entry(SemanticAttributes.HTTP_METHOD, "GET"),
             entry(SemanticAttributes.HTTP_STATUS_CODE, 500L),
@@ -138,7 +142,7 @@ class TemporaryMetricsViewTest {
   }
 
   @Test
-  void shouldApplyServerDurationAndSizeView_stableSemconv() {
+  void shouldApplyServerDurationView_stableSemconv() {
     Attributes startAttributes =
         Attributes.builder()
             .put(HttpAttributes.HTTP_REQUEST_METHOD, "GET")
@@ -167,7 +171,163 @@ class TemporaryMetricsViewTest {
             .put(NetworkAttributes.CLIENT_SOCKET_PORT, 8080)
             .build();
 
-    assertThat(applyServerDurationAndSizeView(startAttributes, endAttributes))
+    assertThat(applyStableServerDurationView(startAttributes, endAttributes))
+        .containsOnly(
+            entry(HttpAttributes.HTTP_REQUEST_METHOD, "GET"),
+            entry(HttpAttributes.HTTP_RESPONSE_STATUS_CODE, 500L),
+            entry(SemanticAttributes.HTTP_ROUTE, "/somehost/high/{name}/{id}"),
+            entry(UrlAttributes.URL_SCHEME, "https"),
+            entry(NetworkAttributes.NETWORK_PROTOCOL_NAME, "http"),
+            entry(NetworkAttributes.NETWORK_PROTOCOL_VERSION, "1.1"));
+  }
+
+  @Test
+  void shouldApplyClientSizeView() {
+    Attributes startAttributes =
+        Attributes.builder()
+            .put(
+                SemanticAttributes.HTTP_URL,
+                "https://somehost/high/cardinality/12345?jsessionId=121454")
+            .put(SemanticAttributes.HTTP_METHOD, "GET")
+            .put(SemanticAttributes.HTTP_SCHEME, "https")
+            .put(SemanticAttributes.HTTP_TARGET, "/high/cardinality/12345?jsessionId=121454")
+            .build();
+
+    Attributes endAttributes =
+        Attributes.builder()
+            .put(SemanticAttributes.HTTP_STATUS_CODE, 500)
+            .put(SemanticAttributes.NET_TRANSPORT, IP_TCP)
+            .put(SemanticAttributes.NET_PROTOCOL_NAME, "http")
+            .put(SemanticAttributes.NET_PROTOCOL_VERSION, "1.1")
+            .put(SemanticAttributes.NET_PEER_NAME, "somehost2")
+            .put(SemanticAttributes.NET_PEER_PORT, 443)
+            .put(SemanticAttributes.NET_SOCK_FAMILY, "inet")
+            .put(SemanticAttributes.NET_SOCK_PEER_ADDR, "1.2.3.4")
+            .put(SemanticAttributes.NET_SOCK_PEER_NAME, "somehost20")
+            .put(SemanticAttributes.NET_SOCK_PEER_PORT, 8080)
+            .build();
+
+    assertThat(applyClientRequestSizeView(startAttributes, endAttributes))
+        .containsOnly(
+            entry(SemanticAttributes.HTTP_METHOD, "GET"),
+            entry(SemanticAttributes.HTTP_STATUS_CODE, 500L),
+            entry(SemanticAttributes.NET_PROTOCOL_NAME, "http"),
+            entry(SemanticAttributes.NET_PROTOCOL_VERSION, "1.1"),
+            entry(SemanticAttributes.NET_PEER_NAME, "somehost2"),
+            entry(SemanticAttributes.NET_PEER_PORT, 443L),
+            entry(SemanticAttributes.NET_SOCK_PEER_ADDR, "1.2.3.4"));
+  }
+
+  @Test
+  void shouldApplyClientSizeView_stableSemconv() {
+    Attributes startAttributes =
+        Attributes.builder()
+            .put(
+                UrlAttributes.URL_FULL, "https://somehost/high/cardinality/12345?jsessionId=121454")
+            .put(HttpAttributes.HTTP_REQUEST_METHOD, "GET")
+            .put(UrlAttributes.URL_SCHEME, "https")
+            .put(UrlAttributes.URL_PATH, "/high/cardinality/12345")
+            .put(UrlAttributes.URL_QUERY, "jsessionId=121454")
+            .put(NetworkAttributes.SERVER_ADDRESS, "somehost2")
+            .put(NetworkAttributes.SERVER_PORT, 443)
+            .build();
+
+    Attributes endAttributes =
+        Attributes.builder()
+            .put(HttpAttributes.HTTP_RESPONSE_STATUS_CODE, 500)
+            .put(NetworkAttributes.NETWORK_TRANSPORT, "tcp")
+            .put(NetworkAttributes.NETWORK_TYPE, "ipv4")
+            .put(NetworkAttributes.NETWORK_PROTOCOL_NAME, "http")
+            .put(NetworkAttributes.NETWORK_PROTOCOL_VERSION, "1.1")
+            .put(NetworkAttributes.SERVER_SOCKET_ADDRESS, "1.2.3.4")
+            .put(NetworkAttributes.SERVER_SOCKET_DOMAIN, "somehost20")
+            .put(NetworkAttributes.SERVER_SOCKET_PORT, 8080)
+            .build();
+
+    assertThat(applyClientRequestSizeView(startAttributes, endAttributes))
+        .containsOnly(
+            entry(HttpAttributes.HTTP_REQUEST_METHOD, "GET"),
+            entry(HttpAttributes.HTTP_RESPONSE_STATUS_CODE, 500L),
+            entry(NetworkAttributes.NETWORK_PROTOCOL_NAME, "http"),
+            entry(NetworkAttributes.NETWORK_PROTOCOL_VERSION, "1.1"),
+            entry(NetworkAttributes.SERVER_ADDRESS, "somehost2"),
+            entry(NetworkAttributes.SERVER_PORT, 443L),
+            entry(NetworkAttributes.SERVER_SOCKET_ADDRESS, "1.2.3.4"));
+  }
+
+  @Test
+  void shouldApplyServerSizeView() {
+    Attributes startAttributes =
+        Attributes.builder()
+            .put(SemanticAttributes.HTTP_METHOD, "GET")
+            .put(
+                SemanticAttributes.HTTP_URL,
+                "https://somehost/high/cardinality/12345?jsessionId=121454")
+            .put(SemanticAttributes.HTTP_TARGET, "/high/cardinality/12345?jsessionId=121454")
+            .put(SemanticAttributes.HTTP_SCHEME, "https")
+            .put(SemanticAttributes.NET_TRANSPORT, IP_TCP)
+            .put(SemanticAttributes.NET_PROTOCOL_NAME, "http")
+            .put(SemanticAttributes.NET_PROTOCOL_VERSION, "1.1")
+            .put(SemanticAttributes.NET_HOST_NAME, "somehost")
+            .put(SemanticAttributes.NET_HOST_PORT, 443)
+            .put(SemanticAttributes.NET_SOCK_FAMILY, "inet")
+            .put(SemanticAttributes.NET_SOCK_PEER_ADDR, "1.2.3.4")
+            .put(SemanticAttributes.NET_SOCK_PEER_PORT, 8080)
+            .put(SemanticAttributes.NET_SOCK_HOST_ADDR, "4.3.2.1")
+            .put(SemanticAttributes.NET_SOCK_HOST_PORT, 9090)
+            .build();
+
+    Attributes endAttributes =
+        Attributes.builder()
+            .put(SemanticAttributes.HTTP_ROUTE, "/somehost/high/{name}/{id}")
+            .put(SemanticAttributes.HTTP_STATUS_CODE, 500)
+            .put(SemanticAttributes.NET_PEER_NAME, "somehost2")
+            .put(SemanticAttributes.NET_PEER_PORT, 443)
+            .build();
+
+    assertThat(applyServerRequestSizeView(startAttributes, endAttributes))
+        .containsOnly(
+            entry(SemanticAttributes.HTTP_METHOD, "GET"),
+            entry(SemanticAttributes.HTTP_STATUS_CODE, 500L),
+            entry(SemanticAttributes.HTTP_SCHEME, "https"),
+            entry(SemanticAttributes.NET_PROTOCOL_NAME, "http"),
+            entry(SemanticAttributes.NET_PROTOCOL_VERSION, "1.1"),
+            entry(SemanticAttributes.NET_HOST_NAME, "somehost"),
+            entry(SemanticAttributes.NET_HOST_PORT, 443L),
+            entry(SemanticAttributes.HTTP_ROUTE, "/somehost/high/{name}/{id}"));
+  }
+
+  @Test
+  void shouldApplyServerSizeView_stableSemconv() {
+    Attributes startAttributes =
+        Attributes.builder()
+            .put(HttpAttributes.HTTP_REQUEST_METHOD, "GET")
+            .put(
+                UrlAttributes.URL_FULL, "https://somehost/high/cardinality/12345?jsessionId=121454")
+            .put(UrlAttributes.URL_SCHEME, "https")
+            .put(UrlAttributes.URL_PATH, "/high/cardinality/12345")
+            .put(UrlAttributes.URL_QUERY, "jsessionId=121454")
+            .put(NetworkAttributes.SERVER_ADDRESS, "somehost")
+            .put(NetworkAttributes.SERVER_PORT, 443)
+            .put(NetworkAttributes.CLIENT_ADDRESS, "somehost2")
+            .put(NetworkAttributes.CLIENT_PORT, 443)
+            .build();
+
+    Attributes endAttributes =
+        Attributes.builder()
+            .put(SemanticAttributes.HTTP_ROUTE, "/somehost/high/{name}/{id}")
+            .put(HttpAttributes.HTTP_RESPONSE_STATUS_CODE, 500)
+            .put(NetworkAttributes.NETWORK_TRANSPORT, "tcp")
+            .put(NetworkAttributes.NETWORK_TYPE, "ipv4")
+            .put(NetworkAttributes.NETWORK_PROTOCOL_NAME, "http")
+            .put(NetworkAttributes.NETWORK_PROTOCOL_VERSION, "1.1")
+            .put(NetworkAttributes.SERVER_SOCKET_ADDRESS, "4.3.2.1")
+            .put(NetworkAttributes.SERVER_SOCKET_PORT, 9090)
+            .put(NetworkAttributes.CLIENT_SOCKET_ADDRESS, "1.2.3.4")
+            .put(NetworkAttributes.CLIENT_SOCKET_PORT, 8080)
+            .build();
+
+    assertThat(applyServerRequestSizeView(startAttributes, endAttributes))
         .containsOnly(
             entry(HttpAttributes.HTTP_REQUEST_METHOD, "GET"),
             entry(HttpAttributes.HTTP_RESPONSE_STATUS_CODE, 500L),