Browse Source

Add peer service support back to couchbase26 (#5451)

* Add peer service support back to couchbase26

* extract common module

* move tests

* fix tests

* address review comments

* remove CouchbaseRequestInfoHolder
Lauri Tulmin 3 years ago
parent
commit
e6a8bdf697
20 changed files with 262 additions and 130 deletions
  1. 1 1
      instrumentation/couchbase/couchbase-2-common/javaagent-unit-tests/build.gradle.kts
  2. 0 0
      instrumentation/couchbase/couchbase-2-common/javaagent-unit-tests/src/test/groovy/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseQuerySanitizerTest.groovy
  3. 8 0
      instrumentation/couchbase/couchbase-2-common/javaagent/build.gradle.kts
  4. 0 0
      instrumentation/couchbase/couchbase-2-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseQuerySanitizer.java
  5. 114 0
      instrumentation/couchbase/couchbase-2-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseRequestInfo.java
  6. 1 3
      instrumentation/couchbase/couchbase-2.0/javaagent/build.gradle.kts
  7. 7 7
      instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseAttributesExtractor.java
  8. 5 4
      instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseBucketInstrumentation.java
  9. 1 1
      instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseClusterInstrumentation.java
  10. 39 0
      instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseNetAttributesGetter.java
  11. 0 57
      instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseRequest.java
  12. 24 6
      instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseSingletons.java
  13. 4 4
      instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseSpanNameExtractor.java
  14. 30 0
      instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/ExperimentalAttributesExtractor.java
  15. 1 0
      instrumentation/couchbase/couchbase-2.6/javaagent/build.gradle.kts
  16. 0 16
      instrumentation/couchbase/couchbase-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_6/CouchbaseConfig.java
  17. 15 16
      instrumentation/couchbase/couchbase-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_6/CouchbaseCoreInstrumentation.java
  18. 8 14
      instrumentation/couchbase/couchbase-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_6/CouchbaseNetworkInstrumentation.java
  19. 2 0
      instrumentation/couchbase/couchbase-2.6/javaagent/src/test/groovy/CouchbaseSpanUtil.groovy
  20. 2 1
      settings.gradle.kts

+ 1 - 1
instrumentation/couchbase/couchbase-2.0/javaagent-unit-tests/build.gradle.kts → instrumentation/couchbase/couchbase-2-common/javaagent-unit-tests/build.gradle.kts

@@ -7,6 +7,6 @@ dependencies {
   testImplementation("org.spockframework:spock-core")
 
   testImplementation(project(":instrumentation-api"))
-  testImplementation(project(":instrumentation:couchbase:couchbase-2.0:javaagent"))
+  testImplementation(project(":instrumentation:couchbase:couchbase-2-common:javaagent"))
   testImplementation("com.couchbase.client:java-client:2.5.0")
 }

+ 0 - 0
instrumentation/couchbase/couchbase-2.0/javaagent-unit-tests/src/test/groovy/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseQuerySanitizerTest.groovy → instrumentation/couchbase/couchbase-2-common/javaagent-unit-tests/src/test/groovy/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseQuerySanitizerTest.groovy


+ 8 - 0
instrumentation/couchbase/couchbase-2-common/javaagent/build.gradle.kts

@@ -0,0 +1,8 @@
+plugins {
+  id("otel.javaagent-instrumentation")
+}
+
+dependencies {
+  compileOnly("com.google.auto.value:auto-value-annotations")
+  annotationProcessor("com.google.auto.value:auto-value")
+}

+ 0 - 0
instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseQuerySanitizer.java → instrumentation/couchbase/couchbase-2-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseQuerySanitizer.java


+ 114 - 0
instrumentation/couchbase/couchbase-2-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseRequestInfo.java

@@ -0,0 +1,114 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.javaagent.instrumentation.couchbase.v2_0;
+
+import static io.opentelemetry.context.ContextKey.named;
+
+import com.google.auto.value.AutoValue;
+import io.opentelemetry.context.Context;
+import io.opentelemetry.context.ContextKey;
+import io.opentelemetry.instrumentation.api.db.SqlStatementInfo;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.annotation.Nullable;
+
+@AutoValue
+public abstract class CouchbaseRequestInfo {
+
+  private static final ContextKey<CouchbaseRequestInfo> KEY =
+      named("opentelemetry-couchbase-request-key");
+
+  private static final ClassValue<Map<String, String>> methodOperationNames =
+      new ClassValue<Map<String, String>>() {
+        @Override
+        protected Map<String, String> computeValue(Class<?> type) {
+          return new ConcurrentHashMap<>();
+        }
+      };
+
+  private String peerName;
+  private Integer peerPort;
+  private String localAddress;
+  private String operationId;
+
+  public static CouchbaseRequestInfo create(
+      @Nullable String bucket, Class<?> declaringClass, String methodName) {
+    String operation =
+        methodOperationNames
+            .get(declaringClass)
+            .computeIfAbsent(methodName, m -> computeOperation(declaringClass, m));
+    return new AutoValue_CouchbaseRequestInfo(bucket, null, operation, true);
+  }
+
+  public static CouchbaseRequestInfo create(@Nullable String bucket, Object query) {
+    SqlStatementInfo statement = CouchbaseQuerySanitizer.sanitize(query);
+
+    return new AutoValue_CouchbaseRequestInfo(
+        bucket, statement.getFullStatement(), statement.getOperation(), false);
+  }
+
+  private static String computeOperation(Class<?> declaringClass, String methodName) {
+    String className =
+        declaringClass.getSimpleName().replace("CouchbaseAsync", "").replace("DefaultAsync", "");
+    return className + "." + methodName;
+  }
+
+  public static Context init(Context context, CouchbaseRequestInfo couchbaseRequest) {
+    return context.with(KEY, couchbaseRequest);
+  }
+
+  @Nullable
+  public static CouchbaseRequestInfo get(Context context) {
+    return context.get(KEY);
+  }
+
+  @Nullable
+  public abstract String bucket();
+
+  @Nullable
+  public abstract String statement();
+
+  @Nullable
+  public abstract String operation();
+
+  public abstract boolean isMethodCall();
+
+  @Nullable
+  public String getPeerName() {
+    return peerName;
+  }
+
+  public void setPeerName(String peerName) {
+    this.peerName = peerName;
+  }
+
+  @Nullable
+  public Integer getPeerPort() {
+    return peerPort;
+  }
+
+  public void setPeerPort(Integer peerPort) {
+    this.peerPort = peerPort;
+  }
+
+  @Nullable
+  public String getLocalAddress() {
+    return localAddress;
+  }
+
+  public void setLocalAddress(String localAddress) {
+    this.localAddress = localAddress;
+  }
+
+  @Nullable
+  public String getOperationId() {
+    return operationId;
+  }
+
+  public void setOperationId(String operationId) {
+    this.operationId = operationId;
+  }
+}

+ 1 - 3
instrumentation/couchbase/couchbase-2.0/javaagent/build.gradle.kts

@@ -28,9 +28,7 @@ muzzle {
 }
 
 dependencies {
-  compileOnly("com.google.auto.value:auto-value-annotations")
-  annotationProcessor("com.google.auto.value:auto-value")
-
+  implementation(project(":instrumentation:couchbase:couchbase-2-common:javaagent"))
   implementation(project(":instrumentation:rxjava:rxjava-1.0:library"))
 
   library("com.couchbase.client:java-client:2.0.0")

+ 7 - 7
instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseAttributesExtractor.java

@@ -9,39 +9,39 @@ import io.opentelemetry.instrumentation.api.instrumenter.db.DbAttributesExtracto
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
 import javax.annotation.Nullable;
 
-final class CouchbaseAttributesExtractor extends DbAttributesExtractor<CouchbaseRequest, Void> {
+final class CouchbaseAttributesExtractor extends DbAttributesExtractor<CouchbaseRequestInfo, Void> {
   @Override
-  protected String system(CouchbaseRequest couchbaseRequest) {
+  protected String system(CouchbaseRequestInfo couchbaseRequest) {
     return SemanticAttributes.DbSystemValues.COUCHBASE;
   }
 
   @Override
   @Nullable
-  protected String user(CouchbaseRequest couchbaseRequest) {
+  protected String user(CouchbaseRequestInfo couchbaseRequest) {
     return null;
   }
 
   @Override
   @Nullable
-  protected String name(CouchbaseRequest couchbaseRequest) {
+  protected String name(CouchbaseRequestInfo couchbaseRequest) {
     return couchbaseRequest.bucket();
   }
 
   @Override
   @Nullable
-  protected String connectionString(CouchbaseRequest couchbaseRequest) {
+  protected String connectionString(CouchbaseRequestInfo couchbaseRequest) {
     return null;
   }
 
   @Override
   @Nullable
-  protected String statement(CouchbaseRequest couchbaseRequest) {
+  protected String statement(CouchbaseRequestInfo couchbaseRequest) {
     return couchbaseRequest.statement();
   }
 
   @Override
   @Nullable
-  protected String operation(CouchbaseRequest couchbaseRequest) {
+  protected String operation(CouchbaseRequestInfo couchbaseRequest) {
     return couchbaseRequest.operation();
   }
 }

+ 5 - 4
instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseBucketInstrumentation.java

@@ -61,7 +61,8 @@ public class CouchbaseBucketInstrumentation implements TypeInstrumentation {
       if (callDepth.decrementAndGet() > 0) {
         return;
       }
-      CouchbaseRequest request = CouchbaseRequest.create(bucket, declaringClass, methodName);
+      CouchbaseRequestInfo request =
+          CouchbaseRequestInfo.create(bucket, declaringClass, methodName);
       result = Observable.create(new TracedOnSubscribe<>(result, instrumenter(), request));
     }
   }
@@ -87,10 +88,10 @@ public class CouchbaseBucketInstrumentation implements TypeInstrumentation {
         return;
       }
 
-      CouchbaseRequest request =
+      CouchbaseRequestInfo request =
           query == null
-              ? CouchbaseRequest.create(bucket, declaringClass, methodName)
-              : CouchbaseRequest.create(bucket, query);
+              ? CouchbaseRequestInfo.create(bucket, declaringClass, methodName)
+              : CouchbaseRequestInfo.create(bucket, query);
       result = Observable.create(new TracedOnSubscribe<>(result, instrumenter(), request));
     }
   }

+ 1 - 1
instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseClusterInstrumentation.java

@@ -58,7 +58,7 @@ public class CouchbaseClusterInstrumentation implements TypeInstrumentation {
         return;
       }
 
-      CouchbaseRequest request = CouchbaseRequest.create(null, declaringClass, methodName);
+      CouchbaseRequestInfo request = CouchbaseRequestInfo.create(null, declaringClass, methodName);
       result = Observable.create(new TracedOnSubscribe<>(result, instrumenter(), request));
     }
   }

+ 39 - 0
instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseNetAttributesGetter.java

@@ -0,0 +1,39 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.javaagent.instrumentation.couchbase.v2_0;
+
+import io.opentelemetry.instrumentation.api.instrumenter.net.NetClientAttributesGetter;
+import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
+import javax.annotation.Nullable;
+
+public class CouchbaseNetAttributesGetter
+    implements NetClientAttributesGetter<CouchbaseRequestInfo, Void> {
+  @Nullable
+  @Override
+  public String transport(CouchbaseRequestInfo couchbaseRequest, @Nullable Void unused) {
+    return couchbaseRequest.getPeerName() != null
+        ? SemanticAttributes.NetTransportValues.IP_TCP
+        : null;
+  }
+
+  @Nullable
+  @Override
+  public String peerName(CouchbaseRequestInfo couchbaseRequest, @Nullable Void unused) {
+    return couchbaseRequest.getPeerName();
+  }
+
+  @Nullable
+  @Override
+  public Integer peerPort(CouchbaseRequestInfo couchbaseRequest, @Nullable Void unused) {
+    return couchbaseRequest.getPeerPort();
+  }
+
+  @Nullable
+  @Override
+  public String peerIp(CouchbaseRequestInfo couchbaseRequest, @Nullable Void unused) {
+    return null;
+  }
+}

+ 0 - 57
instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseRequest.java

@@ -1,57 +0,0 @@
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package io.opentelemetry.javaagent.instrumentation.couchbase.v2_0;
-
-import com.google.auto.value.AutoValue;
-import io.opentelemetry.instrumentation.api.db.SqlStatementInfo;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import javax.annotation.Nullable;
-
-@AutoValue
-public abstract class CouchbaseRequest {
-
-  private static final ClassValue<Map<String, String>> methodOperationNames =
-      new ClassValue<Map<String, String>>() {
-        @Override
-        protected Map<String, String> computeValue(Class<?> type) {
-          return new ConcurrentHashMap<>();
-        }
-      };
-
-  public static CouchbaseRequest create(
-      @Nullable String bucket, Class<?> declaringClass, String methodName) {
-    String operation =
-        methodOperationNames
-            .get(declaringClass)
-            .computeIfAbsent(methodName, m -> computeOperation(declaringClass, m));
-    return new AutoValue_CouchbaseRequest(bucket, null, operation, true);
-  }
-
-  public static CouchbaseRequest create(@Nullable String bucket, Object query) {
-    SqlStatementInfo statement = CouchbaseQuerySanitizer.sanitize(query);
-
-    return new AutoValue_CouchbaseRequest(
-        bucket, statement.getFullStatement(), statement.getOperation(), false);
-  }
-
-  private static String computeOperation(Class<?> declaringClass, String methodName) {
-    String className =
-        declaringClass.getSimpleName().replace("CouchbaseAsync", "").replace("DefaultAsync", "");
-    return className + "." + methodName;
-  }
-
-  @Nullable
-  public abstract String bucket();
-
-  @Nullable
-  public abstract String statement();
-
-  @Nullable
-  public abstract String operation();
-
-  public abstract boolean isMethodCall();
-}

+ 24 - 6
instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseSingletons.java

@@ -6,30 +6,48 @@
 package io.opentelemetry.javaagent.instrumentation.couchbase.v2_0;
 
 import io.opentelemetry.api.GlobalOpenTelemetry;
+import io.opentelemetry.instrumentation.api.config.Config;
 import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
+import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
+import io.opentelemetry.instrumentation.api.instrumenter.PeerServiceAttributesExtractor;
 import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
 import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
 import io.opentelemetry.instrumentation.api.instrumenter.db.DbSpanNameExtractor;
+import io.opentelemetry.instrumentation.api.instrumenter.net.NetClientAttributesExtractor;
 
 public final class CouchbaseSingletons {
 
   private static final String INSTRUMENTATION_NAME = "io.opentelemetry.couchbase-2.0";
 
-  private static final Instrumenter<CouchbaseRequest, Void> INSTRUMENTER;
+  private static final Instrumenter<CouchbaseRequestInfo, Void> INSTRUMENTER;
 
   static {
     CouchbaseAttributesExtractor couchbaseAttributesExtractor = new CouchbaseAttributesExtractor();
-    SpanNameExtractor<CouchbaseRequest> spanNameExtractor =
+    SpanNameExtractor<CouchbaseRequestInfo> spanNameExtractor =
         new CouchbaseSpanNameExtractor(DbSpanNameExtractor.create(couchbaseAttributesExtractor));
+    CouchbaseNetAttributesGetter netAttributesGetter = new CouchbaseNetAttributesGetter();
+    NetClientAttributesExtractor<CouchbaseRequestInfo, Void> netClientAttributesExtractor =
+        NetClientAttributesExtractor.create(netAttributesGetter);
 
-    INSTRUMENTER =
-        Instrumenter.<CouchbaseRequest, Void>builder(
+    InstrumenterBuilder<CouchbaseRequestInfo, Void> builder =
+        Instrumenter.<CouchbaseRequestInfo, Void>builder(
                 GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME, spanNameExtractor)
             .addAttributesExtractor(couchbaseAttributesExtractor)
-            .newInstrumenter(SpanKindExtractor.alwaysClient());
+            .addAttributesExtractor(netClientAttributesExtractor)
+            .addAttributesExtractor(PeerServiceAttributesExtractor.create(netAttributesGetter))
+            .addContextCustomizer(
+                (context, couchbaseRequest, startAttributes) ->
+                    CouchbaseRequestInfo.init(context, couchbaseRequest));
+
+    if (Config.get()
+        .getBoolean("otel.instrumentation.couchbase.experimental-span-attributes", false)) {
+      builder.addAttributesExtractor(new ExperimentalAttributesExtractor());
+    }
+
+    INSTRUMENTER = builder.newInstrumenter(SpanKindExtractor.alwaysClient());
   }
 
-  public static Instrumenter<CouchbaseRequest, Void> instrumenter() {
+  public static Instrumenter<CouchbaseRequestInfo, Void> instrumenter() {
     return INSTRUMENTER;
   }
 

+ 4 - 4
instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseSpanNameExtractor.java

@@ -7,15 +7,15 @@ package io.opentelemetry.javaagent.instrumentation.couchbase.v2_0;
 
 import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
 
-public class CouchbaseSpanNameExtractor implements SpanNameExtractor<CouchbaseRequest> {
-  private final SpanNameExtractor<CouchbaseRequest> dbSpanNameExtractor;
+public class CouchbaseSpanNameExtractor implements SpanNameExtractor<CouchbaseRequestInfo> {
+  private final SpanNameExtractor<CouchbaseRequestInfo> dbSpanNameExtractor;
 
-  public CouchbaseSpanNameExtractor(SpanNameExtractor<CouchbaseRequest> dbSpanNameExtractor) {
+  public CouchbaseSpanNameExtractor(SpanNameExtractor<CouchbaseRequestInfo> dbSpanNameExtractor) {
     this.dbSpanNameExtractor = dbSpanNameExtractor;
   }
 
   @Override
-  public String extract(CouchbaseRequest couchbaseRequest) {
+  public String extract(CouchbaseRequestInfo couchbaseRequest) {
     if (couchbaseRequest.isMethodCall()) {
       return couchbaseRequest.operation();
     }

+ 30 - 0
instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/ExperimentalAttributesExtractor.java

@@ -0,0 +1,30 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.javaagent.instrumentation.couchbase.v2_0;
+
+import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
+import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
+import javax.annotation.Nullable;
+
+public class ExperimentalAttributesExtractor
+    implements AttributesExtractor<CouchbaseRequestInfo, Void> {
+
+  @Override
+  public void onStart(
+      AttributesBuilder attributes, Context parentContext, CouchbaseRequestInfo request) {}
+
+  @Override
+  public void onEnd(
+      AttributesBuilder attributes,
+      Context context,
+      CouchbaseRequestInfo request,
+      @Nullable Void response,
+      @Nullable Throwable error) {
+    attributes.put("couchbase.operation_id", request.getOperationId());
+    attributes.put("couchbase.local.address", request.getLocalAddress());
+  }
+}

+ 1 - 0
instrumentation/couchbase/couchbase-2.6/javaagent/build.gradle.kts

@@ -20,6 +20,7 @@ muzzle {
 
 dependencies {
   implementation(project(":instrumentation:rxjava:rxjava-1.0:library"))
+  implementation(project(":instrumentation:couchbase:couchbase-2-common:javaagent"))
 
   library("com.couchbase.client:java-client:2.6.0")
 

+ 0 - 16
instrumentation/couchbase/couchbase-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_6/CouchbaseConfig.java

@@ -1,16 +0,0 @@
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package io.opentelemetry.javaagent.instrumentation.couchbase.v2_6;
-
-import io.opentelemetry.instrumentation.api.config.Config;
-
-public final class CouchbaseConfig {
-
-  public static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
-      Config.get().getBoolean("otel.instrumentation.couchbase.experimental-span-attributes", false);
-
-  private CouchbaseConfig() {}
-}

+ 15 - 16
instrumentation/couchbase/couchbase-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_6/CouchbaseCoreInstrumentation.java

@@ -11,11 +11,12 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
 import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
 
 import com.couchbase.client.core.message.CouchbaseRequest;
-import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.context.Context;
 import io.opentelemetry.instrumentation.api.field.VirtualField;
 import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
 import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
 import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
+import io.opentelemetry.javaagent.instrumentation.couchbase.v2_0.CouchbaseRequestInfo;
 import net.bytebuddy.asm.Advice;
 import net.bytebuddy.description.type.TypeDescription;
 import net.bytebuddy.matcher.ElementMatcher;
@@ -43,23 +44,21 @@ public class CouchbaseCoreInstrumentation implements TypeInstrumentation {
     @Advice.OnMethodExit(suppress = Throwable.class)
     public static void addOperationIdToSpan(@Advice.Argument(0) CouchbaseRequest request) {
 
-      Span parentSpan = Java8BytecodeBridge.currentSpan();
-      if (parentSpan != null) {
-        // The scope from the initial rxJava subscribe is not available to the networking layer
-        // To transfer the span, the span is added to the context store
-
-        VirtualField<CouchbaseRequest, Span> virtualField =
-            VirtualField.find(CouchbaseRequest.class, Span.class);
+      VirtualField<CouchbaseRequest, CouchbaseRequestInfo> virtualField =
+          VirtualField.find(CouchbaseRequest.class, CouchbaseRequestInfo.class);
+      CouchbaseRequestInfo requestInfo = virtualField.get(request);
+      if (requestInfo != null) {
+        return;
+      }
 
-        Span span = virtualField.get(request);
+      Context currentContext = Java8BytecodeBridge.currentContext();
+      requestInfo = CouchbaseRequestInfo.get(currentContext);
+      if (requestInfo != null) {
+        // The scope from the initial rxJava subscribe is not available to the networking layer
+        // To transfer the request info it is added to the context store
+        virtualField.set(request, requestInfo);
 
-        if (span == null) {
-          span = parentSpan;
-          virtualField.set(request, span);
-          if (CouchbaseConfig.CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES) {
-            span.setAttribute("couchbase.operation_id", request.operationId());
-          }
-        }
+        requestInfo.setOperationId(request.operationId());
       }
     }
   }

+ 8 - 14
instrumentation/couchbase/couchbase-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_6/CouchbaseNetworkInstrumentation.java

@@ -14,11 +14,10 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
 import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
 
 import com.couchbase.client.core.message.CouchbaseRequest;
-import io.opentelemetry.api.trace.Span;
 import io.opentelemetry.instrumentation.api.field.VirtualField;
 import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
 import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
-import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
+import io.opentelemetry.javaagent.instrumentation.couchbase.v2_0.CouchbaseRequestInfo;
 import java.util.List;
 import net.bytebuddy.asm.Advice;
 import net.bytebuddy.description.type.TypeDescription;
@@ -61,28 +60,23 @@ public class CouchbaseNetworkInstrumentation implements TypeInstrumentation {
         @Advice.FieldValue("remoteSocket") String remoteSocket,
         @Advice.FieldValue("localSocket") String localSocket,
         @Advice.Argument(1) CouchbaseRequest request) {
-      VirtualField<CouchbaseRequest, Span> virtualField =
-          VirtualField.find(CouchbaseRequest.class, Span.class);
+      VirtualField<CouchbaseRequest, CouchbaseRequestInfo> virtualField =
+          VirtualField.find(CouchbaseRequest.class, CouchbaseRequestInfo.class);
 
-      // TODO add support for peer service name
-      Span span = virtualField.get(request);
-      if (span != null) {
+      CouchbaseRequestInfo requestInfo = virtualField.get(request);
+      if (requestInfo != null) {
         if (remoteHostname != null) {
-          span.setAttribute(SemanticAttributes.NET_PEER_NAME, remoteHostname);
+          requestInfo.setPeerName(remoteHostname);
         }
 
         if (remoteSocket != null) {
           int splitIndex = remoteSocket.lastIndexOf(":");
           if (splitIndex != -1) {
-            span.setAttribute(
-                SemanticAttributes.NET_PEER_PORT,
-                (long) Integer.parseInt(remoteSocket.substring(splitIndex + 1)));
+            requestInfo.setPeerPort(Integer.parseInt(remoteSocket.substring(splitIndex + 1)));
           }
         }
 
-        if (CouchbaseConfig.CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES) {
-          span.setAttribute("couchbase.local.address", localSocket);
-        }
+        requestInfo.setLocalAddress(localSocket);
       }
     }
   }

+ 2 - 0
instrumentation/couchbase/couchbase-2.6/javaagent/src/test/groovy/CouchbaseSpanUtil.groovy

@@ -8,6 +8,7 @@ import io.opentelemetry.sdk.trace.data.SpanData
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
 
 import static io.opentelemetry.api.trace.SpanKind.CLIENT
+import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NetTransportValues.IP_TCP
 
 class CouchbaseSpanUtil {
   // Reusable span assertion method.  Cannot directly override AbstractCouchbaseTest.assertCouchbaseSpan because
@@ -33,6 +34,7 @@ class CouchbaseSpanUtil {
         "$SemanticAttributes.DB_STATEMENT" statement
         "$SemanticAttributes.DB_OPERATION"(operation ?: spanName)
 
+        "$SemanticAttributes.NET_TRANSPORT" { it == null || it == IP_TCP }
         // Because of caching, not all requests hit the server so these attributes may be absent
         "$SemanticAttributes.NET_PEER_NAME" { it == "localhost" || it == "127.0.0.1" || it == null }
         "$SemanticAttributes.NET_PEER_PORT" { it == null || Number }

+ 2 - 1
settings.gradle.kts

@@ -162,8 +162,9 @@ include(":instrumentation:internal:internal-reflection:javaagent-integration-tes
 include(":instrumentation:internal:internal-url-class-loader:javaagent")
 include(":instrumentation:internal:internal-url-class-loader:javaagent-integration-tests")
 include(":instrumentation:couchbase:couchbase-2.0:javaagent")
-include(":instrumentation:couchbase:couchbase-2.0:javaagent-unit-tests")
 include(":instrumentation:couchbase:couchbase-2.6:javaagent")
+include(":instrumentation:couchbase:couchbase-2-common:javaagent")
+include(":instrumentation:couchbase:couchbase-2-common:javaagent-unit-tests")
 include(":instrumentation:couchbase:couchbase-3.1:javaagent")
 include(":instrumentation:couchbase:couchbase-3.1:tracing-opentelemetry-shaded")
 include(":instrumentation:couchbase:couchbase-3.1.6:javaagent")