Skip to content

Commit

Permalink
Load couchbase otel instrumentation for 3.1 (#2524)
Browse files Browse the repository at this point in the history
* Load couchbase otel instrumentation for 3.1

* Drift
  • Loading branch information
Anuraag Agrawal authored Mar 9, 2021
1 parent 3dff448 commit 0dde62b
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apply from: "$rootDir/gradle/instrumentation.gradle"

muzzle {
pass {
group = "com.couchbase.client"
module = "java-client"
versions = "[3.1,)"
assertInverse = true
}
}

dependencies {
implementation group: "com.couchbase.client", name: "tracing-opentelemetry", version: "0.3.3"

library group: "com.couchbase.client", name: "core-io", version: "2.1.0"

testLibrary group: "com.couchbase.client", name: "java-client", version: "3.1.0"

testImplementation group: "org.testcontainers", name: "couchbase", version: versions.testcontainers
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.couchbase.v3_1;

import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
import static net.bytebuddy.matcher.ElementMatchers.named;

import com.couchbase.client.core.env.CoreEnvironment;
import com.couchbase.client.tracing.opentelemetry.OpenTelemetryRequestTracer;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Collections;
import java.util.Map;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;

public class CouchbaseEnvironmentInstrumentation implements TypeInstrumentation {

@Override
public ElementMatcher<? super TypeDescription> typeMatcher() {
return named("com.couchbase.client.core.env.CoreEnvironment$Builder");
}

@Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return Collections.singletonMap(
isConstructor(),
CouchbaseEnvironmentInstrumentation.class.getName() + "$ConstructorAdvice");
}

public static class ConstructorAdvice {
@Advice.OnMethodExit(suppress = Throwable.class)
public static void onExit(@Advice.This CoreEnvironment.Builder<?> builder) {
builder.requestTracer(
OpenTelemetryRequestTracer.wrap(
GlobalOpenTelemetry.getTracer("io.opentelemetry.javaagent.couchbase-3.0")));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.couchbase.v3_1;

import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed;

import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Collections;
import java.util.List;
import net.bytebuddy.matcher.ElementMatcher;

@AutoService(InstrumentationModule.class)
public class CouchbaseInstrumentationModule extends InstrumentationModule {
public CouchbaseInstrumentationModule() {
super("couchbase", "couchbase-3.1");
}

@Override
protected String[] additionalHelperClassNames() {
return new String[] {
"com.couchbase.client.tracing.opentelemetry.OpenTelemetryRequestSpan",
"com.couchbase.client.tracing.opentelemetry.OpenTelemetryRequestTracer"
};
}

@Override
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
// New class introduced in 3.1, the minimum version we support.
// NB: Couchbase does not provide any API guarantees on their core IO artifact so reconsider
// instrumenting it instead of each individual JVM artifact if this becomes unmaintainable.
return hasClassesNamed("com.couchbase.client.core.cnc.TracingIdentifiers");
}

@Override
public List<TypeInstrumentation> typeInstrumentations() {
return Collections.singletonList(new CouchbaseEnvironmentInstrumentation());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

import com.couchbase.client.core.error.DocumentNotFoundException
import com.couchbase.client.java.Cluster
import com.couchbase.client.java.Collection
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
import java.time.Duration
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.testcontainers.containers.output.Slf4jLogConsumer
import org.testcontainers.couchbase.BucketDefinition
import org.testcontainers.couchbase.CouchbaseContainer
import org.testcontainers.couchbase.CouchbaseService
import spock.lang.Shared

// Couchbase instrumentation is owned upstream so we don't assert on the contents of the spans, only
// that the instrumentation is properly registered by the agent, meaning some spans were generated.
class CouchbaseClient31Test extends AgentInstrumentationSpecification {
private static final Logger log = LoggerFactory.getLogger("couchbase-container")

@Shared
CouchbaseContainer couchbase
@Shared
Cluster cluster
@Shared
Collection collection

def setupSpec() {
couchbase = new CouchbaseContainer()
.withExposedPorts(8091)
.withEnabledServices(CouchbaseService.KV)
.withBucket(new BucketDefinition("test"))
.withLogConsumer(new Slf4jLogConsumer(log))
.withStartupTimeout(Duration.ofSeconds(120))
couchbase.start()

cluster = Cluster.connect(couchbase.connectionString, couchbase.username, couchbase.password)
def bucket = cluster.bucket("test")
collection = bucket.defaultCollection()
bucket.waitUntilReady(Duration.ofSeconds(10))
}

def cleanupSpec() {
couchbase.stop()
}

def "emits spans"() {
when:
try {
collection.get("id")
} catch (DocumentNotFoundException e) {
// Expected
}

then:
assertTraces(1) {
trace(0, 2) {
span(0) {
name(~/.*get/)
}
span(1) {
name("dispatch_to_server")
}
}
}

cleanup:
cluster.disconnect()
}
}
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ include ':instrumentation:classloaders:javaagent:tomcat-testing'
include ':instrumentation:couchbase:couchbase-2.0:javaagent'
include ':instrumentation:couchbase:couchbase-2.0:javaagent-unittests'
include ':instrumentation:couchbase:couchbase-2.6:javaagent'
include ':instrumentation:couchbase:couchbase-3.1:javaagent'
include ':instrumentation:couchbase:couchbase-testing'
include ':instrumentation:dropwizard-views-0.7:javaagent'
include ':instrumentation:dropwizard-testing'
Expand Down

0 comments on commit 0dde62b

Please sign in to comment.