Browse Source

Refactor AttributesExtractor so that it extracts route from Context (#5288)

* Refactor AttributesExtractor so that it extracts route from Context

* typo

* fix tests

* Update instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpRouteHolder.java

Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>

* fix all AttributesExtractors

Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
Mateusz Rzeszutek 3 years ago
parent
commit
551418c283
72 changed files with 458 additions and 209 deletions
  1. 3 1
      instrumentation-api-annotation-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/MethodSpanAttributesExtractor.java
  2. 16 7
      instrumentation-api-annotation-support/src/test/groovy/io/opentelemetry/instrumentation/api/annotation/support/MethodSpanAttributesExtractorTest.groovy
  3. 43 8
      instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/AttributesExtractor.java
  4. 3 1
      instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/ConstantAttributesExtractor.java
  5. 2 2
      instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/Instrumenter.java
  6. 3 1
      instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/PeerServiceAttributesExtractor.java
  7. 3 1
      instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/code/CodeAttributesExtractor.java
  8. 4 1
      instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/db/DbAttributesExtractor.java
  9. 3 2
      instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/db/SqlAttributesExtractor.java
  10. 5 3
      instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpClientAttributesExtractor.java
  11. 3 1
      instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpCommonAttributesExtractor.java
  12. 13 14
      instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpRouteHolder.java
  13. 16 6
      instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpServerAttributesExtractor.java
  14. 1 20
      instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpServerMetrics.java
  15. 3 1
      instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/messaging/MessagingAttributesExtractor.java
  16. 3 1
      instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/net/NetClientAttributesExtractor.java
  17. 3 1
      instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/net/NetServerAttributesExtractor.java
  18. 3 1
      instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/rpc/RpcAttributesExtractor.java
  19. 9 4
      instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/AttributesExtractorTest.java
  20. 6 2
      instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterTest.java
  21. 21 10
      instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/PeerServiceAttributesExtractorTest.java
  22. 6 3
      instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/code/CodeAttributesExtractorTest.java
  23. 6 3
      instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/db/DbAttributesExtractorTest.java
  24. 9 4
      instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/db/SqlAttributesExtractorTest.java
  25. 5 4
      instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpClientAttributesExtractorTest.java
  26. 12 7
      instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpServerAttributesExtractorTest.java
  27. 3 3
      instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpServerMetricsTest.java
  28. 9 4
      instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/messaging/MessagingAttributesExtractorTest.java
  29. 10 5
      instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/net/InetSocketAddressNetClientAttributesGetterTest.java
  30. 10 5
      instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/net/InetSocketAddressNetServerAttributesGetterTest.java
  31. 13 6
      instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/net/NetClientAttributesExtractorTest.java
  32. 13 6
      instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/net/NetServerAttributesExtractorTest.java
  33. 5 2
      instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/rpc/RpcAttributesExtractorTest.java
  34. 4 1
      instrumentation/apache-camel-2.20/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachecamel/CamelSingletons.java
  35. 4 1
      instrumentation/async-http-client/async-http-client-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/asynchttpclient/v2_0/AsyncHttpClientAdditionalAttributesExtractor.java
  36. 4 1
      instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/internal/ApiGatewayProxyAttributesExtractor.java
  37. 11 7
      instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/internal/AwsLambdaFunctionAttributesExtractor.java
  38. 3 1
      instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/internal/SqsEventAttributesExtractor.java
  39. 3 1
      instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/internal/SqsMessageAttributesExtractor.java
  40. 3 1
      instrumentation/aws-sdk/aws-sdk-1.11/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/AwsSdkExperimentalAttributesExtractor.java
  41. 6 1
      instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AwsSdkExperimentalAttributesExtractor.java
  42. 4 1
      instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraAttributesExtractor.java
  43. 6 2
      instrumentation/elasticsearch/elasticsearch-transport-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_0/Elasticsearch5TransportExperimentalAttributesExtractor.java
  44. 6 2
      instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_3/Elasticsearch53TransportExperimentalAttributesExtractor.java
  45. 6 2
      instrumentation/elasticsearch/elasticsearch-transport-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v6_0/Elasticsearch6TransportExperimentalAttributesExtractor.java
  46. 7 2
      instrumentation/elasticsearch/elasticsearch-transport-common/library/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/ElasticsearchTransportExperimentalAttributesExtractor.java
  47. 4 1
      instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/GrpcAttributesExtractor.java
  48. 4 1
      instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/HibernateExperimentalAttributesExtractor.java
  49. 4 1
      instrumentation/hystrix-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hystrix/ExperimentalAttributesExtractor.java
  50. 4 1
      instrumentation/jsp-2.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jsp/HttpJspPageInstrumentationSingletons.java
  51. 5 1
      instrumentation/jsp-2.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jsp/JspCompilationContextInstrumentationSingletons.java
  52. 4 1
      instrumentation/kafka/kafka-clients/kafka-clients-common/library/src/main/java/io/opentelemetry/instrumentation/kafka/internal/KafkaConsumerAdditionalAttributesExtractor.java
  53. 4 1
      instrumentation/kafka/kafka-clients/kafka-clients-common/library/src/main/java/io/opentelemetry/instrumentation/kafka/internal/KafkaConsumerExperimentalAttributesExtractor.java
  54. 4 1
      instrumentation/kafka/kafka-clients/kafka-clients-common/library/src/main/java/io/opentelemetry/instrumentation/kafka/internal/KafkaProducerAdditionalAttributesExtractor.java
  55. 3 1
      instrumentation/kubernetes-client-7.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kubernetesclient/KubernetesExperimentalAttributesExtractor.java
  56. 7 2
      instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceConnectAttributesExtractor.java
  57. 7 2
      instrumentation/lettuce/lettuce-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceConnectAttributesExtractor.java
  58. 17 18
      instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/OpenTelemetryTracing.java
  59. 4 1
      instrumentation/mongo/mongo-3.1/library/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoAttributesExtractor.java
  60. 4 1
      instrumentation/rabbitmq-2.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rabbitmq/RabbitDeliveryExperimentalAttributesExtractor.java
  61. 4 1
      instrumentation/rabbitmq-2.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rabbitmq/RabbitDeliveryExtraAttributesExtractor.java
  62. 4 1
      instrumentation/rabbitmq-2.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rabbitmq/RabbitReceiveExperimentalAttributesExtractor.java
  63. 3 1
      instrumentation/rocketmq-client-4.8/library/src/main/java/io/opentelemetry/instrumentation/rocketmq/RockerMqConsumerExperimentalAttributeExtractor.java
  64. 4 1
      instrumentation/rocketmq-client-4.8/library/src/main/java/io/opentelemetry/instrumentation/rocketmq/RockerMqProducerExperimentalAttributeExtractor.java
  65. 5 1
      instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/ServletAdditionalAttributesExtractor.java
  66. 5 1
      instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/ServletRequestParametersExtractor.java
  67. 3 1
      instrumentation/spring/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/server/ExperimentalAttributesExtractor.java
  68. 3 1
      instrumentation/spring/spring-webflux-5.0/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/client/SpringWebfluxExperimentalAttributesExtractor.java
  69. 4 1
      instrumentation/spring/spring-webmvc-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springwebmvc/ModelAndViewAttributesExtractor.java
  70. 4 1
      instrumentation/spring/spring-webmvc-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/webmvc/StatusCodeExtractor.java
  71. 3 1
      instrumentation/tomcat/tomcat-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/tomcat/common/TomcatAdditionalAttributesExtractor.java
  72. 7 2
      instrumentation/twilio-6.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/twilio/TwilioExperimentalAttributesExtractor.java

+ 3 - 1
instrumentation-api-annotation-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/MethodSpanAttributesExtractor.java

@@ -6,6 +6,7 @@
 package io.opentelemetry.instrumentation.api.annotation.support;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.cache.Cache;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import java.lang.reflect.Method;
@@ -45,7 +46,7 @@ public final class MethodSpanAttributesExtractor<REQUEST, RESPONSE>
   }
 
   @Override
-  public void onStart(AttributesBuilder attributes, REQUEST request) {
+  public void onStart(AttributesBuilder attributes, Context parentContext, REQUEST request) {
     Method method = methodExtractor.extract(request);
     AttributeBindings bindings = cache.computeIfAbsent(method, this::bind);
     if (!bindings.isEmpty()) {
@@ -57,6 +58,7 @@ public final class MethodSpanAttributesExtractor<REQUEST, RESPONSE>
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       REQUEST request,
       @Nullable RESPONSE response,
       @Nullable Throwable error) {}

+ 16 - 7
instrumentation-api-annotation-support/src/test/groovy/io/opentelemetry/instrumentation/api/annotation/support/MethodSpanAttributesExtractorTest.groovy

@@ -6,6 +6,7 @@
 package io.opentelemetry.instrumentation.api.annotation.support
 
 import io.opentelemetry.api.common.AttributesBuilder
+import io.opentelemetry.context.Context
 import io.opentelemetry.instrumentation.api.cache.Cache
 import spock.lang.Specification
 
@@ -17,6 +18,7 @@ class MethodSpanAttributesExtractorTest extends Specification {
   def "extracts attributes for method with attribute names"() {
     given:
     def request = new Object()
+    def context = Context.root()
     def method = TestClass.getDeclaredMethod("method", String, String, String)
     AttributesBuilder builder = Mock()
 
@@ -32,7 +34,7 @@ class MethodSpanAttributesExtractorTest extends Specification {
     )
 
     when:
-    extractor.onStart(builder, request)
+    extractor.onStart(builder, context, request)
 
     then:
     1 * builder.put({ it.getKey() == "x" }, "a")
@@ -43,6 +45,7 @@ class MethodSpanAttributesExtractorTest extends Specification {
   def "does not extract attributes for empty attribute name array"() {
     given:
     def request = new Object()
+    def context = Context.root()
     def method = TestClass.getDeclaredMethod("method", String, String, String)
     AttributesBuilder builder = Mock()
 
@@ -58,7 +61,7 @@ class MethodSpanAttributesExtractorTest extends Specification {
     )
 
     when:
-    extractor.onStart(builder, request)
+    extractor.onStart(builder, context, request)
 
     then:
     0 * builder.put(*_)
@@ -67,6 +70,7 @@ class MethodSpanAttributesExtractorTest extends Specification {
   def "does not extract attributes for method with attribute names array with fewer elements than parameters"() {
     given:
     def request = new Object()
+    def context = Context.root()
     def method = TestClass.getDeclaredMethod("method", String, String, String)
     AttributesBuilder builder = Mock()
 
@@ -82,7 +86,7 @@ class MethodSpanAttributesExtractorTest extends Specification {
     )
 
     when:
-    extractor.onStart(builder, request)
+    extractor.onStart(builder, context, request)
 
     then:
     0 * builder.put(*_)
@@ -91,6 +95,7 @@ class MethodSpanAttributesExtractorTest extends Specification {
   def "extracts attributes for method with attribute names array with null element"() {
     given:
     def request = new Object()
+    def context = Context.root()
     def method = TestClass.getDeclaredMethod("method", String, String, String)
     AttributesBuilder builder = Mock()
 
@@ -106,7 +111,7 @@ class MethodSpanAttributesExtractorTest extends Specification {
     )
 
     when:
-    extractor.onStart(builder, request)
+    extractor.onStart(builder, context, request)
 
     then:
     1 * builder.put({ it.getKey() == "x" }, "a")
@@ -117,6 +122,7 @@ class MethodSpanAttributesExtractorTest extends Specification {
   def "does not extracts attribute for method with null argument"() {
     given:
     def request = new Object()
+    def context = Context.root()
     def method = TestClass.getDeclaredMethod("method", String, String, String)
     AttributesBuilder builder = Mock()
 
@@ -132,7 +138,7 @@ class MethodSpanAttributesExtractorTest extends Specification {
     )
 
     when:
-    extractor.onStart(builder, request)
+    extractor.onStart(builder, context, request)
 
     then:
     1 * builder.put({ it.getKey() == "x" }, "a")
@@ -143,6 +149,7 @@ class MethodSpanAttributesExtractorTest extends Specification {
   def "applies cached bindings"() {
     given:
     def request = new Object()
+    def context = Context.root()
     def method = TestClass.getDeclaredMethod("method", String, String, String)
     AttributesBuilder builder = Mock()
 
@@ -161,7 +168,7 @@ class MethodSpanAttributesExtractorTest extends Specification {
     )
 
     when:
-    extractor.onStart(builder, request)
+    extractor.onStart(builder, context, request)
 
     then:
     1 * bindings.apply(_, ["a", "b", "c"])
@@ -170,6 +177,7 @@ class MethodSpanAttributesExtractorTest extends Specification {
   def "does not apply cached empty bindings"() {
     given:
     def request = new Object()
+    def context = Context.root()
     def method = TestClass.getDeclaredMethod("method", String, String, String)
     AttributesBuilder builder = Mock()
 
@@ -188,13 +196,14 @@ class MethodSpanAttributesExtractorTest extends Specification {
     )
 
     when:
-    extractor.onStart(builder, request)
+    extractor.onStart(builder, context, request)
 
     then:
     0 * bindings.apply(_, _)
   }
 
   class TestClass {
+    @SuppressWarnings("unused")
     void method(String x, String y, String z) {}
   }
 }

+ 43 - 8
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/AttributesExtractor.java

@@ -7,6 +7,7 @@ package io.opentelemetry.instrumentation.api.instrumenter;
 
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.db.DbAttributesExtractor;
 import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
 import io.opentelemetry.instrumentation.api.instrumenter.net.NetServerAttributesExtractor;
@@ -14,32 +15,66 @@ import javax.annotation.Nullable;
 
 /**
  * Extractor of {@link io.opentelemetry.api.common.Attributes} for a given request and response.
- * Will be called {@linkplain #onStart(AttributesBuilder, Object) on start} with just the {@link
- * REQUEST} and again {@linkplain #onEnd(AttributesBuilder, Object, Object, Throwable) on end} with
- * both {@link REQUEST} and {@link RESPONSE} to allow populating attributes at each stage of a
- * request's lifecycle. It is best to populate as much as possible in {@link
- * #onStart(AttributesBuilder, Object)} to have it available during sampling.
+ * Will be called {@linkplain #onStart(AttributesBuilder, Context, Object) on start} with just the
+ * {@link REQUEST} and again {@linkplain #onEnd(AttributesBuilder, Context, Object, Object,
+ * Throwable) on end} with both {@link REQUEST} and {@link RESPONSE} to allow populating attributes
+ * at each stage of a request's lifecycle. It is best to populate as much as possible in {@link
+ * #onStart(AttributesBuilder, Context, Object)} to have it available during sampling.
  *
  * @see DbAttributesExtractor
  * @see HttpClientAttributesExtractor
  * @see NetServerAttributesExtractor
  */
 public interface AttributesExtractor<REQUEST, RESPONSE> {
+
+  /**
+   * Extracts attributes from the {@link Context} and the {@link REQUEST} into the {@link
+   * AttributesBuilder} at the beginning of a request.
+   */
+  default void onStart(AttributesBuilder attributes, Context parentContext, REQUEST request) {
+    onStart(attributes, request);
+  }
+
   /**
    * Extracts attributes from the {@link REQUEST} into the {@link AttributesBuilder} at the
    * beginning of a request.
+   *
+   * @deprecated Use {@link #onStart(AttributesBuilder, Context, Object)} instead.
+   */
+  @Deprecated
+  default void onStart(AttributesBuilder attributes, REQUEST request) {
+    throw new UnsupportedOperationException(
+        "This method variant is deprecated and will be removed in the next minor release.");
+  }
+
+  /**
+   * Extracts attributes from the {@link Context}, the {@link REQUEST} and either {@link RESPONSE}
+   * or {@code error} into the {@link AttributesBuilder} at the end of a request.
    */
-  void onStart(AttributesBuilder attributes, REQUEST request);
+  default void onEnd(
+      AttributesBuilder attributes,
+      Context context,
+      REQUEST request,
+      @Nullable RESPONSE response,
+      @Nullable Throwable error) {
+    onEnd(attributes, request, response, error);
+  }
 
   /**
    * Extracts attributes from the {@link REQUEST} and either {@link RESPONSE} or {@code error} into
    * the {@link AttributesBuilder} at the end of a request.
+   *
+   * @deprecated Use {@link #onEnd(AttributesBuilder, Context, Object, Object, Throwable)} instead.
    */
-  void onEnd(
+  @Deprecated
+  default void onEnd(
       AttributesBuilder attributes,
       REQUEST request,
       @Nullable RESPONSE response,
-      @Nullable Throwable error);
+      @Nullable Throwable error) {
+    throw new UnsupportedOperationException(
+        "This method variant is deprecated and will be removed in the next minor release.");
+  }
 
   /**
    * Sets the {@code value} with the given {@code key} to the {@link AttributesBuilder} if {@code

+ 3 - 1
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/ConstantAttributesExtractor.java

@@ -7,6 +7,7 @@ package io.opentelemetry.instrumentation.api.instrumenter;
 
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import javax.annotation.Nullable;
 
 final class ConstantAttributesExtractor<REQUEST, RESPONSE, T>
@@ -21,13 +22,14 @@ final class ConstantAttributesExtractor<REQUEST, RESPONSE, T>
   }
 
   @Override
-  public void onStart(AttributesBuilder attributes, REQUEST request) {
+  public void onStart(AttributesBuilder attributes, Context parentContext, REQUEST request) {
     attributes.put(attributeKey, attributeValue);
   }
 
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       REQUEST request,
       @Nullable RESPONSE response,
       @Nullable Throwable error) {}

+ 2 - 2
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/Instrumenter.java

@@ -171,7 +171,7 @@ public class Instrumenter<REQUEST, RESPONSE> {
 
     UnsafeAttributes attributesBuilder = new UnsafeAttributes();
     for (AttributesExtractor<? super REQUEST, ? super RESPONSE> extractor : attributesExtractors) {
-      extractor.onStart(attributesBuilder, request);
+      extractor.onStart(attributesBuilder, parentContext, request);
     }
     Attributes attributes = attributesBuilder;
 
@@ -221,7 +221,7 @@ public class Instrumenter<REQUEST, RESPONSE> {
 
     UnsafeAttributes attributes = new UnsafeAttributes();
     for (AttributesExtractor<? super REQUEST, ? super RESPONSE> extractor : attributesExtractors) {
-      extractor.onEnd(attributes, request, response, error);
+      extractor.onEnd(attributes, context, request, response, error);
     }
     span.setAllAttributes(attributes);
 

+ 3 - 1
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/PeerServiceAttributesExtractor.java

@@ -8,6 +8,7 @@ package io.opentelemetry.instrumentation.api.instrumenter;
 import static java.util.Collections.emptyMap;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.config.Config;
 import io.opentelemetry.instrumentation.api.instrumenter.net.NetClientAttributesGetter;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
@@ -49,11 +50,12 @@ public final class PeerServiceAttributesExtractor<REQUEST, RESPONSE>
   }
 
   @Override
-  public void onStart(AttributesBuilder attributes, REQUEST request) {}
+  public void onStart(AttributesBuilder attributes, Context parentContext, REQUEST request) {}
 
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       REQUEST request,
       @Nullable RESPONSE response,
       @Nullable Throwable error) {

+ 3 - 1
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/code/CodeAttributesExtractor.java

@@ -6,6 +6,7 @@
 package io.opentelemetry.instrumentation.api.instrumenter.code;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import javax.annotation.Nullable;
@@ -19,7 +20,7 @@ public abstract class CodeAttributesExtractor<REQUEST, RESPONSE>
     implements AttributesExtractor<REQUEST, RESPONSE> {
 
   @Override
-  public final void onStart(AttributesBuilder attributes, REQUEST request) {
+  public final void onStart(AttributesBuilder attributes, Context parentContext, REQUEST request) {
     Class<?> cls = codeClass(request);
     if (cls != null) {
       set(attributes, SemanticAttributes.CODE_NAMESPACE, cls.getName());
@@ -32,6 +33,7 @@ public abstract class CodeAttributesExtractor<REQUEST, RESPONSE>
   @Override
   public final void onEnd(
       AttributesBuilder attributes,
+      Context context,
       REQUEST request,
       @Nullable RESPONSE response,
       @Nullable Throwable error) {}

+ 4 - 1
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/db/DbAttributesExtractor.java

@@ -6,6 +6,7 @@
 package io.opentelemetry.instrumentation.api.instrumenter.db;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import javax.annotation.Nullable;
@@ -21,8 +22,9 @@ import javax.annotation.Nullable;
  */
 public abstract class DbAttributesExtractor<REQUEST, RESPONSE>
     implements AttributesExtractor<REQUEST, RESPONSE> {
+
   @Override
-  public void onStart(AttributesBuilder attributes, REQUEST request) {
+  public void onStart(AttributesBuilder attributes, Context parentContext, REQUEST request) {
     set(attributes, SemanticAttributes.DB_SYSTEM, system(request));
     set(attributes, SemanticAttributes.DB_USER, user(request));
     set(attributes, SemanticAttributes.DB_NAME, name(request));
@@ -34,6 +36,7 @@ public abstract class DbAttributesExtractor<REQUEST, RESPONSE>
   @Override
   public final void onEnd(
       AttributesBuilder attributes,
+      Context context,
       REQUEST request,
       @Nullable RESPONSE response,
       @Nullable Throwable error) {}

+ 3 - 2
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/db/SqlAttributesExtractor.java

@@ -7,6 +7,7 @@ package io.opentelemetry.instrumentation.api.instrumenter.db;
 
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.db.SqlStatementInfo;
 import io.opentelemetry.instrumentation.api.db.SqlStatementSanitizer;
 import javax.annotation.Nullable;
@@ -26,8 +27,8 @@ public abstract class SqlAttributesExtractor<REQUEST, RESPONSE>
     extends DbAttributesExtractor<REQUEST, RESPONSE> {
 
   @Override
-  public final void onStart(AttributesBuilder attributes, REQUEST request) {
-    super.onStart(attributes, request);
+  public final void onStart(AttributesBuilder attributes, Context parentContext, REQUEST request) {
+    super.onStart(attributes, parentContext, request);
     AttributeKey<String> dbTable = dbTableAttribute();
     if (dbTable != null) {
       set(attributes, dbTable, table(request));

+ 5 - 3
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpClientAttributesExtractor.java

@@ -6,6 +6,7 @@
 package io.opentelemetry.instrumentation.api.instrumenter.http;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.config.Config;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import javax.annotation.Nullable;
@@ -49,18 +50,19 @@ public final class HttpClientAttributesExtractor<REQUEST, RESPONSE>
   }
 
   @Override
-  public void onStart(AttributesBuilder attributes, REQUEST request) {
-    super.onStart(attributes, request);
+  public void onStart(AttributesBuilder attributes, Context parentContext, REQUEST request) {
+    super.onStart(attributes, parentContext, request);
     set(attributes, SemanticAttributes.HTTP_URL, getter.url(request));
   }
 
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       REQUEST request,
       @Nullable RESPONSE response,
       @Nullable Throwable error) {
-    super.onEnd(attributes, request, response, error);
+    super.onEnd(attributes, context, request, response, error);
     set(attributes, SemanticAttributes.HTTP_FLAVOR, getter.flavor(request, response));
   }
 }

+ 3 - 1
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpCommonAttributesExtractor.java

@@ -9,6 +9,7 @@ import static io.opentelemetry.instrumentation.api.instrumenter.http.HttpHeaderA
 import static io.opentelemetry.instrumentation.api.instrumenter.http.HttpHeaderAttributes.responseAttributeKey;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import java.util.List;
@@ -32,7 +33,7 @@ abstract class HttpCommonAttributesExtractor<
   }
 
   @Override
-  public void onStart(AttributesBuilder attributes, REQUEST request) {
+  public void onStart(AttributesBuilder attributes, Context parentContext, REQUEST request) {
     set(attributes, SemanticAttributes.HTTP_METHOD, getter.method(request));
     set(attributes, SemanticAttributes.HTTP_USER_AGENT, userAgent(request));
 
@@ -47,6 +48,7 @@ abstract class HttpCommonAttributesExtractor<
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       REQUEST request,
       @Nullable RESPONSE response,
       @Nullable Throwable error) {

+ 13 - 14
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpRouteHolder.java

@@ -20,7 +20,7 @@ import javax.annotation.Nullable;
  *
  * <p>Usually the route is not accessible when the request processing starts; and needs to be set
  * later, after the instrumented operation starts. This class provides several static methods that
- * allow the isntrumentation author to provide the matching HTTP route to the instrumentation when
+ * allow the instrumentation author to provide the matching HTTP route to the instrumentation when
  * it is discovered.
  */
 public final class HttpRouteHolder {
@@ -52,7 +52,7 @@ public final class HttpRouteHolder {
    * <p>If there is a server span in the context, and the context has been customized with a {@link
    * HttpRouteHolder}, then this method will update the route using the provided {@code httpRoute}
    * if and only if the last {@link HttpRouteSource} to update the route using this method has
-   * strictly lower priority than the provided {@link HttpRouteSource}, and the pased value is
+   * strictly lower priority than the provided {@link HttpRouteSource}, and the passed value is
    * non-null.
    *
    * <p>If there is a server span in the context, and the context has NOT been customized with a
@@ -111,7 +111,9 @@ public final class HttpRouteHolder {
     if (httpRouteHolder == null) {
       String httpRoute = httpRouteGetter.get(context, arg1, arg2);
       if (httpRoute != null && !httpRoute.isEmpty()) {
-        updateSpanData(serverSpan, httpRoute);
+        // update both span name and attribute, since there's no HttpRouteHolder in the context
+        serverSpan.updateName(httpRoute);
+        serverSpan.setAttribute(SemanticAttributes.HTTP_ROUTE, httpRoute);
       }
       return;
     }
@@ -124,20 +126,17 @@ public final class HttpRouteHolder {
       if (route != null
           && !route.isEmpty()
           && (!onlyIfBetterRoute || httpRouteHolder.isBetterRoute(route))) {
-        updateSpanData(serverSpan, route);
+
+        // update just the span name - the attribute will be picked up by the
+        // HttpServerAttributesExtractor at the end of request processing
+        serverSpan.updateName(route);
+
         httpRouteHolder.updatedBySourceOrder = source.order;
         httpRouteHolder.route = route;
       }
     }
   }
 
-  // TODO: instead of calling setAttribute() consider storing the route in context end retrieving it
-  // in the AttributesExtractor
-  private static void updateSpanData(Span serverSpan, String route) {
-    serverSpan.updateName(route);
-    serverSpan.setAttribute(SemanticAttributes.HTTP_ROUTE, route);
-  }
-
   // This is used when setting route from a servlet filter to pick the most descriptive (longest)
   // route.
   private boolean isBetterRoute(String name) {
@@ -147,11 +146,11 @@ public final class HttpRouteHolder {
   }
 
   /**
-   * Returns the {@code http.route} attribute value that's stored in the passed {@code context}, or
-   * null if it was not set before.
+   * Returns the {@code http.route} attribute value that's stored in the {@code context}, or null if
+   * it was not set before.
    */
   @Nullable
-  public static String getRoute(Context context) {
+  static String getRoute(Context context) {
     HttpRouteHolder httpRouteHolder = context.get(CONTEXT_KEY);
     return httpRouteHolder == null ? null : httpRouteHolder.route;
   }

+ 16 - 6
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpServerAttributesExtractor.java

@@ -9,8 +9,10 @@ import static io.opentelemetry.instrumentation.api.instrumenter.http.ForwarderHe
 import static io.opentelemetry.instrumentation.api.instrumenter.http.ForwarderHeaderParser.extractForwardedFor;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.config.Config;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
+import java.util.function.Function;
 import javax.annotation.Nullable;
 
 /**
@@ -42,18 +44,24 @@ public final class HttpServerAttributesExtractor<REQUEST, RESPONSE>
   public static <REQUEST, RESPONSE> HttpServerAttributesExtractor<REQUEST, RESPONSE> create(
       HttpServerAttributesGetter<REQUEST, RESPONSE> getter,
       CapturedHttpHeaders capturedHttpHeaders) {
-    return new HttpServerAttributesExtractor<>(getter, capturedHttpHeaders);
+    return new HttpServerAttributesExtractor<>(
+        getter, capturedHttpHeaders, HttpRouteHolder::getRoute);
   }
 
-  private HttpServerAttributesExtractor(
+  private final Function<Context, String> httpRouteHolderGetter;
+
+  // visible for tests
+  HttpServerAttributesExtractor(
       HttpServerAttributesGetter<REQUEST, RESPONSE> getter,
-      CapturedHttpHeaders capturedHttpHeaders) {
+      CapturedHttpHeaders capturedHttpHeaders,
+      Function<Context, String> httpRouteHolderGetter) {
     super(getter, capturedHttpHeaders);
+    this.httpRouteHolderGetter = httpRouteHolderGetter;
   }
 
   @Override
-  public void onStart(AttributesBuilder attributes, REQUEST request) {
-    super.onStart(attributes, request);
+  public void onStart(AttributesBuilder attributes, Context parentContext, REQUEST request) {
+    super.onStart(attributes, parentContext, request);
 
     set(attributes, SemanticAttributes.HTTP_FLAVOR, getter.flavor(request));
     set(attributes, SemanticAttributes.HTTP_SCHEME, getter.scheme(request));
@@ -66,12 +74,14 @@ public final class HttpServerAttributesExtractor<REQUEST, RESPONSE>
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       REQUEST request,
       @Nullable RESPONSE response,
       @Nullable Throwable error) {
 
-    super.onEnd(attributes, request, response, error);
+    super.onEnd(attributes, context, request, response, error);
     set(attributes, SemanticAttributes.HTTP_SERVER_NAME, getter.serverName(request, response));
+    set(attributes, SemanticAttributes.HTTP_ROUTE, httpRouteHolderGetter.apply(context));
   }
 
   @Nullable

+ 1 - 20
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpServerMetrics.java

@@ -18,9 +18,7 @@ import io.opentelemetry.context.ContextKey;
 import io.opentelemetry.instrumentation.api.annotations.UnstableApi;
 import io.opentelemetry.instrumentation.api.instrumenter.RequestListener;
 import io.opentelemetry.instrumentation.api.instrumenter.RequestMetrics;
-import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import java.util.concurrent.TimeUnit;
-import java.util.function.Function;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -51,14 +49,8 @@ public final class HttpServerMetrics implements RequestListener {
 
   private final LongUpDownCounter activeRequests;
   private final DoubleHistogram duration;
-  private final Function<Context, String> httpRouteHolderGetter;
 
   private HttpServerMetrics(Meter meter) {
-    this(meter, HttpRouteHolder::getRoute);
-  }
-
-  // visible for tests
-  HttpServerMetrics(Meter meter, Function<Context, String> httpRouteHolderGetter) {
     activeRequests =
         meter
             .upDownCounterBuilder("http.server.active_requests")
@@ -72,8 +64,6 @@ public final class HttpServerMetrics implements RequestListener {
             .setUnit("ms")
             .setDescription("The duration of the inbound HTTP request")
             .build();
-
-    this.httpRouteHolderGetter = httpRouteHolderGetter;
   }
 
   @Override
@@ -96,19 +86,10 @@ public final class HttpServerMetrics implements RequestListener {
     activeRequests.add(-1, applyActiveRequestsView(state.startAttributes()));
     duration.record(
         (endNanos - state.startTimeNanos()) / NANOS_PER_MS,
-        applyServerDurationView(state.startAttributes(), addHttpRoute(context, endAttributes)),
+        applyServerDurationView(state.startAttributes(), endAttributes),
         context);
   }
 
-  // TODO: the http.route should be extracted by the AttributesExtractor, HttpServerMetrics should
-  // not access the context to get it
-  private Attributes addHttpRoute(Context context, Attributes endAttributes) {
-    String route = httpRouteHolderGetter.apply(context);
-    return route == null
-        ? endAttributes
-        : endAttributes.toBuilder().put(SemanticAttributes.HTTP_ROUTE, route).build();
-  }
-
   @AutoValue
   abstract static class State {
 

+ 3 - 1
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/messaging/MessagingAttributesExtractor.java

@@ -6,6 +6,7 @@
 package io.opentelemetry.instrumentation.api.instrumenter.messaging;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import javax.annotation.Nullable;
@@ -24,7 +25,7 @@ public abstract class MessagingAttributesExtractor<REQUEST, RESPONSE>
   public static final String TEMP_DESTINATION_NAME = "(temporary)";
 
   @Override
-  public final void onStart(AttributesBuilder attributes, REQUEST request) {
+  public final void onStart(AttributesBuilder attributes, Context parentContext, REQUEST request) {
     set(attributes, SemanticAttributes.MESSAGING_SYSTEM, system(request));
     set(attributes, SemanticAttributes.MESSAGING_DESTINATION_KIND, destinationKind(request));
     boolean isTemporaryDestination = temporaryDestination(request);
@@ -55,6 +56,7 @@ public abstract class MessagingAttributesExtractor<REQUEST, RESPONSE>
   @Override
   public final void onEnd(
       AttributesBuilder attributes,
+      Context context,
       REQUEST request,
       @Nullable RESPONSE response,
       @Nullable Throwable error) {

+ 3 - 1
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/net/NetClientAttributesExtractor.java

@@ -6,6 +6,7 @@
 package io.opentelemetry.instrumentation.api.instrumenter.net;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import javax.annotation.Nullable;
@@ -34,11 +35,12 @@ public final class NetClientAttributesExtractor<REQUEST, RESPONSE>
   }
 
   @Override
-  public void onStart(AttributesBuilder attributes, REQUEST request) {}
+  public void onStart(AttributesBuilder attributes, Context parentContext, REQUEST request) {}
 
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       REQUEST request,
       @Nullable RESPONSE response,
       @Nullable Throwable error) {

+ 3 - 1
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/net/NetServerAttributesExtractor.java

@@ -6,6 +6,7 @@
 package io.opentelemetry.instrumentation.api.instrumenter.net;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import javax.annotation.Nullable;
@@ -31,7 +32,7 @@ public final class NetServerAttributesExtractor<REQUEST, RESPONSE>
   }
 
   @Override
-  public final void onStart(AttributesBuilder attributes, REQUEST request) {
+  public void onStart(AttributesBuilder attributes, Context parentContext, REQUEST request) {
     set(attributes, SemanticAttributes.NET_TRANSPORT, getter.transport(request));
 
     String peerIp = getter.peerIp(request);
@@ -51,6 +52,7 @@ public final class NetServerAttributesExtractor<REQUEST, RESPONSE>
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       REQUEST request,
       @Nullable RESPONSE response,
       @Nullable Throwable error) {}

+ 3 - 1
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/rpc/RpcAttributesExtractor.java

@@ -6,6 +6,7 @@
 package io.opentelemetry.instrumentation.api.instrumenter.rpc;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import javax.annotation.Nullable;
@@ -23,7 +24,7 @@ public abstract class RpcAttributesExtractor<REQUEST, RESPONSE>
     implements AttributesExtractor<REQUEST, RESPONSE> {
 
   @Override
-  public final void onStart(AttributesBuilder attributes, REQUEST request) {
+  public final void onStart(AttributesBuilder attributes, Context parentContext, REQUEST request) {
     set(attributes, SemanticAttributes.RPC_SYSTEM, system(request));
     set(attributes, SemanticAttributes.RPC_SERVICE, service(request));
     set(attributes, SemanticAttributes.RPC_METHOD, method(request));
@@ -32,6 +33,7 @@ public abstract class RpcAttributesExtractor<REQUEST, RESPONSE>
   @Override
   public final void onEnd(
       AttributesBuilder attributes,
+      Context context,
       REQUEST request,
       @Nullable RESPONSE response,
       @Nullable Throwable error) {

+ 9 - 4
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/AttributesExtractorTest.java

@@ -11,6 +11,7 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attri
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.Attributes;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import java.util.HashMap;
 import java.util.Map;
 import javax.annotation.Nullable;
@@ -22,7 +23,8 @@ class AttributesExtractorTest {
       implements AttributesExtractor<Map<String, String>, Map<String, String>> {
 
     @Override
-    public void onStart(AttributesBuilder attributes, Map<String, String> request) {
+    public void onStart(
+        AttributesBuilder attributes, Context parentContext, Map<String, String> request) {
       set(attributes, AttributeKey.stringKey("animal"), request.get("animal"));
       set(attributes, AttributeKey.stringKey("country"), request.get("country"));
     }
@@ -30,6 +32,7 @@ class AttributesExtractorTest {
     @Override
     public void onEnd(
         AttributesBuilder attributes,
+        Context context,
         Map<String, String> request,
         @Nullable Map<String, String> response,
         @Nullable Throwable error) {
@@ -54,9 +57,11 @@ class AttributesExtractorTest {
     Exception error = new RuntimeException();
 
     AttributesBuilder attributesBuilder = Attributes.builder();
-    extractor.onStart(attributesBuilder, request);
-    extractor.onEnd(attributesBuilder, request, response, null);
-    extractor.onEnd(attributesBuilder, request, null, error);
+    Context context = Context.root();
+
+    extractor.onStart(attributesBuilder, context, request);
+    extractor.onEnd(attributesBuilder, context, request, response, null);
+    extractor.onEnd(attributesBuilder, context, request, null, error);
 
     assertThat(attributesBuilder.build())
         .containsOnly(

+ 6 - 2
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterTest.java

@@ -81,7 +81,8 @@ class InstrumenterTest {
       implements AttributesExtractor<Map<String, String>, Map<String, String>> {
 
     @Override
-    public void onStart(AttributesBuilder attributes, Map<String, String> request) {
+    public void onStart(
+        AttributesBuilder attributes, Context parentContext, Map<String, String> request) {
       attributes.put("req1", request.get("req1"));
       attributes.put("req2", request.get("req2"));
     }
@@ -89,6 +90,7 @@ class InstrumenterTest {
     @Override
     public void onEnd(
         AttributesBuilder attributes,
+        Context context,
         Map<String, String> request,
         Map<String, String> response,
         @Nullable Throwable error) {
@@ -101,7 +103,8 @@ class InstrumenterTest {
       implements AttributesExtractor<Map<String, String>, Map<String, String>> {
 
     @Override
-    public void onStart(AttributesBuilder attributes, Map<String, String> request) {
+    public void onStart(
+        AttributesBuilder attributes, Context parentContext, Map<String, String> request) {
       attributes.put("req3", request.get("req3"));
       attributes.put("req2", request.get("req2_2"));
     }
@@ -109,6 +112,7 @@ class InstrumenterTest {
     @Override
     public void onEnd(
         AttributesBuilder attributes,
+        Context context,
         Map<String, String> request,
         Map<String, String> response,
         @Nullable Throwable error) {

+ 21 - 10
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/PeerServiceAttributesExtractorTest.java

@@ -14,6 +14,7 @@ import static org.mockito.BDDMockito.given;
 
 import io.opentelemetry.api.common.Attributes;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.net.NetClientAttributesGetter;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import java.util.HashMap;
@@ -35,10 +36,12 @@ class PeerServiceAttributesExtractorTest {
     PeerServiceAttributesExtractor<String, String> underTest =
         new PeerServiceAttributesExtractor<>(peerServiceMapping, netAttributesExtractor);
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder attributes = Attributes.builder();
-    underTest.onStart(attributes, "request");
-    underTest.onEnd(attributes, "request", "response", null);
+    underTest.onStart(attributes, context, "request");
+    underTest.onEnd(attributes, context, "request", "response", null);
 
     // then
     assertTrue(attributes.build().isEmpty());
@@ -54,11 +57,13 @@ class PeerServiceAttributesExtractorTest {
 
     given(netAttributesExtractor.peerName(any(), any())).willReturn("example2.com");
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder startAttributes = Attributes.builder();
-    underTest.onStart(startAttributes, "request");
+    underTest.onStart(startAttributes, context, "request");
     AttributesBuilder endAttributes = Attributes.builder();
-    underTest.onEnd(endAttributes, "request", "response", null);
+    underTest.onEnd(endAttributes, context, "request", "response", null);
 
     // then
     assertTrue(startAttributes.build().isEmpty());
@@ -75,11 +80,13 @@ class PeerServiceAttributesExtractorTest {
 
     given(netAttributesExtractor.peerIp(any(), any())).willReturn("1.2.3.5");
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder startAttributes = Attributes.builder();
-    underTest.onStart(startAttributes, "request");
+    underTest.onStart(startAttributes, context, "request");
     AttributesBuilder endAttributes = Attributes.builder();
-    underTest.onEnd(endAttributes, "request", "response", null);
+    underTest.onEnd(endAttributes, context, "request", "response", null);
 
     // then
     assertTrue(startAttributes.build().isEmpty());
@@ -98,11 +105,13 @@ class PeerServiceAttributesExtractorTest {
 
     given(netAttributesExtractor.peerName(any(), any())).willReturn("example.com");
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder startAttributes = Attributes.builder();
-    underTest.onStart(startAttributes, "request");
+    underTest.onStart(startAttributes, context, "request");
     AttributesBuilder endAttributes = Attributes.builder();
-    underTest.onEnd(endAttributes, "request", "response", null);
+    underTest.onEnd(endAttributes, context, "request", "response", null);
 
     // then
     assertThat(startAttributes.build()).isEmpty();
@@ -123,11 +132,13 @@ class PeerServiceAttributesExtractorTest {
     given(netAttributesExtractor.peerName(any(), any())).willReturn("test.com");
     given(netAttributesExtractor.peerIp(any(), any())).willReturn("1.2.3.4");
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder startAttributes = Attributes.builder();
-    underTest.onStart(startAttributes, "request");
+    underTest.onStart(startAttributes, context, "request");
     AttributesBuilder endAttributes = Attributes.builder();
-    underTest.onEnd(endAttributes, "request", "response", null);
+    underTest.onEnd(endAttributes, context, "request", "response", null);
 
     // then
     assertThat(startAttributes.build()).isEmpty();

+ 6 - 3
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/code/CodeAttributesExtractorTest.java

@@ -10,6 +10,7 @@ import static org.assertj.core.api.Assertions.entry;
 
 import io.opentelemetry.api.common.Attributes;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import java.util.Collections;
 import java.util.HashMap;
@@ -56,12 +57,14 @@ class CodeAttributesExtractorTest {
     request.put("filePath", "/tmp/TestClass.java");
     request.put("lineNo", "42");
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder startAttributes = Attributes.builder();
-    underTest.onStart(startAttributes, request);
+    underTest.onStart(startAttributes, context, request);
 
     AttributesBuilder endAttributes = Attributes.builder();
-    underTest.onEnd(endAttributes, request, null, null);
+    underTest.onEnd(endAttributes, context, request, null, null);
 
     // then
     assertThat(startAttributes.build())
@@ -78,7 +81,7 @@ class CodeAttributesExtractorTest {
   void shouldExtractNoAttributesIfNoneAreAvailable() {
     // when
     AttributesBuilder attributes = Attributes.builder();
-    underTest.onStart(attributes, Collections.emptyMap());
+    underTest.onStart(attributes, Context.root(), Collections.emptyMap());
 
     // then
     assertThat(attributes.build().isEmpty()).isTrue();

+ 6 - 3
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/db/DbAttributesExtractorTest.java

@@ -10,6 +10,7 @@ import static org.assertj.core.api.Assertions.entry;
 
 import io.opentelemetry.api.common.Attributes;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import java.util.Collections;
 import java.util.HashMap;
@@ -61,12 +62,14 @@ class DbAttributesExtractorTest {
     request.put("db.statement", "SELECT * FROM potato");
     request.put("db.operation", "SELECT");
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder startAttributes = Attributes.builder();
-    underTest.onStart(startAttributes, request);
+    underTest.onStart(startAttributes, context, request);
 
     AttributesBuilder endAttributes = Attributes.builder();
-    underTest.onEnd(endAttributes, request, null, null);
+    underTest.onEnd(endAttributes, context, request, null, null);
 
     // then
     assertThat(startAttributes.build())
@@ -85,7 +88,7 @@ class DbAttributesExtractorTest {
   void shouldExtractNoAttributesIfNoneAreAvailable() {
     // when
     AttributesBuilder attributes = Attributes.builder();
-    underTest.onStart(attributes, Collections.emptyMap());
+    underTest.onStart(attributes, Context.root(), Collections.emptyMap());
 
     // then
     assertThat(attributes.build().isEmpty()).isTrue();

+ 9 - 4
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/db/SqlAttributesExtractorTest.java

@@ -11,6 +11,7 @@ import static org.assertj.core.api.Assertions.entry;
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.Attributes;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import java.util.Collections;
 import java.util.HashMap;
@@ -65,12 +66,14 @@ class SqlAttributesExtractorTest {
 
     dbTableAttribute = SemanticAttributes.DB_SQL_TABLE;
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder startAttributes = Attributes.builder();
-    underTest.onStart(startAttributes, request);
+    underTest.onStart(startAttributes, context, request);
 
     AttributesBuilder endAttributes = Attributes.builder();
-    underTest.onEnd(endAttributes, request, null, null);
+    underTest.onEnd(endAttributes, context, request, null, null);
 
     // then
     assertThat(startAttributes.build())
@@ -94,9 +97,11 @@ class SqlAttributesExtractorTest {
 
     dbTableAttribute = null;
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder attributes = Attributes.builder();
-    underTest.onStart(attributes, request);
+    underTest.onStart(attributes, context, request);
 
     // then
     assertThat(attributes.build())
@@ -109,7 +114,7 @@ class SqlAttributesExtractorTest {
   void shouldExtractNoAttributesIfNoneAreAvailable() {
     // when
     AttributesBuilder attributes = Attributes.builder();
-    underTest.onStart(attributes, Collections.emptyMap());
+    underTest.onStart(attributes, Context.root(), Collections.emptyMap());
 
     // then
     assertThat(attributes.build().isEmpty()).isTrue();

+ 5 - 4
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpClientAttributesExtractorTest.java

@@ -14,6 +14,7 @@ import static org.assertj.core.api.Assertions.entry;
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.Attributes;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import java.util.HashMap;
 import java.util.List;
@@ -109,7 +110,7 @@ class HttpClientAttributesExtractorTest {
                 singletonList("Custom-Request-Header"), singletonList("Custom-Response-Header")));
 
     AttributesBuilder attributes = Attributes.builder();
-    extractor.onStart(attributes, request);
+    extractor.onStart(attributes, Context.root(), request);
     assertThat(attributes.build())
         .containsOnly(
             entry(SemanticAttributes.HTTP_METHOD, "POST"),
@@ -119,7 +120,7 @@ class HttpClientAttributesExtractorTest {
                 AttributeKey.stringArrayKey("http.request.header.custom_request_header"),
                 asList("123", "456")));
 
-    extractor.onEnd(attributes, request, response, null);
+    extractor.onEnd(attributes, Context.root(), request, response, null);
     assertThat(attributes.build())
         .containsOnly(
             entry(SemanticAttributes.HTTP_METHOD, "POST"),
@@ -151,10 +152,10 @@ class HttpClientAttributesExtractorTest {
             new TestHttpClientAttributesGetter(), CapturedHttpHeaders.empty());
 
     AttributesBuilder attributes = Attributes.builder();
-    extractor.onStart(attributes, request);
+    extractor.onStart(attributes, Context.root(), request);
     assertThat(attributes.build()).isEmpty();
 
-    extractor.onEnd(attributes, request, response, null);
+    extractor.onEnd(attributes, Context.root(), request, response, null);
     assertThat(attributes.build()).isEmpty();
   }
 }

+ 12 - 7
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpServerAttributesExtractorTest.java

@@ -14,10 +14,12 @@ import static org.assertj.core.api.Assertions.entry;
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.Attributes;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Function;
 import org.junit.jupiter.api.Test;
 
 class HttpServerAttributesExtractorTest {
@@ -124,14 +126,17 @@ class HttpServerAttributesExtractorTest {
     response.put("responseContentLengthUncompressed", "21");
     response.put("header.custom-response-header", "654,321");
 
+    Function<Context, String> routeFromContext = ctx -> "/repositories/{repoId}";
+
     HttpServerAttributesExtractor<Map<String, String>, Map<String, String>> extractor =
-        HttpServerAttributesExtractor.create(
+        new HttpServerAttributesExtractor<>(
             new TestHttpServerAttributesExtractor(),
             CapturedHttpHeaders.create(
-                singletonList("Custom-Request-Header"), singletonList("Custom-Response-Header")));
+                singletonList("Custom-Request-Header"), singletonList("Custom-Response-Header")),
+            routeFromContext);
 
     AttributesBuilder attributes = Attributes.builder();
-    extractor.onStart(attributes, request);
+    extractor.onStart(attributes, Context.root(), request);
     assertThat(attributes.build())
         .containsOnly(
             entry(SemanticAttributes.HTTP_FLAVOR, "http/2"),
@@ -146,7 +151,7 @@ class HttpServerAttributesExtractorTest {
                 AttributeKey.stringArrayKey("http.request.header.custom_request_header"),
                 asList("123", "456")));
 
-    extractor.onEnd(attributes, request, response, null);
+    extractor.onEnd(attributes, Context.root(), request, response, null);
     assertThat(attributes.build())
         .containsOnly(
             entry(SemanticAttributes.HTTP_METHOD, "POST"),
@@ -154,7 +159,7 @@ class HttpServerAttributesExtractorTest {
             entry(SemanticAttributes.HTTP_HOST, "github.com"),
             entry(SemanticAttributes.HTTP_TARGET, "/repositories/1"),
             entry(SemanticAttributes.HTTP_USER_AGENT, "okhttp 3.x"),
-            entry(SemanticAttributes.HTTP_ROUTE, "/repositories/{id}"),
+            entry(SemanticAttributes.HTTP_ROUTE, "/repositories/{repoId}"),
             entry(SemanticAttributes.HTTP_CLIENT_IP, "1.1.1.1"),
             entry(
                 AttributeKey.stringArrayKey("http.request.header.custom_request_header"),
@@ -181,11 +186,11 @@ class HttpServerAttributesExtractorTest {
             new TestHttpServerAttributesExtractor(), CapturedHttpHeaders.empty());
 
     AttributesBuilder attributes = Attributes.builder();
-    extractor.onStart(attributes, request);
+    extractor.onStart(attributes, Context.root(), request);
     assertThat(attributes.build())
         .containsOnly(entry(SemanticAttributes.HTTP_CLIENT_IP, "1.1.1.1"));
 
-    extractor.onEnd(attributes, request, null, null);
+    extractor.onEnd(attributes, Context.root(), request, null, null);
     assertThat(attributes.build())
         .containsOnly(entry(SemanticAttributes.HTTP_CLIENT_IP, "1.1.1.1"));
   }

+ 3 - 3
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpServerMetricsTest.java

@@ -157,7 +157,7 @@ class HttpServerMetricsTest {
   }
 
   @Test
-  void collectsHttpRouteFromContext() {
+  void collectsHttpRouteFromEndAttributes() {
     // given
     InMemoryMetricReader metricReader = InMemoryMetricReader.create();
     SdkMeterProvider meterProvider =
@@ -166,12 +166,12 @@ class HttpServerMetricsTest {
             .setMinimumCollectionInterval(Duration.ZERO)
             .build();
 
-    RequestListener listener = new HttpServerMetrics(meterProvider.get("test"), c -> "/test/{id}");
+    RequestListener listener = HttpServerMetrics.get().create(meterProvider.get("test"));
 
     Attributes requestAttributes =
         Attributes.builder().put("http.host", "host").put("http.scheme", "https").build();
 
-    Attributes responseAttributes = Attributes.empty();
+    Attributes responseAttributes = Attributes.builder().put("http.route", "/test/{id}").build();
 
     Context parentContext = Context.root();
 

+ 9 - 4
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/messaging/MessagingAttributesExtractorTest.java

@@ -11,6 +11,7 @@ import static org.assertj.core.api.Assertions.entry;
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.Attributes;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -50,12 +51,14 @@ class MessagingAttributesExtractorTest {
 
     TestMessagingAttributesExtractor underTest = new TestMessagingAttributesExtractor(operation);
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder startAttributes = Attributes.builder();
-    underTest.onStart(startAttributes, request);
+    underTest.onStart(startAttributes, context, request);
 
     AttributesBuilder endAttributes = Attributes.builder();
-    underTest.onEnd(endAttributes, request, "42", null);
+    underTest.onEnd(endAttributes, context, request, "42", null);
 
     // then
     List<MapEntry<AttributeKey<?>, Object>> expectedEntries = new ArrayList<>();
@@ -95,12 +98,14 @@ class MessagingAttributesExtractorTest {
     TestMessagingAttributesExtractor underTest =
         new TestMessagingAttributesExtractor(MessageOperation.SEND);
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder startAttributes = Attributes.builder();
-    underTest.onStart(startAttributes, Collections.emptyMap());
+    underTest.onStart(startAttributes, context, Collections.emptyMap());
 
     AttributesBuilder endAttributes = Attributes.builder();
-    underTest.onEnd(endAttributes, Collections.emptyMap(), null, null);
+    underTest.onEnd(endAttributes, context, Collections.emptyMap(), null, null);
 
     // then
     assertThat(startAttributes.build().isEmpty()).isTrue();

+ 10 - 5
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/net/InetSocketAddressNetClientAttributesGetterTest.java

@@ -10,6 +10,7 @@ import static org.assertj.core.api.Assertions.entry;
 
 import io.opentelemetry.api.common.Attributes;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import java.net.InetSocketAddress;
 import org.junit.jupiter.api.Test;
@@ -40,7 +41,7 @@ class InetSocketAddressNetClientAttributesGetterTest {
   void noInetSocketAddress() {
 
     AttributesBuilder attributes = Attributes.builder();
-    extractor.onEnd(attributes, null, null, null);
+    extractor.onEnd(attributes, Context.root(), null, null, null);
     assertThat(attributes.build())
         .containsOnly(
             entry(SemanticAttributes.NET_TRANSPORT, SemanticAttributes.NetTransportValues.IP_TCP));
@@ -55,12 +56,14 @@ class InetSocketAddressNetClientAttributesGetterTest {
     InetSocketAddress response = new InetSocketAddress("api.github.com", 456);
     assertThat(request.getAddress().getHostAddress()).isNotNull();
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder startAttributes = Attributes.builder();
-    extractor.onStart(startAttributes, request);
+    extractor.onStart(startAttributes, context, request);
 
     AttributesBuilder endAttributes = Attributes.builder();
-    extractor.onEnd(endAttributes, request, response, null);
+    extractor.onEnd(endAttributes, context, request, response, null);
 
     // then
     assertThat(startAttributes.build()).isEmpty();
@@ -82,12 +85,14 @@ class InetSocketAddressNetClientAttributesGetterTest {
     InetSocketAddress response = InetSocketAddress.createUnresolved("api.github.com", 456);
     assertThat(request.getAddress()).isNull();
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder startAttributes = Attributes.builder();
-    extractor.onStart(startAttributes, request);
+    extractor.onStart(startAttributes, context, request);
 
     AttributesBuilder endAttributes = Attributes.builder();
-    extractor.onEnd(endAttributes, request, response, null);
+    extractor.onEnd(endAttributes, context, request, response, null);
 
     // then
     assertThat(startAttributes.build()).isEmpty();

+ 10 - 5
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/net/InetSocketAddressNetServerAttributesGetterTest.java

@@ -10,6 +10,7 @@ import static org.assertj.core.api.Assertions.entry;
 
 import io.opentelemetry.api.common.Attributes;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import java.net.InetSocketAddress;
 import org.junit.jupiter.api.Test;
@@ -36,7 +37,7 @@ class InetSocketAddressNetServerAttributesGetterTest {
   @Test
   void noInetSocketAddress() {
     AttributesBuilder attributes = Attributes.builder();
-    extractor.onStart(attributes, null);
+    extractor.onStart(attributes, Context.root(), null);
     assertThat(attributes.build())
         .containsOnly(
             entry(SemanticAttributes.NET_TRANSPORT, SemanticAttributes.NetTransportValues.IP_TCP));
@@ -51,12 +52,14 @@ class InetSocketAddressNetServerAttributesGetterTest {
     InetSocketAddress response = new InetSocketAddress("api.github.com", 456);
     assertThat(request.getAddress().getHostAddress()).isNotNull();
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder startAttributes = Attributes.builder();
-    extractor.onStart(startAttributes, request);
+    extractor.onStart(startAttributes, context, request);
 
     AttributesBuilder endAttributes = Attributes.builder();
-    extractor.onEnd(endAttributes, request, response, null);
+    extractor.onEnd(endAttributes, context, request, response, null);
 
     // then
     assertThat(startAttributes.build())
@@ -78,12 +81,14 @@ class InetSocketAddressNetServerAttributesGetterTest {
     InetSocketAddress response = InetSocketAddress.createUnresolved("api.github.com", 456);
     assertThat(request.getAddress()).isNull();
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder startAttributes = Attributes.builder();
-    extractor.onStart(startAttributes, request);
+    extractor.onStart(startAttributes, context, request);
 
     AttributesBuilder endAttributes = Attributes.builder();
-    extractor.onEnd(endAttributes, request, response, null);
+    extractor.onEnd(endAttributes, context, request, response, null);
 
     // then
     assertThat(startAttributes.build())

+ 13 - 6
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/net/NetClientAttributesExtractorTest.java

@@ -10,6 +10,7 @@ import static org.assertj.core.api.Assertions.entry;
 
 import io.opentelemetry.api.common.Attributes;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import java.util.HashMap;
 import java.util.Map;
@@ -68,12 +69,14 @@ class NetClientAttributesExtractorTest {
     NetClientAttributesExtractor<Map<String, String>, Map<String, String>> extractor =
         NetClientAttributesExtractor.create(getter);
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder startAttributes = Attributes.builder();
-    extractor.onStart(startAttributes, request);
+    extractor.onStart(startAttributes, context, request);
 
     AttributesBuilder endAttributes = Attributes.builder();
-    extractor.onEnd(endAttributes, request, response, null);
+    extractor.onEnd(endAttributes, context, request, response, null);
 
     // then
     assertThat(startAttributes.build()).isEmpty();
@@ -103,12 +106,14 @@ class NetClientAttributesExtractorTest {
     NetClientAttributesExtractor<Map<String, String>, Map<String, String>> extractor =
         NetClientAttributesExtractor.create(getter);
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder startAttributes = Attributes.builder();
-    extractor.onStart(startAttributes, request);
+    extractor.onStart(startAttributes, context, request);
 
     AttributesBuilder endAttributes = Attributes.builder();
-    extractor.onEnd(endAttributes, request, response, null);
+    extractor.onEnd(endAttributes, context, request, response, null);
 
     // then
     assertThat(startAttributes.build()).isEmpty();
@@ -132,12 +137,14 @@ class NetClientAttributesExtractorTest {
     NetClientAttributesExtractor<Map<String, String>, Map<String, String>> extractor =
         NetClientAttributesExtractor.create(getter);
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder startAttributes = Attributes.builder();
-    extractor.onStart(startAttributes, request);
+    extractor.onStart(startAttributes, context, request);
 
     AttributesBuilder endAttributes = Attributes.builder();
-    extractor.onEnd(endAttributes, request, response, null);
+    extractor.onEnd(endAttributes, context, request, response, null);
 
     // then
     assertThat(startAttributes.build()).isEmpty();

+ 13 - 6
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/net/NetServerAttributesExtractorTest.java

@@ -10,6 +10,7 @@ import static org.assertj.core.api.Assertions.entry;
 
 import io.opentelemetry.api.common.Attributes;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import java.util.HashMap;
 import java.util.Map;
@@ -58,12 +59,14 @@ class NetServerAttributesExtractorTest {
     NetServerAttributesExtractor<Map<String, String>, Map<String, String>> extractor =
         createTestExtractor();
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder startAttributes = Attributes.builder();
-    extractor.onStart(startAttributes, request);
+    extractor.onStart(startAttributes, context, request);
 
     AttributesBuilder endAttributes = Attributes.builder();
-    extractor.onEnd(endAttributes, request, response, null);
+    extractor.onEnd(endAttributes, context, request, response, null);
 
     // then
     assertThat(startAttributes.build())
@@ -93,12 +96,14 @@ class NetServerAttributesExtractorTest {
     NetServerAttributesExtractor<Map<String, String>, Map<String, String>> extractor =
         createTestExtractor();
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder startAttributes = Attributes.builder();
-    extractor.onStart(startAttributes, request);
+    extractor.onStart(startAttributes, context, request);
 
     AttributesBuilder endAttributes = Attributes.builder();
-    extractor.onEnd(endAttributes, request, response, null);
+    extractor.onEnd(endAttributes, context, request, response, null);
 
     // then
     assertThat(startAttributes.build())
@@ -122,12 +127,14 @@ class NetServerAttributesExtractorTest {
     NetServerAttributesExtractor<Map<String, String>, Map<String, String>> extractor =
         createTestExtractor();
 
+    Context context = Context.root();
+
     // when
     AttributesBuilder startAttributes = Attributes.builder();
-    extractor.onStart(startAttributes, request);
+    extractor.onStart(startAttributes, context, request);
 
     AttributesBuilder endAttributes = Attributes.builder();
-    extractor.onEnd(endAttributes, request, response, null);
+    extractor.onEnd(endAttributes, context, request, response, null);
 
     // then
     assertThat(startAttributes.build()).isEmpty();

+ 5 - 2
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/rpc/RpcAttributesExtractorTest.java

@@ -10,6 +10,7 @@ import static org.assertj.core.api.Assertions.entry;
 
 import io.opentelemetry.api.common.Attributes;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import java.util.HashMap;
 import java.util.Map;
@@ -41,15 +42,17 @@ class RpcAttributesExtractorTest {
     request.put("service", "my.Service");
     request.put("method", "Method");
 
+    Context context = Context.root();
+
     TestExtractor extractor = new TestExtractor();
     AttributesBuilder attributes = Attributes.builder();
-    extractor.onStart(attributes, request);
+    extractor.onStart(attributes, context, request);
     assertThat(attributes.build())
         .containsOnly(
             entry(SemanticAttributes.RPC_SYSTEM, "test"),
             entry(SemanticAttributes.RPC_SERVICE, "my.Service"),
             entry(SemanticAttributes.RPC_METHOD, "Method"));
-    extractor.onEnd(attributes, request, null, null);
+    extractor.onEnd(attributes, context, request, null, null);
     assertThat(attributes.build())
         .containsOnly(
             entry(SemanticAttributes.RPC_SYSTEM, "test"),

+ 4 - 1
instrumentation/apache-camel-2.20/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachecamel/CamelSingletons.java

@@ -8,6 +8,7 @@ package io.opentelemetry.javaagent.instrumentation.apachecamel;
 import io.opentelemetry.api.GlobalOpenTelemetry;
 import io.opentelemetry.api.common.AttributesBuilder;
 import io.opentelemetry.api.trace.StatusCode;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
 import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
@@ -39,7 +40,8 @@ public final class CamelSingletons {
         new AttributesExtractor<CamelRequest, Void>() {
 
           @Override
-          public void onStart(AttributesBuilder attributes, CamelRequest camelRequest) {
+          public void onStart(
+              AttributesBuilder attributes, Context parentContext, CamelRequest camelRequest) {
             SpanDecorator spanDecorator = camelRequest.getSpanDecorator();
             spanDecorator.pre(
                 attributes,
@@ -51,6 +53,7 @@ public final class CamelSingletons {
           @Override
           public void onEnd(
               AttributesBuilder attributes,
+              Context context,
               CamelRequest camelRequest,
               @Nullable Void unused,
               @Nullable Throwable error) {

+ 4 - 1
instrumentation/async-http-client/async-http-client-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/asynchttpclient/v2_0/AsyncHttpClientAdditionalAttributesExtractor.java

@@ -6,6 +6,7 @@
 package io.opentelemetry.javaagent.instrumentation.asynchttpclient.v2_0;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import javax.annotation.Nullable;
@@ -16,11 +17,13 @@ public class AsyncHttpClientAdditionalAttributesExtractor
     implements AttributesExtractor<RequestContext, Response> {
 
   @Override
-  public void onStart(AttributesBuilder attributes, RequestContext requestContext) {}
+  public void onStart(
+      AttributesBuilder attributes, Context parentContext, RequestContext requestContext) {}
 
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       RequestContext requestContext,
       @Nullable Response response,
       @Nullable Throwable error) {

+ 4 - 1
instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/internal/ApiGatewayProxyAttributesExtractor.java

@@ -16,6 +16,7 @@ import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.HTTP_
 import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
 import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.instrumentation.awslambda.v1_0.AwsLambdaRequest;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
@@ -28,7 +29,8 @@ import javax.annotation.Nullable;
 final class ApiGatewayProxyAttributesExtractor
     implements AttributesExtractor<AwsLambdaRequest, Object> {
   @Override
-  public void onStart(AttributesBuilder attributes, AwsLambdaRequest request) {
+  public void onStart(
+      AttributesBuilder attributes, Context parentContext, AwsLambdaRequest request) {
     if (request.getInput() instanceof APIGatewayProxyRequestEvent) {
       set(attributes, FAAS_TRIGGER, SemanticAttributes.FaasTriggerValues.HTTP);
       onRequest(attributes, (APIGatewayProxyRequestEvent) request.getInput());
@@ -78,6 +80,7 @@ final class ApiGatewayProxyAttributesExtractor
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       AwsLambdaRequest request,
       @Nullable Object response,
       @Nullable Throwable error) {

+ 11 - 7
instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/internal/AwsLambdaFunctionAttributesExtractor.java

@@ -40,27 +40,31 @@ class AwsLambdaFunctionAttributesExtractor
   private volatile String accountId;
 
   @Override
-  public void onStart(AttributesBuilder attributes, AwsLambdaRequest request) {
-    Context context = request.getAwsContext();
-    set(attributes, FAAS_EXECUTION, context.getAwsRequestId());
-    set(attributes, FAAS_ID, getFunctionArn(context));
-    set(attributes, CLOUD_ACCOUNT_ID, getAccountId(getFunctionArn(context)));
+  public void onStart(
+      AttributesBuilder attributes,
+      io.opentelemetry.context.Context parentContext,
+      AwsLambdaRequest request) {
+    Context awsContext = request.getAwsContext();
+    set(attributes, FAAS_EXECUTION, awsContext.getAwsRequestId());
+    set(attributes, FAAS_ID, getFunctionArn(awsContext));
+    set(attributes, CLOUD_ACCOUNT_ID, getAccountId(getFunctionArn(awsContext)));
   }
 
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      io.opentelemetry.context.Context context,
       AwsLambdaRequest request,
       @Nullable Object response,
       @Nullable Throwable error) {}
 
   @Nullable
-  private static String getFunctionArn(Context context) {
+  private static String getFunctionArn(Context awsContext) {
     if (GET_FUNCTION_ARN == null) {
       return null;
     }
     try {
-      return (String) GET_FUNCTION_ARN.invoke(context);
+      return (String) GET_FUNCTION_ARN.invoke(awsContext);
     } catch (Throwable throwable) {
       return null;
     }

+ 3 - 1
instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/internal/SqsEventAttributesExtractor.java

@@ -7,13 +7,14 @@ package io.opentelemetry.instrumentation.awslambda.v1_0.internal;
 
 import com.amazonaws.services.lambda.runtime.events.SQSEvent;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import javax.annotation.Nullable;
 
 class SqsEventAttributesExtractor implements AttributesExtractor<SQSEvent, Void> {
   @Override
-  public void onStart(AttributesBuilder attributes, SQSEvent event) {
+  public void onStart(AttributesBuilder attributes, Context parentContext, SQSEvent event) {
     attributes.put(SemanticAttributes.MESSAGING_SYSTEM, "AmazonSQS");
     attributes.put(SemanticAttributes.MESSAGING_OPERATION, "process");
   }
@@ -21,6 +22,7 @@ class SqsEventAttributesExtractor implements AttributesExtractor<SQSEvent, Void>
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       SQSEvent event,
       @Nullable Void unused,
       @Nullable Throwable error) {}

+ 3 - 1
instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/internal/SqsMessageAttributesExtractor.java

@@ -7,13 +7,14 @@ package io.opentelemetry.instrumentation.awslambda.v1_0.internal;
 
 import com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import javax.annotation.Nullable;
 
 class SqsMessageAttributesExtractor implements AttributesExtractor<SQSMessage, Void> {
   @Override
-  public void onStart(AttributesBuilder attributes, SQSMessage message) {
+  public void onStart(AttributesBuilder attributes, Context parentContext, SQSMessage message) {
     attributes.put(SemanticAttributes.MESSAGING_SYSTEM, "AmazonSQS");
     attributes.put(SemanticAttributes.MESSAGING_OPERATION, "process");
     attributes.put(SemanticAttributes.MESSAGING_MESSAGE_ID, message.getMessageId());
@@ -23,6 +24,7 @@ class SqsMessageAttributesExtractor implements AttributesExtractor<SQSMessage, V
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       SQSMessage message,
       @Nullable Void unused,
       @Nullable Throwable error) {}

+ 3 - 1
instrumentation/aws-sdk/aws-sdk-1.11/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/AwsSdkExperimentalAttributesExtractor.java

@@ -18,6 +18,7 @@ import com.amazonaws.AmazonWebServiceResponse;
 import com.amazonaws.Request;
 import com.amazonaws.Response;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import javax.annotation.Nullable;
 
@@ -26,7 +27,7 @@ class AwsSdkExperimentalAttributesExtractor
   private static final String COMPONENT_NAME = "java-aws-sdk";
 
   @Override
-  public void onStart(AttributesBuilder attributes, Request<?> request) {
+  public void onStart(AttributesBuilder attributes, Context parentContext, Request<?> request) {
     set(attributes, AWS_AGENT, COMPONENT_NAME);
     set(attributes, AWS_ENDPOINT, request.getEndpoint().toString());
 
@@ -41,6 +42,7 @@ class AwsSdkExperimentalAttributesExtractor
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       Request<?> request,
       @Nullable Response<?> response,
       @Nullable Throwable error) {

+ 6 - 1
instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AwsSdkExperimentalAttributesExtractor.java

@@ -7,6 +7,7 @@ package io.opentelemetry.instrumentation.awssdk.v2_2;
 
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import javax.annotation.Nullable;
 import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
@@ -19,13 +20,17 @@ class AwsSdkExperimentalAttributesExtractor
   private static final AttributeKey<String> AWS_AGENT = AttributeKey.stringKey("aws.agent");
 
   @Override
-  public void onStart(AttributesBuilder attributes, ExecutionAttributes executionAttributes) {
+  public void onStart(
+      AttributesBuilder attributes,
+      Context parentContext,
+      ExecutionAttributes executionAttributes) {
     attributes.put(AWS_AGENT, COMPONENT_NAME);
   }
 
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       ExecutionAttributes executionAttributes,
       @Nullable SdkHttpResponse sdkHttpResponse,
       @Nullable Throwable error) {}

+ 4 - 1
instrumentation/cassandra/cassandra-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/cassandra/v4_0/CassandraAttributesExtractor.java

@@ -11,6 +11,7 @@ import com.datastax.oss.driver.api.core.cql.ExecutionInfo;
 import com.datastax.oss.driver.api.core.cql.Statement;
 import com.datastax.oss.driver.api.core.metadata.Node;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import javax.annotation.Nullable;
@@ -19,11 +20,13 @@ final class CassandraAttributesExtractor
     implements AttributesExtractor<CassandraRequest, ExecutionInfo> {
 
   @Override
-  public void onStart(AttributesBuilder attributes, CassandraRequest request) {}
+  public void onStart(
+      AttributesBuilder attributes, Context parentContext, CassandraRequest request) {}
 
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       CassandraRequest request,
       @Nullable ExecutionInfo executionInfo,
       @Nullable Throwable error) {

+ 6 - 2
instrumentation/elasticsearch/elasticsearch-transport-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_0/Elasticsearch5TransportExperimentalAttributesExtractor.java

@@ -6,6 +6,7 @@
 package io.opentelemetry.javaagent.instrumentation.elasticsearch.transport.v5_0;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.javaagent.instrumentation.elasticsearch.transport.ElasticTransportRequest;
 import io.opentelemetry.javaagent.instrumentation.elasticsearch.transport.ElasticsearchTransportExperimentalAttributesExtractor;
 import org.elasticsearch.action.DocumentRequest;
@@ -14,8 +15,11 @@ public class Elasticsearch5TransportExperimentalAttributesExtractor
     extends ElasticsearchTransportExperimentalAttributesExtractor {
 
   @Override
-  public void onStart(AttributesBuilder attributes, ElasticTransportRequest transportRequest) {
-    super.onStart(attributes, transportRequest);
+  public void onStart(
+      AttributesBuilder attributes,
+      Context parentContext,
+      ElasticTransportRequest transportRequest) {
+    super.onStart(attributes, parentContext, transportRequest);
 
     Object request = transportRequest.getRequest();
     if (request instanceof DocumentRequest) {

+ 6 - 2
instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_3/Elasticsearch53TransportExperimentalAttributesExtractor.java

@@ -6,6 +6,7 @@
 package io.opentelemetry.javaagent.instrumentation.elasticsearch.transport.v5_3;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.javaagent.instrumentation.elasticsearch.transport.ElasticTransportRequest;
 import io.opentelemetry.javaagent.instrumentation.elasticsearch.transport.ElasticsearchTransportExperimentalAttributesExtractor;
 import org.elasticsearch.action.DocWriteRequest;
@@ -14,8 +15,11 @@ public class Elasticsearch53TransportExperimentalAttributesExtractor
     extends ElasticsearchTransportExperimentalAttributesExtractor {
 
   @Override
-  public void onStart(AttributesBuilder attributes, ElasticTransportRequest transportRequest) {
-    super.onStart(attributes, transportRequest);
+  public void onStart(
+      AttributesBuilder attributes,
+      Context parentContext,
+      ElasticTransportRequest transportRequest) {
+    super.onStart(attributes, parentContext, transportRequest);
 
     Object request = transportRequest.getRequest();
     if (request instanceof DocWriteRequest) {

+ 6 - 2
instrumentation/elasticsearch/elasticsearch-transport-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v6_0/Elasticsearch6TransportExperimentalAttributesExtractor.java

@@ -6,6 +6,7 @@
 package io.opentelemetry.javaagent.instrumentation.elasticsearch.transport.v6_0;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.javaagent.instrumentation.elasticsearch.transport.ElasticTransportRequest;
 import io.opentelemetry.javaagent.instrumentation.elasticsearch.transport.ElasticsearchTransportExperimentalAttributesExtractor;
 import org.elasticsearch.action.DocWriteRequest;
@@ -14,8 +15,11 @@ public class Elasticsearch6TransportExperimentalAttributesExtractor
     extends ElasticsearchTransportExperimentalAttributesExtractor {
 
   @Override
-  public void onStart(AttributesBuilder attributes, ElasticTransportRequest transportRequest) {
-    super.onStart(attributes, transportRequest);
+  public void onStart(
+      AttributesBuilder attributes,
+      Context parentContext,
+      ElasticTransportRequest transportRequest) {
+    super.onStart(attributes, parentContext, transportRequest);
 
     Object request = transportRequest.getRequest();
     if (request instanceof DocWriteRequest) {

+ 7 - 2
instrumentation/elasticsearch/elasticsearch-transport-common/library/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/ElasticsearchTransportExperimentalAttributesExtractor.java

@@ -6,6 +6,7 @@
 package io.opentelemetry.javaagent.instrumentation.elasticsearch.transport;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import javax.annotation.Nullable;
 import org.elasticsearch.action.ActionResponse;
@@ -21,7 +22,10 @@ import org.elasticsearch.action.support.replication.ReplicationResponse;
 public class ElasticsearchTransportExperimentalAttributesExtractor
     implements AttributesExtractor<ElasticTransportRequest, ActionResponse> {
   @Override
-  public void onStart(AttributesBuilder attributes, ElasticTransportRequest transportRequest) {
+  public void onStart(
+      AttributesBuilder attributes,
+      Context parentContext,
+      ElasticTransportRequest transportRequest) {
     Object request = transportRequest.getRequest();
     attributes.put("elasticsearch.action", transportRequest.getAction().getClass().getSimpleName());
     attributes.put("elasticsearch.request", request.getClass().getSimpleName());
@@ -45,8 +49,9 @@ public class ElasticsearchTransportExperimentalAttributesExtractor
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       ElasticTransportRequest request,
-      ActionResponse response,
+      @Nullable ActionResponse response,
       @Nullable Throwable error) {
     if (response instanceof GetResponse) {
       GetResponse resp = (GetResponse) response;

+ 4 - 1
instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/GrpcAttributesExtractor.java

@@ -7,19 +7,22 @@ package io.opentelemetry.instrumentation.grpc.v1_6;
 
 import io.grpc.Status;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import javax.annotation.Nullable;
 
 final class GrpcAttributesExtractor implements AttributesExtractor<GrpcRequest, Status> {
   @Override
-  public void onStart(AttributesBuilder attributes, GrpcRequest grpcRequest) {
+  public void onStart(
+      AttributesBuilder attributes, Context parentContext, GrpcRequest grpcRequest) {
     // No request attributes
   }
 
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       GrpcRequest request,
       @Nullable Status status,
       @Nullable Throwable error) {

+ 4 - 1
instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/HibernateExperimentalAttributesExtractor.java

@@ -6,6 +6,7 @@
 package io.opentelemetry.javaagent.instrumentation.hibernate;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import javax.annotation.Nullable;
 
@@ -13,7 +14,8 @@ class HibernateExperimentalAttributesExtractor
     implements AttributesExtractor<HibernateOperation, Void> {
 
   @Override
-  public void onStart(AttributesBuilder attributes, HibernateOperation hibernateOperation) {
+  public void onStart(
+      AttributesBuilder attributes, Context parentContext, HibernateOperation hibernateOperation) {
     String sessionId = hibernateOperation.getSessionId();
     if (sessionId != null) {
       attributes.put("hibernate.session_id", sessionId);
@@ -23,6 +25,7 @@ class HibernateExperimentalAttributesExtractor
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       HibernateOperation hibernateOperation,
       @Nullable Void unused,
       @Nullable Throwable error) {}

+ 4 - 1
instrumentation/hystrix-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hystrix/ExperimentalAttributesExtractor.java

@@ -10,6 +10,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey;
 
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import javax.annotation.Nullable;
 
@@ -20,7 +21,8 @@ final class ExperimentalAttributesExtractor implements AttributesExtractor<Hystr
       booleanKey("hystrix.circuit_open");
 
   @Override
-  public void onStart(AttributesBuilder attributes, HystrixRequest hystrixRequest) {
+  public void onStart(
+      AttributesBuilder attributes, Context parentContext, HystrixRequest hystrixRequest) {
     String commandName = hystrixRequest.command().getCommandKey().name();
     String groupName = hystrixRequest.command().getCommandGroup().name();
     boolean circuitOpen = hystrixRequest.command().isCircuitBreakerOpen();
@@ -33,6 +35,7 @@ final class ExperimentalAttributesExtractor implements AttributesExtractor<Hystr
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       HystrixRequest hystrixRequest,
       @Nullable Void unused,
       @Nullable Throwable error) {}

+ 4 - 1
instrumentation/jsp-2.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jsp/HttpJspPageInstrumentationSingletons.java

@@ -7,6 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.jsp;
 
 import io.opentelemetry.api.GlobalOpenTelemetry;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.config.Config;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
@@ -55,7 +56,8 @@ public class HttpJspPageInstrumentationSingletons {
       implements AttributesExtractor<HttpServletRequest, Void> {
 
     @Override
-    public void onStart(AttributesBuilder attributes, HttpServletRequest request) {
+    public void onStart(
+        AttributesBuilder attributes, Context parentContext, HttpServletRequest request) {
       if (!CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES) {
         return;
       }
@@ -81,6 +83,7 @@ public class HttpJspPageInstrumentationSingletons {
     @Override
     public void onEnd(
         AttributesBuilder attributes,
+        Context context,
         HttpServletRequest httpServletRequest,
         @Nullable Void unused,
         @Nullable Throwable error) {}

+ 5 - 1
instrumentation/jsp-2.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jsp/JspCompilationContextInstrumentationSingletons.java

@@ -7,6 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.jsp;
 
 import io.opentelemetry.api.GlobalOpenTelemetry;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.config.Config;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
@@ -46,11 +47,14 @@ public class JspCompilationContextInstrumentationSingletons {
 
     @Override
     public void onStart(
-        AttributesBuilder attributes, JspCompilationContext jspCompilationContext) {}
+        AttributesBuilder attributes,
+        Context parentContext,
+        JspCompilationContext jspCompilationContext) {}
 
     @Override
     public void onEnd(
         AttributesBuilder attributes,
+        Context context,
         JspCompilationContext jspCompilationContext,
         @Nullable Void unused,
         @Nullable Throwable error) {

+ 4 - 1
instrumentation/kafka/kafka-clients/kafka-clients-common/library/src/main/java/io/opentelemetry/instrumentation/kafka/internal/KafkaConsumerAdditionalAttributesExtractor.java

@@ -6,6 +6,7 @@
 package io.opentelemetry.instrumentation.kafka.internal;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import javax.annotation.Nullable;
@@ -18,7 +19,8 @@ import org.apache.kafka.clients.consumer.ConsumerRecord;
 public final class KafkaConsumerAdditionalAttributesExtractor
     implements AttributesExtractor<ConsumerRecord<?, ?>, Void> {
   @Override
-  public void onStart(AttributesBuilder attributes, ConsumerRecord<?, ?> consumerRecord) {
+  public void onStart(
+      AttributesBuilder attributes, Context parentContext, ConsumerRecord<?, ?> consumerRecord) {
     set(
         attributes,
         SemanticAttributes.MESSAGING_KAFKA_PARTITION,
@@ -31,6 +33,7 @@ public final class KafkaConsumerAdditionalAttributesExtractor
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       ConsumerRecord<?, ?> consumerRecord,
       @Nullable Void unused,
       @Nullable Throwable error) {}

+ 4 - 1
instrumentation/kafka/kafka-clients/kafka-clients-common/library/src/main/java/io/opentelemetry/instrumentation/kafka/internal/KafkaConsumerExperimentalAttributesExtractor.java

@@ -9,6 +9,7 @@ import static io.opentelemetry.api.common.AttributeKey.longKey;
 
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.config.Config;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import javax.annotation.Nullable;
@@ -34,7 +35,8 @@ public final class KafkaConsumerExperimentalAttributesExtractor
   }
 
   @Override
-  public void onStart(AttributesBuilder attributes, ConsumerRecord<?, ?> consumerRecord) {
+  public void onStart(
+      AttributesBuilder attributes, Context parentContext, ConsumerRecord<?, ?> consumerRecord) {
     set(attributes, KAFKA_OFFSET, consumerRecord.offset());
 
     // don't record a duration if the message was sent from an old Kafka client
@@ -52,6 +54,7 @@ public final class KafkaConsumerExperimentalAttributesExtractor
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       ConsumerRecord<?, ?> consumerRecord,
       @Nullable Void unused,
       @Nullable Throwable error) {}

+ 4 - 1
instrumentation/kafka/kafka-clients/kafka-clients-common/library/src/main/java/io/opentelemetry/instrumentation/kafka/internal/KafkaProducerAdditionalAttributesExtractor.java

@@ -6,6 +6,7 @@
 package io.opentelemetry.instrumentation.kafka.internal;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import javax.annotation.Nullable;
@@ -18,7 +19,8 @@ import org.apache.kafka.clients.producer.ProducerRecord;
 public final class KafkaProducerAdditionalAttributesExtractor
     implements AttributesExtractor<ProducerRecord<?, ?>, Void> {
   @Override
-  public void onStart(AttributesBuilder attributes, ProducerRecord<?, ?> producerRecord) {
+  public void onStart(
+      AttributesBuilder attributes, Context parentContext, ProducerRecord<?, ?> producerRecord) {
     Integer partition = producerRecord.partition();
     if (partition != null) {
       set(attributes, SemanticAttributes.MESSAGING_KAFKA_PARTITION, partition.longValue());
@@ -31,6 +33,7 @@ public final class KafkaProducerAdditionalAttributesExtractor
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       ProducerRecord<?, ?> producerRecord,
       @Nullable Void unused,
       @Nullable Throwable error) {}

+ 3 - 1
instrumentation/kubernetes-client-7.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kubernetesclient/KubernetesExperimentalAttributesExtractor.java

@@ -7,6 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.kubernetesclient;
 
 import io.kubernetes.client.openapi.ApiResponse;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import javax.annotation.Nullable;
 import okhttp3.Request;
@@ -14,7 +15,7 @@ import okhttp3.Request;
 class KubernetesExperimentalAttributesExtractor
     implements AttributesExtractor<Request, ApiResponse<?>> {
   @Override
-  public void onStart(AttributesBuilder attributes, Request request) {
+  public void onStart(AttributesBuilder attributes, Context parentContext, Request request) {
     KubernetesRequestDigest digest = KubernetesRequestDigest.parse(request);
     attributes
         .put("kubernetes-client.namespace", digest.getResourceMeta().getNamespace())
@@ -24,6 +25,7 @@ class KubernetesExperimentalAttributesExtractor
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       Request request,
       @Nullable ApiResponse<?> apiResponse,
       @Nullable Throwable error) {}

+ 7 - 2
instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceConnectAttributesExtractor.java

@@ -7,6 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.lettuce.v4_0;
 
 import com.lambdaworks.redis.RedisURI;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import javax.annotation.Nullable;
@@ -14,7 +15,7 @@ import javax.annotation.Nullable;
 final class LettuceConnectAttributesExtractor implements AttributesExtractor<RedisURI, Void> {
 
   @Override
-  public void onStart(AttributesBuilder attributes, RedisURI redisUri) {
+  public void onStart(AttributesBuilder attributes, Context parentContext, RedisURI redisUri) {
     attributes.put(SemanticAttributes.DB_SYSTEM, SemanticAttributes.DbSystemValues.REDIS);
 
     int database = redisUri.getDatabase();
@@ -25,5 +26,9 @@ final class LettuceConnectAttributesExtractor implements AttributesExtractor<Red
 
   @Override
   public void onEnd(
-      AttributesBuilder attributes, RedisURI redisUri, Void unused, @Nullable Throwable error) {}
+      AttributesBuilder attributes,
+      Context context,
+      RedisURI redisUri,
+      Void unused,
+      @Nullable Throwable error) {}
 }

+ 7 - 2
instrumentation/lettuce/lettuce-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v5_0/LettuceConnectAttributesExtractor.java

@@ -7,6 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.lettuce.v5_0;
 
 import io.lettuce.core.RedisURI;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import javax.annotation.Nullable;
@@ -14,7 +15,7 @@ import javax.annotation.Nullable;
 final class LettuceConnectAttributesExtractor implements AttributesExtractor<RedisURI, Void> {
 
   @Override
-  public void onStart(AttributesBuilder attributes, RedisURI redisUri) {
+  public void onStart(AttributesBuilder attributes, Context parentContext, RedisURI redisUri) {
     attributes.put(SemanticAttributes.DB_SYSTEM, SemanticAttributes.DbSystemValues.REDIS);
 
     int database = redisUri.getDatabase();
@@ -25,5 +26,9 @@ final class LettuceConnectAttributesExtractor implements AttributesExtractor<Red
 
   @Override
   public void onEnd(
-      AttributesBuilder attributes, RedisURI redisUri, Void unused, @Nullable Throwable error) {}
+      AttributesBuilder attributes,
+      Context context,
+      RedisURI redisUri,
+      Void unused,
+      @Nullable Throwable error) {}
 }

+ 17 - 18
instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/opentelemetry/instrumentation/lettuce/v5_1/OpenTelemetryTracing.java

@@ -155,7 +155,7 @@ final class OpenTelemetryTracing implements Tracing {
               .setSpanKind(SpanKind.CLIENT)
               .setParent(context)
               .setAttribute(SemanticAttributes.DB_SYSTEM, DbSystemValues.REDIS);
-      return new OpenTelemetrySpan(spanBuilder);
+      return new OpenTelemetrySpan(context, spanBuilder);
     }
   }
 
@@ -164,19 +164,18 @@ final class OpenTelemetryTracing implements Tracing {
   // particularly safe, synchronizing all accesses. Relying on implementation details would allow
   // reducing synchronization but the impact should be minimal.
   private static class OpenTelemetrySpan extends Tracer.Span {
+
+    private final Context context;
     private final SpanBuilder spanBuilder;
 
     @Nullable private String name;
-
     @Nullable private List<Object> events;
-
     @Nullable private Throwable error;
-
     @Nullable private Span span;
-
     @Nullable private String args;
 
-    OpenTelemetrySpan(SpanBuilder spanBuilder) {
+    OpenTelemetrySpan(Context context, SpanBuilder spanBuilder) {
+      this.context = context;
       this.spanBuilder = spanBuilder;
     }
 
@@ -194,11 +193,22 @@ final class OpenTelemetryTracing implements Tracing {
     @Override
     public synchronized Tracer.Span remoteEndpoint(Endpoint endpoint) {
       if (endpoint instanceof OpenTelemetryEndpoint) {
-        fillEndpoint(span, spanBuilder, (OpenTelemetryEndpoint) endpoint);
+        fillEndpoint((OpenTelemetryEndpoint) endpoint);
       }
       return this;
     }
 
+    private void fillEndpoint(OpenTelemetryEndpoint endpoint) {
+      AttributesBuilder attributesBuilder = Attributes.builder();
+      Context currentContext = span == null ? context : context.with(span);
+      netAttributesExtractor.onEnd(attributesBuilder, currentContext, endpoint, null, null);
+      if (span != null) {
+        span.setAllAttributes(attributesBuilder.build());
+      } else {
+        spanBuilder.setAllAttributes(attributesBuilder.build());
+      }
+    }
+
     // Added and called in 6.0+
     // @Override
     public synchronized Tracer.Span start(RedisCommand<?, ?, ?> command) {
@@ -314,15 +324,4 @@ final class OpenTelemetryTracing implements Tracing {
       span.end();
     }
   }
-
-  private static void fillEndpoint(
-      @Nullable Span span, SpanBuilder spanBuilder, OpenTelemetryEndpoint endpoint) {
-    AttributesBuilder attributesBuilder = Attributes.builder();
-    netAttributesExtractor.onEnd(attributesBuilder, endpoint, null, null);
-    if (span != null) {
-      span.setAllAttributes(attributesBuilder.build());
-    } else {
-      spanBuilder.setAllAttributes(attributesBuilder.build());
-    }
-  }
 }

+ 4 - 1
instrumentation/mongo/mongo-3.1/library/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoAttributesExtractor.java

@@ -10,6 +10,7 @@ import static java.util.Arrays.asList;
 
 import com.mongodb.event.CommandStartedEvent;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import java.util.HashSet;
 import java.util.Set;
@@ -18,13 +19,15 @@ import org.bson.BsonValue;
 
 class MongoAttributesExtractor implements AttributesExtractor<CommandStartedEvent, Void> {
   @Override
-  public void onStart(AttributesBuilder attributes, CommandStartedEvent event) {
+  public void onStart(
+      AttributesBuilder attributes, Context parentContext, CommandStartedEvent event) {
     set(attributes, DB_MONGODB_COLLECTION, collectionName(event));
   }
 
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       CommandStartedEvent event,
       @Nullable Void unused,
       @Nullable Throwable error) {}

+ 4 - 1
instrumentation/rabbitmq-2.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rabbitmq/RabbitDeliveryExperimentalAttributesExtractor.java

@@ -9,6 +9,7 @@ import static io.opentelemetry.javaagent.instrumentation.rabbitmq.RabbitInstrume
 
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import java.util.Date;
 import javax.annotation.Nullable;
@@ -19,7 +20,8 @@ class RabbitDeliveryExperimentalAttributesExtractor
       AttributeKey.longKey("rabbitmq.record.queue_time_ms");
 
   @Override
-  public void onStart(AttributesBuilder attributes, DeliveryRequest request) {
+  public void onStart(
+      AttributesBuilder attributes, Context parentContext, DeliveryRequest request) {
     Date timestamp = request.getProperties().getTimestamp();
     if (timestamp != null) {
       // this will be set if the sender sets the timestamp,
@@ -37,6 +39,7 @@ class RabbitDeliveryExperimentalAttributesExtractor
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       DeliveryRequest request,
       @Nullable Void unused,
       @Nullable Throwable error) {}

+ 4 - 1
instrumentation/rabbitmq-2.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rabbitmq/RabbitDeliveryExtraAttributesExtractor.java

@@ -7,6 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.rabbitmq;
 
 import com.rabbitmq.client.Envelope;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import javax.annotation.Nullable;
@@ -14,7 +15,8 @@ import javax.annotation.Nullable;
 class RabbitDeliveryExtraAttributesExtractor implements AttributesExtractor<DeliveryRequest, Void> {
 
   @Override
-  public void onStart(AttributesBuilder attributes, DeliveryRequest request) {
+  public void onStart(
+      AttributesBuilder attributes, Context parentContext, DeliveryRequest request) {
     Envelope envelope = request.getEnvelope();
     String routingKey = envelope.getRoutingKey();
     if (routingKey != null && !routingKey.isEmpty()) {
@@ -25,6 +27,7 @@ class RabbitDeliveryExtraAttributesExtractor implements AttributesExtractor<Deli
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       DeliveryRequest request,
       @Nullable Void unused,
       @Nullable Throwable error) {}

+ 4 - 1
instrumentation/rabbitmq-2.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rabbitmq/RabbitReceiveExperimentalAttributesExtractor.java

@@ -10,6 +10,7 @@ import static io.opentelemetry.javaagent.instrumentation.rabbitmq.RabbitInstrume
 import com.rabbitmq.client.GetResponse;
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import javax.annotation.Nullable;
 
@@ -19,7 +20,8 @@ class RabbitReceiveExperimentalAttributesExtractor
       AttributeKey.stringKey("rabbitmq.queue");
 
   @Override
-  public void onStart(AttributesBuilder attributes, ReceiveRequest receiveRequest) {
+  public void onStart(
+      AttributesBuilder attributes, Context parentContext, ReceiveRequest receiveRequest) {
     set(attributes, RABBITMQ_COMMAND, "basic.get");
     set(attributes, RABBITMQ_QUEUE, receiveRequest.getQueue());
   }
@@ -27,6 +29,7 @@ class RabbitReceiveExperimentalAttributesExtractor
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       ReceiveRequest receiveRequest,
       @Nullable GetResponse response,
       @Nullable Throwable error) {}

+ 3 - 1
instrumentation/rocketmq-client-4.8/library/src/main/java/io/opentelemetry/instrumentation/rocketmq/RockerMqConsumerExperimentalAttributeExtractor.java

@@ -7,6 +7,7 @@ package io.opentelemetry.instrumentation.rocketmq;
 
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import javax.annotation.Nullable;
 import org.apache.rocketmq.common.message.MessageExt;
@@ -23,7 +24,7 @@ class RockerMqConsumerExperimentalAttributeExtractor
       AttributeKey.stringKey("messaging.rocketmq.broker_address");
 
   @Override
-  public void onStart(AttributesBuilder attributes, MessageExt msg) {
+  public void onStart(AttributesBuilder attributes, Context parentContext, MessageExt msg) {
     set(attributes, MESSAGING_ROCKETMQ_TAGS, msg.getTags());
     set(attributes, MESSAGING_ROCKETMQ_QUEUE_ID, (long) msg.getQueueId());
     set(attributes, MESSAGING_ROCKETMQ_QUEUE_OFFSET, msg.getQueueOffset());
@@ -42,6 +43,7 @@ class RockerMqConsumerExperimentalAttributeExtractor
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       MessageExt consumeMessageContext,
       @Nullable Void unused,
       @Nullable Throwable error) {}

+ 4 - 1
instrumentation/rocketmq-client-4.8/library/src/main/java/io/opentelemetry/instrumentation/rocketmq/RockerMqProducerExperimentalAttributeExtractor.java

@@ -7,6 +7,7 @@ package io.opentelemetry.instrumentation.rocketmq;
 
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import javax.annotation.Nullable;
 import org.apache.rocketmq.client.hook.SendMessageContext;
@@ -21,7 +22,8 @@ class RockerMqProducerExperimentalAttributeExtractor
       AttributeKey.stringKey("messaging.rocketmq.send_result");
 
   @Override
-  public void onStart(AttributesBuilder attributes, SendMessageContext request) {
+  public void onStart(
+      AttributesBuilder attributes, Context parentContext, SendMessageContext request) {
     if (request.getMessage() != null) {
       set(attributes, MESSAGING_ROCKETMQ_TAGS, request.getMessage().getTags());
     }
@@ -31,6 +33,7 @@ class RockerMqProducerExperimentalAttributeExtractor
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       SendMessageContext request,
       @Nullable Void unused,
       @Nullable Throwable error) {

+ 5 - 1
instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/ServletAdditionalAttributesExtractor.java

@@ -9,6 +9,7 @@ import static io.opentelemetry.api.common.AttributeKey.longKey;
 
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.config.Config;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
@@ -30,11 +31,14 @@ public class ServletAdditionalAttributesExtractor<REQUEST, RESPONSE>
 
   @Override
   public void onStart(
-      AttributesBuilder attributes, ServletRequestContext<REQUEST> requestContext) {}
+      AttributesBuilder attributes,
+      Context parentContext,
+      ServletRequestContext<REQUEST> requestContext) {}
 
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       ServletRequestContext<REQUEST> requestContext,
       @Nullable ServletResponseContext<RESPONSE> responseContext,
       @Nullable Throwable error) {

+ 5 - 1
instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/ServletRequestParametersExtractor.java

@@ -9,6 +9,7 @@ import static java.util.Collections.emptyList;
 
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.config.Config;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import java.util.List;
@@ -51,11 +52,14 @@ public class ServletRequestParametersExtractor<REQUEST, RESPONSE>
 
   @Override
   public void onStart(
-      AttributesBuilder attributes, ServletRequestContext<REQUEST> requestContext) {}
+      AttributesBuilder attributes,
+      Context parentContext,
+      ServletRequestContext<REQUEST> requestContext) {}
 
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       ServletRequestContext<REQUEST> requestContext,
       @Nullable ServletResponseContext<RESPONSE> responseContext,
       @Nullable Throwable error) {

+ 3 - 1
instrumentation/spring/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/server/ExperimentalAttributesExtractor.java

@@ -7,6 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.spring.webflux.server;
 
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import javax.annotation.Nullable;
 import org.springframework.web.method.HandlerMethod;
@@ -17,13 +18,14 @@ public class ExperimentalAttributesExtractor implements AttributesExtractor<Obje
       AttributeKey.stringKey("spring-webflux.handler.type");
 
   @Override
-  public void onStart(AttributesBuilder attributes, Object handler) {
+  public void onStart(AttributesBuilder attributes, Context parentContext, Object handler) {
     attributes.put(HANDLER_TYPE, getHandlerType(handler));
   }
 
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       Object handler,
       @Nullable Void unused,
       @Nullable Throwable error) {}

+ 3 - 1
instrumentation/spring/spring-webflux-5.0/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/client/SpringWebfluxExperimentalAttributesExtractor.java

@@ -9,6 +9,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey;
 
 import io.opentelemetry.api.common.AttributeKey;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.config.Config;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import javax.annotation.Nullable;
@@ -29,11 +30,12 @@ final class SpringWebfluxExperimentalAttributesExtractor
   }
 
   @Override
-  public void onStart(AttributesBuilder attributes, ClientRequest request) {}
+  public void onStart(AttributesBuilder attributes, Context parentContext, ClientRequest request) {}
 
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       ClientRequest request,
       @Nullable ClientResponse response,
       @Nullable Throwable error) {

+ 4 - 1
instrumentation/spring/spring-webmvc-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springwebmvc/ModelAndViewAttributesExtractor.java

@@ -6,6 +6,7 @@
 package io.opentelemetry.javaagent.instrumentation.springwebmvc;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.config.Config;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.instrumentation.api.instrumenter.ClassNames;
@@ -20,7 +21,8 @@ public class ModelAndViewAttributesExtractor implements AttributesExtractor<Mode
           .getBoolean("otel.instrumentation.spring-webmvc.experimental-span-attributes", false);
 
   @Override
-  public void onStart(AttributesBuilder attributes, ModelAndView modelAndView) {
+  public void onStart(
+      AttributesBuilder attributes, Context parentContext, ModelAndView modelAndView) {
     if (CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES) {
       attributes.put("spring-webmvc.view.name", modelAndView.getViewName());
       View view = modelAndView.getView();
@@ -33,6 +35,7 @@ public class ModelAndViewAttributesExtractor implements AttributesExtractor<Mode
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       ModelAndView modelAndView,
       @Nullable Void unused,
       @Nullable Throwable error) {}

+ 4 - 1
instrumentation/spring/spring-webmvc-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/webmvc/StatusCodeExtractor.java

@@ -6,6 +6,7 @@
 package io.opentelemetry.instrumentation.spring.webmvc;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import javax.annotation.Nullable;
@@ -16,11 +17,13 @@ final class StatusCodeExtractor
     implements AttributesExtractor<HttpServletRequest, HttpServletResponse> {
 
   @Override
-  public void onStart(AttributesBuilder attributes, HttpServletRequest httpServletRequest) {}
+  public void onStart(
+      AttributesBuilder attributes, Context parentContext, HttpServletRequest httpServletRequest) {}
 
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       HttpServletRequest httpServletRequest,
       @Nullable HttpServletResponse response,
       @Nullable Throwable error) {

+ 3 - 1
instrumentation/tomcat/tomcat-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/tomcat/common/TomcatAdditionalAttributesExtractor.java

@@ -6,6 +6,7 @@
 package io.opentelemetry.javaagent.instrumentation.tomcat.common;
 
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import io.opentelemetry.javaagent.instrumentation.servlet.ServletAccessor;
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
@@ -27,11 +28,12 @@ public class TomcatAdditionalAttributesExtractor<REQUEST, RESPONSE>
   }
 
   @Override
-  public void onStart(AttributesBuilder attributes, Request request) {}
+  public void onStart(AttributesBuilder attributes, Context parentContext, Request request) {}
 
   @Override
   public void onEnd(
       AttributesBuilder attributes,
+      Context context,
       Request request,
       @Nullable Response response,
       @Nullable Throwable error) {

+ 7 - 2
instrumentation/twilio-6.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/twilio/TwilioExperimentalAttributesExtractor.java

@@ -10,6 +10,7 @@ import com.google.common.util.concurrent.Uninterruptibles;
 import com.twilio.rest.api.v2010.account.Call;
 import com.twilio.rest.api.v2010.account.Message;
 import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
 import java.lang.reflect.Method;
 import java.util.concurrent.TimeUnit;
@@ -23,11 +24,15 @@ class TwilioExperimentalAttributesExtractor implements AttributesExtractor<Strin
       LoggerFactory.getLogger(TwilioExperimentalAttributesExtractor.class);
 
   @Override
-  public void onStart(AttributesBuilder attributes, String s) {}
+  public void onStart(AttributesBuilder attributes, Context parentContext, String s) {}
 
   @Override
   public void onEnd(
-      AttributesBuilder attributes, String s, @Nullable Object result, @Nullable Throwable error) {
+      AttributesBuilder attributes,
+      Context context,
+      String s,
+      @Nullable Object result,
+      @Nullable Throwable error) {
     if (result == null) {
       return;
     }