Convert Spymemcached integration to Instrumenter (#4273)
* Convert Spymemcached integration to Instrumenter * Update instrumentation/spymemcached-2.12/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spymemcached/SpymemcachedAttributeExtractor.java Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com> * Spotless * Optimise Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
This commit is contained in:
parent
fbb5f8f5c6
commit
11b2f16820
|
@ -14,6 +14,9 @@ muzzle {
|
|||
dependencies {
|
||||
library("net.spy:spymemcached:2.12.0")
|
||||
|
||||
compileOnly("com.google.auto.value:auto-value-annotations")
|
||||
annotationProcessor("com.google.auto.value:auto-value")
|
||||
|
||||
testImplementation("com.google.guava:guava")
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
package io.opentelemetry.javaagent.instrumentation.spymemcached;
|
||||
|
||||
import static io.opentelemetry.javaagent.instrumentation.spymemcached.MemcacheClientTracer.tracer;
|
||||
import static io.opentelemetry.javaagent.instrumentation.spymemcached.SpymemcachedSingletons.instrumenter;
|
||||
|
||||
import io.opentelemetry.api.trace.Span;
|
||||
import io.opentelemetry.context.Context;
|
||||
|
@ -26,10 +26,12 @@ public abstract class CompletionListener<T> {
|
|||
private static final String MISS = "miss";
|
||||
|
||||
private final Context context;
|
||||
private final SpymemcachedRequest request;
|
||||
|
||||
protected CompletionListener(
|
||||
Context parentContext, MemcachedConnection connection, String methodName) {
|
||||
context = tracer().startSpan(parentContext, connection, methodName);
|
||||
request = SpymemcachedRequest.create(connection, methodName);
|
||||
context = instrumenter().start(parentContext, request);
|
||||
}
|
||||
|
||||
protected void closeAsyncSpan(T future) {
|
||||
|
@ -48,26 +50,22 @@ public abstract class CompletionListener<T> {
|
|||
span.setAttribute(DB_COMMAND_CANCELLED, true);
|
||||
}
|
||||
} else {
|
||||
tracer().endExceptionally(context, e);
|
||||
instrumenter().end(context, request, null, e);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
// Avoid swallowing InterruptedException
|
||||
tracer().endExceptionally(context, e);
|
||||
instrumenter().end(context, request, null, e);
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (Throwable t) {
|
||||
// This should never happen, just in case to make sure we cover all unexpected exceptions
|
||||
tracer().endExceptionally(context, t);
|
||||
instrumenter().end(context, request, null, t);
|
||||
} finally {
|
||||
tracer().end(context);
|
||||
instrumenter().end(context, request, future, null);
|
||||
}
|
||||
}
|
||||
|
||||
protected void closeSyncSpan(Throwable thrown) {
|
||||
if (thrown == null) {
|
||||
tracer().end(context);
|
||||
} else {
|
||||
tracer().endExceptionally(context, thrown);
|
||||
}
|
||||
instrumenter().end(context, request, null, thrown);
|
||||
}
|
||||
|
||||
protected abstract void processResult(Span span, T future)
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.spymemcached;
|
||||
|
||||
import io.opentelemetry.instrumentation.api.tracer.DatabaseClientTracer;
|
||||
import io.opentelemetry.instrumentation.api.tracer.net.NetPeerAttributes;
|
||||
import java.net.InetSocketAddress;
|
||||
import net.spy.memcached.MemcachedConnection;
|
||||
|
||||
public class MemcacheClientTracer
|
||||
extends DatabaseClientTracer<MemcachedConnection, String, String> {
|
||||
private static final MemcacheClientTracer TRACER = new MemcacheClientTracer();
|
||||
|
||||
private MemcacheClientTracer() {
|
||||
super(NetPeerAttributes.INSTANCE);
|
||||
}
|
||||
|
||||
public static MemcacheClientTracer tracer() {
|
||||
return TRACER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String sanitizeStatement(String methodName) {
|
||||
char[] chars =
|
||||
methodName
|
||||
.replaceFirst("^async", "")
|
||||
// 'CAS' name is special, we have to lowercase whole name
|
||||
.replaceFirst("^CAS", "cas")
|
||||
.toCharArray();
|
||||
|
||||
// Lowercase first letter
|
||||
chars[0] = Character.toLowerCase(chars[0]);
|
||||
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String dbSystem(MemcachedConnection memcachedConnection) {
|
||||
return "memcached";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InetSocketAddress peerAddress(MemcachedConnection memcachedConnection) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String dbOperation(
|
||||
MemcachedConnection connection, String methodName, String operation) {
|
||||
return operation;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getInstrumentationName() {
|
||||
return "io.opentelemetry.spymemcached-2.12";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.spymemcached;
|
||||
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.db.DbAttributesExtractor;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public class SpymemcachedAttributeExtractor
|
||||
extends DbAttributesExtractor<SpymemcachedRequest, Object> {
|
||||
@Override
|
||||
protected String system(SpymemcachedRequest spymemcachedRequest) {
|
||||
return "memcached";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable String user(SpymemcachedRequest spymemcachedRequest) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable String name(SpymemcachedRequest spymemcachedRequest) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable String connectionString(SpymemcachedRequest spymemcachedRequest) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable String statement(SpymemcachedRequest spymemcachedRequest) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable String operation(SpymemcachedRequest spymemcachedRequest) {
|
||||
return spymemcachedRequest.dbOperation();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.spymemcached;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import net.spy.memcached.MemcachedConnection;
|
||||
|
||||
@AutoValue
|
||||
public abstract class SpymemcachedRequest {
|
||||
|
||||
public static SpymemcachedRequest create(MemcachedConnection connection, String statement) {
|
||||
return new AutoValue_SpymemcachedRequest(connection, statement);
|
||||
}
|
||||
|
||||
public abstract MemcachedConnection getConnection();
|
||||
|
||||
public abstract String getStatement();
|
||||
|
||||
public String dbOperation() {
|
||||
String statement = getStatement();
|
||||
if (statement.startsWith("async")) {
|
||||
statement = statement.substring("async".length());
|
||||
}
|
||||
if (statement.startsWith("CAS")) {
|
||||
// 'CAS' name is special, we have to lowercase whole name
|
||||
return "cas" + statement.substring("CAS".length());
|
||||
}
|
||||
|
||||
char[] chars = statement.toCharArray();
|
||||
// Lowercase first letter
|
||||
chars[0] = Character.toLowerCase(chars[0]);
|
||||
return new String(chars);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.spymemcached;
|
||||
|
||||
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 SpymemcachedSingletons {
|
||||
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.spymemcached-2.12";
|
||||
|
||||
private static final Instrumenter<SpymemcachedRequest, Object> INSTRUMENTER;
|
||||
|
||||
static {
|
||||
DbAttributesExtractor<SpymemcachedRequest, Object> attributesExtractor =
|
||||
new SpymemcachedAttributeExtractor();
|
||||
SpanNameExtractor<SpymemcachedRequest> spanName =
|
||||
DbSpanNameExtractor.create(attributesExtractor);
|
||||
|
||||
INSTRUMENTER =
|
||||
Instrumenter.newBuilder(GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME, spanName)
|
||||
.addAttributesExtractor(attributesExtractor)
|
||||
.newInstrumenter(SpanKindExtractor.alwaysClient());
|
||||
}
|
||||
|
||||
public static Instrumenter<SpymemcachedRequest, Object> instrumenter() {
|
||||
return INSTRUMENTER;
|
||||
}
|
||||
|
||||
private SpymemcachedSingletons() {}
|
||||
}
|
Loading…
Reference in New Issue