Update geode to Instrumenter API
MODIFY
instrumentation/geode-1.4/javaagent/geode-1.4-javaagent.gradle
instrumentation/geode-1.4/javaagent/geode-1.4-javaagent.gradle
@@ -10,4 +10,7 @@ muzzle {
dependencies {
library "org.apache.geode:geode-core:1.4.0"
+
+ compileOnly deps.autoValueAnnotations
+ annotationProcessor deps.autoValue
}

ADD
instrumentation/geode-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/geode/GeodeDbAttributesExtractor.java
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.javaagent.instrumentation.geode;
+
+import io.opentelemetry.instrumentation.api.db.SqlStatementSanitizer;
+import io.opentelemetry.instrumentation.api.instrumenter.db.DbAttributesExtractor;
+import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+final class GeodeDbAttributesExtractor extends DbAttributesExtractor<GeodeRequest> {
+ @Override
+ protected String system(GeodeRequest request) {
+ return SemanticAttributes.DbSystemValues.GEODE;
+ }
+
+ @Override
+ @Nullable
+ protected String user(GeodeRequest request) {
+ return null;
+ }
+
+ @Override
+ protected String name(GeodeRequest request) {
+ return request.getRegion().getName();
+ }
+
+ @Override
+ @Nullable
+ protected String connectionString(GeodeRequest request) {
+ return null;
+ }
+
+ @Override
+ @Nullable
+ protected String statement(GeodeRequest request) {
+ // sanitized statement is cached
+ return SqlStatementSanitizer.sanitize(request.getQuery()).getFullStatement();
+ }
+
+ @Override
+ @Nullable
+ protected String operation(GeodeRequest request) {
+ return request.getOperation();
+ }
+}

MODIFY
instrumentation/geode-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/geode/GeodeInstrumentationModule.java
instrumentation/geode-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/geode/GeodeInstrumentationModule.java
@@ -7,7 +7,8 @@ package io.opentelemetry.javaagent.instrumentation.geode;
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface;
import static io.opentelemetry.javaagent.extension.matcher.ClassLoaderMatcher.hasClassesNamed;
-import static io.opentelemetry.javaagent.instrumentation.geode.GeodeTracer.tracer;
+import static io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge.currentContext;
+import static io.opentelemetry.javaagent.instrumentation.geode.GeodeInstrumenters.instrumenter;
import static java.util.Collections.singletonList;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
@@ -20,7 +21,6 @@ import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
-import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
import java.lang.reflect.Method;
import java.util.List;
import net.bytebuddy.asm.Advice;
@@ -79,67 +79,69 @@ public class GeodeInstrumentationModule extends InstrumentationModule {
public static class SimpleAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(
- @Advice.This Region<?, ?> thiz,
+ @Advice.This Region<?, ?> region,
@Advice.Origin Method method,
+ @Advice.Local("otelRequest") GeodeRequest request,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
- if (CallDepthThreadLocalMap.incrementCallDepth(Region.class) > 0) {
+
+ Context parentContext = currentContext();
+ request = GeodeRequest.create(region, method.getName(), null);
+ if (!instrumenter().shouldStart(parentContext, request)) {
return;
}
- context = tracer().startSpan(method.getName(), thiz, null);
+
+ context = instrumenter().start(parentContext, request);
scope = context.makeCurrent();
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void stopSpan(
@Advice.Thrown Throwable throwable,
+ @Advice.Local("otelRequest") GeodeRequest request,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
if (scope == null) {
return;
}
- scope.close();
- CallDepthThreadLocalMap.reset(Region.class);
- if (throwable != null) {
- tracer().endExceptionally(context, throwable);
- } else {
- tracer().end(context);
- }
+ scope.close();
+ instrumenter().end(context, request, null, throwable);
}
}
public static class QueryAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(
- @Advice.This Region<?, ?> thiz,
+ @Advice.This Region<?, ?> region,
@Advice.Origin Method method,
@Advice.Argument(0) String query,
+ @Advice.Local("otelRequest") GeodeRequest request,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
- if (CallDepthThreadLocalMap.incrementCallDepth(Region.class) > 0) {
+
+ Context parentContext = currentContext();
+ request = GeodeRequest.create(region, method.getName(), query);
+ if (!instrumenter().shouldStart(parentContext, request)) {
return;
}
- context = tracer().startSpan(method.getName(), thiz, query);
+
+ context = instrumenter().start(parentContext, request);
scope = context.makeCurrent();
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void stopSpan(
@Advice.Thrown Throwable throwable,
+ @Advice.Local("otelRequest") GeodeRequest request,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
if (scope == null) {
return;
}
- scope.close();
- CallDepthThreadLocalMap.reset(Region.class);
- if (throwable != null) {
- tracer().endExceptionally(context, throwable);
- } else {
- tracer().end(context);
- }
+ scope.close();
+ instrumenter().end(context, request, null, throwable);
}
}
}

ADD
instrumentation/geode-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/geode/GeodeInstrumenters.java
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.javaagent.instrumentation.geode;
+
+import io.opentelemetry.api.GlobalOpenTelemetry;
+import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
+import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
+import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
+import io.opentelemetry.instrumentation.api.instrumenter.db.DbAttributesExtractor;
+import io.opentelemetry.instrumentation.api.instrumenter.db.DbSpanNameExtractor;
+
+public final class GeodeInstrumenters {
+ private static final String INSTRUMENTATION_NAME = "io.opentelemetry.javaagent.geode-1.4";
+
+ private static final Instrumenter<GeodeRequest, Void> INSTRUMENTER;
+
+ static {
+ DbAttributesExtractor<GeodeRequest> attributesExtractor = new GeodeDbAttributesExtractor();
+ SpanNameExtractor<GeodeRequest> spanName = DbSpanNameExtractor.create(attributesExtractor);
+
+ INSTRUMENTER =
+ Instrumenter.<GeodeRequest, Void>newBuilder(
+ GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME, spanName)
+ .addAttributesExtractor(attributesExtractor)
+ .newInstrumenter(SpanKindExtractor.alwaysClient());
+ }
+
+ public static Instrumenter<GeodeRequest, Void> instrumenter() {
+ return INSTRUMENTER;
+ }
+
+ private GeodeInstrumenters() {}
+}

ADD
instrumentation/geode-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/geode/GeodeRequest.java
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.javaagent.instrumentation.geode;
+
+import com.google.auto.value.AutoValue;
+import org.apache.geode.cache.Region;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+@AutoValue
+public abstract class GeodeRequest {
+
+ public abstract Region<?, ?> getRegion();
+
+ public abstract String getOperation();
+
+ @Nullable
+ public abstract String getQuery();
+
+ public static GeodeRequest create(Region<?, ?> region, String operation, @Nullable String query) {
+ return new AutoValue_GeodeRequest(region, operation, query);
+ }
+}

DELETE
instrumentation/geode-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/geode/GeodeTracer.java
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package io.opentelemetry.javaagent.instrumentation.geode;
-
-import static io.opentelemetry.api.trace.SpanKind.CLIENT;
-
-import io.opentelemetry.api.trace.SpanBuilder;
-import io.opentelemetry.context.Context;
-import io.opentelemetry.instrumentation.api.db.SqlStatementInfo;
-import io.opentelemetry.instrumentation.api.db.SqlStatementSanitizer;
-import io.opentelemetry.instrumentation.api.tracer.DatabaseClientTracer;
-import io.opentelemetry.instrumentation.api.tracer.net.NetPeerAttributes;
-import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
-import java.net.InetSocketAddress;
-import org.apache.geode.cache.Region;
-
-public class GeodeTracer extends DatabaseClientTracer<Region<?, ?>, String, SqlStatementInfo> {
- private static final GeodeTracer TRACER = new GeodeTracer();
-
- private GeodeTracer() {
- super(NetPeerAttributes.INSTANCE);
- }
-
- public static GeodeTracer tracer() {
- return TRACER;
- }
-
- public Context startSpan(String operation, Region<?, ?> connection, String query) {
- Context parentContext = Context.current();
- SqlStatementInfo sanitizedStatement = sanitizeStatement(query);
-
- SpanBuilder span =
- spanBuilder(parentContext, operation, CLIENT)
- .setAttribute(SemanticAttributes.DB_SYSTEM, dbSystem(connection))
- .setAttribute(SemanticAttributes.DB_OPERATION, operation);
-
- onConnection(span, connection);
- setNetSemanticConvention(span, connection);
- onStatement(span, connection, query, sanitizedStatement);
-
- return parentContext.with(span.startSpan());
- }
-
- @Override
- protected SqlStatementInfo sanitizeStatement(String statement) {
- return SqlStatementSanitizer.sanitize(statement);
- }
-
- @Override
- protected String dbSystem(Region<?, ?> region) {
- return SemanticAttributes.DbSystemValues.GEODE;
- }
-
- @Override
- protected String dbName(Region<?, ?> region) {
- return region.getName();
- }
-
- @Override
- protected InetSocketAddress peerAddress(Region<?, ?> region) {
- return null;
- }
-
- @Override
- protected String dbStatement(
- Region<?, ?> connection, String statement, SqlStatementInfo sanitizedStatement) {
- return sanitizedStatement.getFullStatement();
- }
-
- @Override
- protected String getInstrumentationName() {
- return "io.opentelemetry.javaagent.geode-1.4";
- }
-}

MODIFY
instrumentation/geode-1.4/javaagent/src/test/groovy/PutGetTest.groovy
instrumentation/geode-1.4/javaagent/src/test/groovy/PutGetTest.groovy
@@ -114,7 +114,7 @@ class PutGetTest extends AgentInstrumentationSpecification {
kind INTERNAL
}
span(1) {
- name "clear"
+ name "clear test-region"
kind CLIENT
attributes {
"$SemanticAttributes.DB_SYSTEM.key" "geode"
@@ -123,7 +123,7 @@ class PutGetTest extends AgentInstrumentationSpecification {
}
}
span(2) {
- name "put"
+ name "put test-region"
kind CLIENT
attributes {
"$SemanticAttributes.DB_SYSTEM.key" "geode"
@@ -132,7 +132,7 @@ class PutGetTest extends AgentInstrumentationSpecification {
}
}
span(3) {
- name verb
+ name "$verb test-region"
kind CLIENT
attributes {
"$SemanticAttributes.DB_SYSTEM.key" "geode"
@@ -165,7 +165,7 @@ class PutGetTest extends AgentInstrumentationSpecification {
assertTraces(1) {
trace(0, 1) {
span(0) {
- name "query"
+ name "query test-region"
kind CLIENT
attributes {
"$SemanticAttributes.DB_SYSTEM.key" "geode"

Update geode to Instrumenter API (#3067)