Add library instrumentation for elasticsearch rest client 7 (#8911)
Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
This commit is contained in:
parent
6892c64928
commit
fbae980fc5
|
|
@ -7,6 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest;
|
|||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.ElasticsearchEndpointDefinition;
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.apiclient.ElasticsearchEndpointMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
package io.opentelemetry.javaagent.instrumentation.elasticsearch.apiclient;
|
||||
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.ElasticsearchEndpointDefinition;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.ElasticsearchEndpointDefinition;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
|||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.instrumentation.api.util.VirtualField;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.ElasticsearchEndpointDefinition;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.ElasticsearchEndpointDefinition;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
|||
|
||||
import co.elastic.clients.transport.Endpoint;
|
||||
import io.opentelemetry.instrumentation.api.util.VirtualField;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.ElasticsearchEndpointDefinition;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.ElasticsearchEndpointDefinition;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.elasticsearch.apiclient;
|
||||
|
||||
import static io.opentelemetry.instrumentation.testing.GlobalTraceUtil.runWithSpan;
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies;
|
||||
|
|
@ -6,14 +6,15 @@
|
|||
package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.v5_0;
|
||||
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.ElasticsearchRestInstrumenterFactory;
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.ElasticsearchRestRequest;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.ElasticsearchRestRequest;
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.ElasticsearchRestJavaagentInstrumenterFactory;
|
||||
import org.elasticsearch.client.Response;
|
||||
|
||||
public final class ElasticsearchRest5Singletons {
|
||||
|
||||
private static final Instrumenter<ElasticsearchRestRequest, Response> INSTRUMENTER =
|
||||
ElasticsearchRestInstrumenterFactory.create("io.opentelemetry.elasticsearch-rest-5.0");
|
||||
ElasticsearchRestJavaagentInstrumenterFactory.create(
|
||||
"io.opentelemetry.elasticsearch-rest-5.0");
|
||||
|
||||
public static Instrumenter<ElasticsearchRestRequest, Response> instrumenter() {
|
||||
return INSTRUMENTER;
|
||||
|
|
|
|||
|
|
@ -15,10 +15,10 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
|||
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.ElasticsearchRestRequest;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.RestResponseListener;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.ElasticsearchRestRequest;
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.RestResponseListener;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.v5_0;
|
||||
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
|
@ -6,14 +6,15 @@
|
|||
package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.v6_4;
|
||||
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.ElasticsearchRestInstrumenterFactory;
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.ElasticsearchRestRequest;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.ElasticsearchRestRequest;
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.ElasticsearchRestJavaagentInstrumenterFactory;
|
||||
import org.elasticsearch.client.Response;
|
||||
|
||||
public final class ElasticsearchRest6Singletons {
|
||||
|
||||
private static final Instrumenter<ElasticsearchRestRequest, Response> INSTRUMENTER =
|
||||
ElasticsearchRestInstrumenterFactory.create("io.opentelemetry.elasticsearch-rest-6.4");
|
||||
ElasticsearchRestJavaagentInstrumenterFactory.create(
|
||||
"io.opentelemetry.elasticsearch-rest-6.4");
|
||||
|
||||
public static Instrumenter<ElasticsearchRestRequest, Response> instrumenter() {
|
||||
return INSTRUMENTER;
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
|||
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.ElasticsearchRestRequest;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.RestResponseListener;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.ElasticsearchRestRequest;
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.RestResponseListener;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.v6_4;
|
||||
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
|
@ -28,10 +28,7 @@ dependencies {
|
|||
// Netty is used, but it adds complexity to the tests since we're using embedded ES.
|
||||
// testInstrumentation(project(":instrumentation:netty:netty-4.1:javaagent"))
|
||||
|
||||
testImplementation("org.apache.logging.log4j:log4j-core:2.11.0")
|
||||
testImplementation("org.apache.logging.log4j:log4j-api:2.11.0")
|
||||
testImplementation("com.fasterxml.jackson.core:jackson-databind")
|
||||
|
||||
testImplementation("org.testcontainers:elasticsearch")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,14 +6,15 @@
|
|||
package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.v7_0;
|
||||
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.ElasticsearchRestInstrumenterFactory;
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.ElasticsearchRestRequest;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.ElasticsearchRestRequest;
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.ElasticsearchRestJavaagentInstrumenterFactory;
|
||||
import org.elasticsearch.client.Response;
|
||||
|
||||
public final class ElasticsearchRest7Singletons {
|
||||
|
||||
private static final Instrumenter<ElasticsearchRestRequest, Response> INSTRUMENTER =
|
||||
ElasticsearchRestInstrumenterFactory.create("io.opentelemetry.elasticsearch-rest-7.0");
|
||||
ElasticsearchRestJavaagentInstrumenterFactory.create(
|
||||
"io.opentelemetry.elasticsearch-rest-7.0");
|
||||
|
||||
public static Instrumenter<ElasticsearchRestRequest, Response> instrumenter() {
|
||||
return INSTRUMENTER;
|
||||
|
|
|
|||
|
|
@ -15,11 +15,11 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
|||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.instrumentation.api.util.VirtualField;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.ElasticsearchEndpointDefinition;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.ElasticsearchRestRequest;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.RestResponseListener;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.ElasticsearchEndpointDefinition;
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.ElasticsearchRestRequest;
|
||||
import io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.RestResponseListener;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
|
@ -67,6 +67,7 @@ public class RestClientInstrumentation implements TypeInstrumentation {
|
|||
ElasticsearchRestRequest.create(
|
||||
request.getMethod(),
|
||||
request.getEndpoint(),
|
||||
// set by elasticsearch-api-client instrumentation
|
||||
virtualField.get(request),
|
||||
request.getEntity());
|
||||
if (!instrumenter().shouldStart(parentContext, otelRequest)) {
|
||||
|
|
@ -113,6 +114,7 @@ public class RestClientInstrumentation implements TypeInstrumentation {
|
|||
ElasticsearchRestRequest.create(
|
||||
request.getMethod(),
|
||||
request.getEndpoint(),
|
||||
// set by elasticsearch-api-client instrumentation
|
||||
virtualField.get(request),
|
||||
request.getEntity());
|
||||
if (!instrumenter().shouldStart(parentContext, otelRequest)) {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.v7_0;
|
||||
|
||||
import static io.opentelemetry.instrumentation.testing.GlobalTraceUtil.runWithSpan;
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies;
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
plugins {
|
||||
id("otel.library-instrumentation")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
library("org.elasticsearch.client:elasticsearch-rest-client:7.0.0")
|
||||
implementation("net.bytebuddy:byte-buddy")
|
||||
implementation(project(":instrumentation:elasticsearch:elasticsearch-rest-common:library"))
|
||||
|
||||
testImplementation("com.fasterxml.jackson.core:jackson-databind")
|
||||
testImplementation("org.testcontainers:elasticsearch")
|
||||
}
|
||||
|
||||
tasks {
|
||||
test {
|
||||
usesService(gradle.sharedServices.registrations["testcontainersBuildService"].service)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.elasticsearch.rest.v7_0;
|
||||
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.ElasticsearchRestRequest;
|
||||
import org.elasticsearch.client.Response;
|
||||
import org.elasticsearch.client.RestClient;
|
||||
|
||||
/** Entrypoint for instrumenting Apache Elasticsearch Rest clients. */
|
||||
public final class ElasticsearchRest7Telemetry {
|
||||
|
||||
/**
|
||||
* Returns a new {@link ElasticsearchRest7Telemetry} configured with the given {@link
|
||||
* OpenTelemetry}.
|
||||
*/
|
||||
public static ElasticsearchRest7Telemetry create(OpenTelemetry openTelemetry) {
|
||||
return builder(openTelemetry).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link ElasticsearchRest7TelemetryBuilder} configured with the given {@link
|
||||
* OpenTelemetry}.
|
||||
*/
|
||||
public static ElasticsearchRest7TelemetryBuilder builder(OpenTelemetry openTelemetry) {
|
||||
return new ElasticsearchRest7TelemetryBuilder(openTelemetry);
|
||||
}
|
||||
|
||||
private final Instrumenter<ElasticsearchRestRequest, Response> instrumenter;
|
||||
|
||||
ElasticsearchRest7Telemetry(Instrumenter<ElasticsearchRestRequest, Response> instrumenter) {
|
||||
this.instrumenter = instrumenter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new tracing-enable {@link RestClient} using the provided {@link RestClient}
|
||||
* instance.
|
||||
*/
|
||||
public RestClient wrap(RestClient restClient) {
|
||||
return RestClientWrapper.wrap(restClient, instrumenter);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.elasticsearch.rest.v7_0;
|
||||
|
||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.ElasticsearchRestInstrumenterFactory;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.ElasticsearchRestRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.elasticsearch.client.Response;
|
||||
|
||||
public final class ElasticsearchRest7TelemetryBuilder {
|
||||
|
||||
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.elasticsearch-rest-7.0";
|
||||
|
||||
private final OpenTelemetry openTelemetry;
|
||||
private final List<AttributesExtractor<ElasticsearchRestRequest, Response>> attributesExtractors =
|
||||
new ArrayList<>();
|
||||
|
||||
ElasticsearchRest7TelemetryBuilder(OpenTelemetry openTelemetry) {
|
||||
this.openTelemetry = openTelemetry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an additional {@link AttributesExtractor} to invoke to set attributes to instrumented
|
||||
* items.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public ElasticsearchRest7TelemetryBuilder addAttributesExtractor(
|
||||
AttributesExtractor<ElasticsearchRestRequest, Response> attributesExtractor) {
|
||||
attributesExtractors.add(attributesExtractor);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link ElasticsearchRest7Telemetry} with the settings of this {@link
|
||||
* ElasticsearchRest7TelemetryBuilder}.
|
||||
*/
|
||||
public ElasticsearchRest7Telemetry build() {
|
||||
Instrumenter<ElasticsearchRestRequest, Response> instrumenter =
|
||||
ElasticsearchRestInstrumenterFactory.create(
|
||||
openTelemetry, INSTRUMENTATION_NAME, attributesExtractors, false);
|
||||
|
||||
return new ElasticsearchRest7Telemetry(instrumenter);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.elasticsearch.rest.v7_0;
|
||||
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.ElasticsearchRestRequest;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.RestResponseListener;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
import net.bytebuddy.description.modifier.Visibility;
|
||||
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
|
||||
import net.bytebuddy.implementation.InvocationHandlerAdapter;
|
||||
import net.bytebuddy.matcher.ElementMatchers;
|
||||
import org.apache.http.Header;
|
||||
import org.elasticsearch.client.Node;
|
||||
import org.elasticsearch.client.Request;
|
||||
import org.elasticsearch.client.Response;
|
||||
import org.elasticsearch.client.ResponseListener;
|
||||
import org.elasticsearch.client.RestClient;
|
||||
|
||||
class RestClientWrapper {
|
||||
private static final Class<?> proxyClass = createProxyClass();
|
||||
private static final Field targetField = getTargetField(proxyClass);
|
||||
private static final Field instrumenterSupplierField = getInstrumenterSupplierField(proxyClass);
|
||||
private static final Function<RestClient, RestClient> proxyFactory = getProxyFactory(proxyClass);
|
||||
|
||||
private static Class<?> createProxyClass() {
|
||||
return new ByteBuddy()
|
||||
.subclass(RestClient.class)
|
||||
.defineField("target", RestClient.class, Visibility.PUBLIC)
|
||||
// using Supplier instead of Instrumenter in case RestClientWrapper and opentelemetry apis
|
||||
// are in a child class loader of RestClient's class loader and Instrumenter is not visible
|
||||
// for RestClient
|
||||
.defineField("instrumenterSupplier", Supplier.class, Visibility.PUBLIC)
|
||||
.method(ElementMatchers.any())
|
||||
.intercept(
|
||||
InvocationHandlerAdapter.of(
|
||||
(proxy, method, args) -> {
|
||||
RestClient target = (RestClient) targetField.get(proxy);
|
||||
Instrumenter<ElasticsearchRestRequest, Response> instrumenter =
|
||||
getInstrumenter(proxy);
|
||||
// target is null when running proxy constructor
|
||||
if (target == null || instrumenter == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// instrument performRequest and performRequestAsync methods
|
||||
if ("performRequest".equals(method.getName())
|
||||
&& args.length == 1
|
||||
&& args[0] instanceof Request
|
||||
&& Response.class == method.getReturnType()) {
|
||||
Request request = (Request) args[0];
|
||||
Context parentContext = Context.current();
|
||||
ElasticsearchRestRequest otelRequest =
|
||||
ElasticsearchRestRequest.create(request.getMethod(), request.getEndpoint());
|
||||
if (!instrumenter.shouldStart(parentContext, otelRequest)) {
|
||||
return method.invoke(target, args);
|
||||
}
|
||||
|
||||
Response response = null;
|
||||
Throwable throwable = null;
|
||||
Context context = instrumenter.start(parentContext, otelRequest);
|
||||
try (Scope scope = context.makeCurrent()) {
|
||||
response = (Response) method.invoke(target, args);
|
||||
} catch (Throwable exception) {
|
||||
throwable = exception;
|
||||
} finally {
|
||||
instrumenter.end(context, otelRequest, response, throwable);
|
||||
}
|
||||
|
||||
return response;
|
||||
} else if ("performRequestAsync".equals(method.getName())
|
||||
&& args.length == 2
|
||||
&& args[0] instanceof Request
|
||||
&& args[1] instanceof ResponseListener) {
|
||||
|
||||
Request request = (Request) args[0];
|
||||
ResponseListener responseListener = (ResponseListener) args[1];
|
||||
Context parentContext = Context.current();
|
||||
ElasticsearchRestRequest otelRequest =
|
||||
ElasticsearchRestRequest.create(request.getMethod(), request.getEndpoint());
|
||||
if (!instrumenter.shouldStart(parentContext, otelRequest)) {
|
||||
return method.invoke(target, args);
|
||||
}
|
||||
|
||||
Throwable throwable = null;
|
||||
Context context = instrumenter.start(parentContext, otelRequest);
|
||||
args[1] =
|
||||
new RestResponseListener(
|
||||
responseListener, parentContext, instrumenter, context, otelRequest);
|
||||
try (Scope scope = context.makeCurrent()) {
|
||||
return method.invoke(target, args);
|
||||
} catch (Throwable exception) {
|
||||
throwable = exception;
|
||||
} finally {
|
||||
if (throwable != null) {
|
||||
instrumenter.end(context, otelRequest, null, throwable);
|
||||
}
|
||||
// span ended in RestResponseListener
|
||||
}
|
||||
}
|
||||
|
||||
// delegate to wrapped RestClient
|
||||
return method.invoke(target, args);
|
||||
}))
|
||||
.make()
|
||||
.load(RestClient.class.getClassLoader(), ClassLoadingStrategy.Default.INJECTION)
|
||||
.getLoaded();
|
||||
}
|
||||
|
||||
private static Field getTargetField(Class<?> clazz) {
|
||||
return getProxyField(clazz, "target");
|
||||
}
|
||||
|
||||
private static Field getInstrumenterSupplierField(Class<?> clazz) {
|
||||
return getProxyField(clazz, "instrumenterSupplier");
|
||||
}
|
||||
|
||||
private static Field getProxyField(Class<?> clazz, String fieldName) {
|
||||
try {
|
||||
return clazz.getDeclaredField(fieldName);
|
||||
} catch (NoSuchFieldException exception) {
|
||||
throw new IllegalStateException("Could not find proxy field", exception);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Instrumenter<ElasticsearchRestRequest, Response> getInstrumenter(Object proxy)
|
||||
throws IllegalAccessException {
|
||||
Supplier<Instrumenter<ElasticsearchRestRequest, Response>> supplier =
|
||||
(Supplier<Instrumenter<ElasticsearchRestRequest, Response>>)
|
||||
instrumenterSupplierField.get(proxy);
|
||||
return supplier != null ? supplier.get() : null;
|
||||
}
|
||||
|
||||
private static Function<RestClient, RestClient> getProxyFactory(Class<?> clazz) {
|
||||
for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
|
||||
Class<?>[] parameterTypes = constructor.getParameterTypes();
|
||||
if (parameterTypes.length >= 3
|
||||
&& !parameterTypes[0].isPrimitive()
|
||||
&& parameterTypes[1] == Header[].class
|
||||
&& parameterTypes[2] == List.class) {
|
||||
return restClient -> {
|
||||
List<Node> nodes = restClient.getNodes();
|
||||
// all the proxy methods will delegate to the wrapped RestClient, we need to fill only the
|
||||
// arguments that are required by the constructor
|
||||
Object[] arguments = new Object[parameterTypes.length];
|
||||
arguments[1] = new Header[0];
|
||||
arguments[2] = nodes;
|
||||
for (int i = 3; i < parameterTypes.length; i++) {
|
||||
if (parameterTypes[i].isPrimitive()) {
|
||||
arguments[i] = getDefaultValue(parameterTypes[i]);
|
||||
}
|
||||
}
|
||||
try {
|
||||
return (RestClient) constructor.newInstance(arguments);
|
||||
} catch (Exception exception) {
|
||||
throw new IllegalStateException("Failed to construct proxy instance", exception);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Failed to find suitable constructor");
|
||||
}
|
||||
|
||||
// create a single element array of given type, this method is used to get the default value of
|
||||
// a primitive type
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> T getDefaultValue(Class<T> clazz) {
|
||||
return (T) Array.get(Array.newInstance(clazz, 1), 0);
|
||||
}
|
||||
|
||||
static RestClient wrap(
|
||||
RestClient restClient, Instrumenter<ElasticsearchRestRequest, Response> instrumenter) {
|
||||
RestClient wrapped = proxyFactory.apply(restClient);
|
||||
try {
|
||||
// set wrapped RestClient instance and the instrumenter on the proxy
|
||||
targetField.set(wrapped, restClient);
|
||||
instrumenterSupplierField.set(
|
||||
wrapped, (Supplier<Instrumenter<ElasticsearchRestRequest, Response>>) () -> instrumenter);
|
||||
return wrapped;
|
||||
} catch (Exception exception) {
|
||||
throw new IllegalStateException("Failed to construct proxy instance", exception);
|
||||
}
|
||||
}
|
||||
|
||||
private RestClientWrapper() {}
|
||||
}
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.elasticsearch.rest.v7_0;
|
||||
|
||||
import static io.opentelemetry.instrumentation.testing.GlobalTraceUtil.runWithSpan;
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
|
||||
|
||||
import io.opentelemetry.api.trace.SpanKind;
|
||||
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
||||
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.elasticsearch.client.Request;
|
||||
import org.elasticsearch.client.Response;
|
||||
import org.elasticsearch.client.ResponseListener;
|
||||
import org.elasticsearch.client.RestClient;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.testcontainers.elasticsearch.ElasticsearchContainer;
|
||||
import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
class ElasticsearchRest7Test {
|
||||
@RegisterExtension
|
||||
static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();
|
||||
|
||||
static ElasticsearchContainer elasticsearch;
|
||||
|
||||
static HttpHost httpHost;
|
||||
|
||||
static RestClient client;
|
||||
|
||||
static ObjectMapper objectMapper;
|
||||
|
||||
@BeforeAll
|
||||
static void setUp() {
|
||||
elasticsearch =
|
||||
new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2");
|
||||
// limit memory usage
|
||||
elasticsearch.withEnv("ES_JAVA_OPTS", "-Xmx256m -Xms256m");
|
||||
elasticsearch.start();
|
||||
|
||||
httpHost = HttpHost.create(elasticsearch.getHttpHostAddress());
|
||||
|
||||
client =
|
||||
RestClient.builder(httpHost)
|
||||
.setRequestConfigCallback(
|
||||
builder ->
|
||||
builder
|
||||
.setConnectTimeout(Integer.MAX_VALUE)
|
||||
.setSocketTimeout(Integer.MAX_VALUE))
|
||||
.build();
|
||||
client = ElasticsearchRest7Telemetry.create(testing.getOpenTelemetry()).wrap(client);
|
||||
|
||||
objectMapper = new ObjectMapper();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void cleanUp() {
|
||||
elasticsearch.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void elasticsearchStatus() throws Exception {
|
||||
Response response = client.performRequest(new Request("GET", "_cluster/health"));
|
||||
Map<?, ?> result = objectMapper.readValue(response.getEntity().getContent(), Map.class);
|
||||
Assertions.assertEquals(result.get("status"), "green");
|
||||
|
||||
testing.waitAndAssertTraces(
|
||||
trace ->
|
||||
trace.hasSpansSatisfyingExactly(
|
||||
span ->
|
||||
span.hasName("GET")
|
||||
.hasKind(SpanKind.CLIENT)
|
||||
.hasNoParent()
|
||||
.hasAttributesSatisfyingExactly(
|
||||
equalTo(SemanticAttributes.DB_SYSTEM, "elasticsearch"),
|
||||
equalTo(SemanticAttributes.HTTP_METHOD, "GET"),
|
||||
equalTo(SemanticAttributes.NET_PEER_NAME, httpHost.getHostName()),
|
||||
equalTo(SemanticAttributes.NET_PEER_PORT, httpHost.getPort()),
|
||||
equalTo(
|
||||
SemanticAttributes.HTTP_URL,
|
||||
httpHost.toURI() + "/_cluster/health"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void elasticsearchStatusAsync() throws Exception {
|
||||
AsyncRequest asyncRequest = new AsyncRequest();
|
||||
CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
ResponseListener responseListener =
|
||||
new ResponseListener() {
|
||||
@Override
|
||||
public void onSuccess(Response response) {
|
||||
|
||||
runWithSpan(
|
||||
"callback",
|
||||
() -> {
|
||||
asyncRequest.setRequestResponse(response);
|
||||
countDownLatch.countDown();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
runWithSpan(
|
||||
"callback",
|
||||
() -> {
|
||||
asyncRequest.setException(e);
|
||||
countDownLatch.countDown();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
runWithSpan(
|
||||
"parent",
|
||||
() -> client.performRequestAsync(new Request("GET", "_cluster/health"), responseListener));
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
countDownLatch.await(10, TimeUnit.SECONDS);
|
||||
|
||||
if (asyncRequest.getException() != null) {
|
||||
throw asyncRequest.getException();
|
||||
}
|
||||
|
||||
Map<?, ?> result =
|
||||
objectMapper.readValue(
|
||||
asyncRequest.getRequestResponse().getEntity().getContent(), Map.class);
|
||||
Assertions.assertEquals(result.get("status"), "green");
|
||||
|
||||
testing.waitAndAssertTraces(
|
||||
trace ->
|
||||
trace.hasSpansSatisfyingExactly(
|
||||
span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(),
|
||||
span ->
|
||||
span.hasName("GET")
|
||||
.hasKind(SpanKind.CLIENT)
|
||||
.hasParent(trace.getSpan(0))
|
||||
.hasAttributesSatisfyingExactly(
|
||||
equalTo(SemanticAttributes.DB_SYSTEM, "elasticsearch"),
|
||||
equalTo(SemanticAttributes.HTTP_METHOD, "GET"),
|
||||
equalTo(SemanticAttributes.NET_PEER_NAME, httpHost.getHostName()),
|
||||
equalTo(SemanticAttributes.NET_PEER_PORT, httpHost.getPort()),
|
||||
equalTo(
|
||||
SemanticAttributes.HTTP_URL,
|
||||
httpHost.toURI() + "/_cluster/health")),
|
||||
span ->
|
||||
span.hasName("callback")
|
||||
.hasKind(SpanKind.INTERNAL)
|
||||
.hasParent(trace.getSpan(0))));
|
||||
}
|
||||
|
||||
private static class AsyncRequest {
|
||||
volatile Response requestResponse = null;
|
||||
volatile Exception exception = null;
|
||||
|
||||
public Response getRequestResponse() {
|
||||
return requestResponse;
|
||||
}
|
||||
|
||||
public void setRequestResponse(Response requestResponse) {
|
||||
this.requestResponse = requestResponse;
|
||||
}
|
||||
|
||||
public Exception getException() {
|
||||
return exception;
|
||||
}
|
||||
|
||||
public void setException(Exception exception) {
|
||||
this.exception = exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@ plugins {
|
|||
|
||||
dependencies {
|
||||
compileOnly("org.elasticsearch.client:rest:5.0.0")
|
||||
compileOnly("com.google.auto.value:auto-value-annotations")
|
||||
|
||||
annotationProcessor("com.google.auto.value:auto-value")
|
||||
api(project(":instrumentation:elasticsearch:elasticsearch-rest-common:library"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest;
|
||||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.ElasticsearchRestInstrumenterFactory;
|
||||
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.ElasticsearchRestRequest;
|
||||
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
|
||||
import java.util.Collections;
|
||||
import org.elasticsearch.client.Response;
|
||||
|
||||
public final class ElasticsearchRestJavaagentInstrumenterFactory {
|
||||
|
||||
private static final boolean CAPTURE_SEARCH_QUERY =
|
||||
InstrumentationConfig.get()
|
||||
.getBoolean("otel.instrumentation.elasticsearch.capture-search-query", false);
|
||||
|
||||
private ElasticsearchRestJavaagentInstrumenterFactory() {}
|
||||
|
||||
public static Instrumenter<ElasticsearchRestRequest, Response> create(
|
||||
String instrumentationName) {
|
||||
return ElasticsearchRestInstrumenterFactory.create(
|
||||
GlobalOpenTelemetry.get(),
|
||||
instrumentationName,
|
||||
Collections.emptyList(),
|
||||
CAPTURE_SEARCH_QUERY);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
plugins {
|
||||
id("otel.library-instrumentation")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("org.elasticsearch.client:rest:5.0.0")
|
||||
compileOnly("com.google.auto.value:auto-value-annotations")
|
||||
|
||||
annotationProcessor("com.google.auto.value:auto-value")
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest;
|
||||
package io.opentelemetry.instrumentation.elasticsearch.rest.internal;
|
||||
|
||||
import static io.opentelemetry.instrumentation.api.internal.AttributesExtractorUtil.internalSet;
|
||||
|
||||
|
|
@ -20,6 +20,10 @@ import javax.annotation.Nullable;
|
|||
import org.apache.http.HttpHost;
|
||||
import org.elasticsearch.client.Response;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
public class ElasticsearchClientAttributeExtractor
|
||||
implements AttributesExtractor<ElasticsearchRestRequest, Response> {
|
||||
|
||||
|
|
@ -3,12 +3,11 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest;
|
||||
package io.opentelemetry.instrumentation.elasticsearch.rest.internal;
|
||||
|
||||
import static java.util.logging.Level.FINE;
|
||||
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.db.DbClientAttributesGetter;
|
||||
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
|
|
@ -19,16 +18,22 @@ import java.util.stream.Collectors;
|
|||
import javax.annotation.Nullable;
|
||||
import org.apache.http.HttpEntity;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
final class ElasticsearchDbAttributesGetter
|
||||
implements DbClientAttributesGetter<ElasticsearchRestRequest> {
|
||||
|
||||
private static final boolean CAPTURE_SEARCH_QUERY =
|
||||
InstrumentationConfig.get()
|
||||
.getBoolean("otel.instrumentation.elasticsearch.capture-search-query", false);
|
||||
|
||||
private static final Logger logger =
|
||||
Logger.getLogger(ElasticsearchDbAttributesGetter.class.getName());
|
||||
|
||||
private final boolean captureSearchQuery;
|
||||
|
||||
ElasticsearchDbAttributesGetter(boolean captureSearchQuery) {
|
||||
this.captureSearchQuery = captureSearchQuery;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSystem(ElasticsearchRestRequest request) {
|
||||
return SemanticAttributes.DbSystemValues.ELASTICSEARCH;
|
||||
|
|
@ -57,7 +62,7 @@ final class ElasticsearchDbAttributesGetter
|
|||
public String getStatement(ElasticsearchRestRequest request) {
|
||||
ElasticsearchEndpointDefinition epDefinition = request.getEndpointDefinition();
|
||||
HttpEntity httpEntity = request.getHttpEntity();
|
||||
if (CAPTURE_SEARCH_QUERY
|
||||
if (captureSearchQuery
|
||||
&& epDefinition != null
|
||||
&& epDefinition.isSearchEndpoint()
|
||||
&& httpEntity != null
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest;
|
||||
package io.opentelemetry.instrumentation.elasticsearch.rest.internal;
|
||||
|
||||
import static java.util.Collections.unmodifiableList;
|
||||
|
||||
|
|
@ -17,6 +17,10 @@ import java.util.regex.Pattern;
|
|||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
public final class ElasticsearchEndpointDefinition {
|
||||
|
||||
private static final String UNDERSCORE_REPLACEMENT = "0";
|
||||
|
|
@ -62,11 +66,16 @@ public final class ElasticsearchEndpointDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
List<Route> getRoutes() {
|
||||
public List<Route> getRoutes() {
|
||||
return routes;
|
||||
}
|
||||
|
||||
static final class Route {
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
// Visible for testing
|
||||
public static final class Route {
|
||||
private final String name;
|
||||
private final boolean hasParameters;
|
||||
|
||||
|
|
@ -77,7 +86,7 @@ public final class ElasticsearchEndpointDefinition {
|
|||
this.hasParameters = name.contains("{") && name.contains("}");
|
||||
}
|
||||
|
||||
String getName() {
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
|
|
@ -104,7 +113,12 @@ public final class ElasticsearchEndpointDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
static final class EndpointPattern {
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
// Visible for testing
|
||||
public static final class EndpointPattern {
|
||||
private static final Pattern PATH_PART_NAMES_PATTERN = Pattern.compile("\\{([^}]+)}");
|
||||
private final Pattern pattern;
|
||||
private final List<String> pathPartNames;
|
||||
|
|
@ -136,7 +150,7 @@ public final class ElasticsearchEndpointDefinition {
|
|||
}
|
||||
|
||||
/** Builds a regex pattern from the parameterized route pattern. */
|
||||
static Pattern buildRegexPattern(String routeStr) {
|
||||
public static Pattern buildRegexPattern(String routeStr) {
|
||||
StringBuilder regexStr = new StringBuilder();
|
||||
regexStr.append('^');
|
||||
int startIdx = routeStr.indexOf("{");
|
||||
|
|
@ -3,31 +3,41 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest;
|
||||
package io.opentelemetry.instrumentation.elasticsearch.rest.internal;
|
||||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.db.DbClientAttributesExtractor;
|
||||
import java.util.List;
|
||||
import org.elasticsearch.client.Response;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
public final class ElasticsearchRestInstrumenterFactory {
|
||||
|
||||
private ElasticsearchRestInstrumenterFactory() {}
|
||||
|
||||
public static Instrumenter<ElasticsearchRestRequest, Response> create(
|
||||
String instrumentationName) {
|
||||
OpenTelemetry opentelemetry,
|
||||
String instrumentationName,
|
||||
List<AttributesExtractor<ElasticsearchRestRequest, Response>> attributesExtractors,
|
||||
boolean captureSearchQuery) {
|
||||
ElasticsearchDbAttributesGetter dbClientAttributesGetter =
|
||||
new ElasticsearchDbAttributesGetter();
|
||||
new ElasticsearchDbAttributesGetter(captureSearchQuery);
|
||||
ElasticsearchClientAttributeExtractor esClientAtrributesExtractor =
|
||||
new ElasticsearchClientAttributeExtractor();
|
||||
ElasticsearchSpanNameExtractor nameExtractor =
|
||||
new ElasticsearchSpanNameExtractor(dbClientAttributesGetter);
|
||||
|
||||
return Instrumenter.<ElasticsearchRestRequest, Response>builder(
|
||||
GlobalOpenTelemetry.get(), instrumentationName, nameExtractor)
|
||||
opentelemetry, instrumentationName, nameExtractor)
|
||||
.addAttributesExtractor(DbClientAttributesExtractor.create(dbClientAttributesGetter))
|
||||
.addAttributesExtractor(esClientAtrributesExtractor)
|
||||
.addAttributesExtractors(attributesExtractors)
|
||||
.buildInstrumenter(SpanKindExtractor.alwaysClient());
|
||||
}
|
||||
}
|
||||
|
|
@ -3,12 +3,16 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest;
|
||||
package io.opentelemetry.instrumentation.elasticsearch.rest.internal;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import javax.annotation.Nullable;
|
||||
import org.apache.http.HttpEntity;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
@AutoValue
|
||||
public abstract class ElasticsearchRestRequest {
|
||||
|
||||
|
|
@ -3,10 +3,14 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest;
|
||||
package io.opentelemetry.instrumentation.elasticsearch.rest.internal;
|
||||
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
public class ElasticsearchSpanNameExtractor implements SpanNameExtractor<ElasticsearchRestRequest> {
|
||||
|
||||
private final ElasticsearchDbAttributesGetter dbAttributesGetter;
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest;
|
||||
package io.opentelemetry.instrumentation.elasticsearch.rest.internal;
|
||||
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.Scope;
|
||||
|
|
@ -11,6 +11,10 @@ import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
|||
import org.elasticsearch.client.Response;
|
||||
import org.elasticsearch.client.ResponseListener;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
public final class RestResponseListener implements ResponseListener {
|
||||
|
||||
private final ResponseListener listener;
|
||||
|
|
@ -214,19 +214,19 @@ hideFromDependabot(":instrumentation:couchbase:couchbase-common:testing")
|
|||
hideFromDependabot(":instrumentation:dropwizard:dropwizard-metrics-4.0:javaagent")
|
||||
hideFromDependabot(":instrumentation:dropwizard:dropwizard-views-0.7:javaagent")
|
||||
hideFromDependabot(":instrumentation:dropwizard:dropwizard-testing")
|
||||
hideFromDependabot(":instrumentation:elasticsearch:elasticsearch-api-client-7.16:javaagent")
|
||||
hideFromDependabot(":instrumentation:elasticsearch:elasticsearch-api-client-7.16:javaagent-unit-tests")
|
||||
hideFromDependabot(":instrumentation:elasticsearch:elasticsearch-rest-common:javaagent")
|
||||
hideFromDependabot(":instrumentation:opensearch:opensearch-rest-common:javaagent")
|
||||
hideFromDependabot(":instrumentation:elasticsearch:elasticsearch-rest-common:library")
|
||||
hideFromDependabot(":instrumentation:elasticsearch:elasticsearch-rest-5.0:javaagent")
|
||||
hideFromDependabot(":instrumentation:elasticsearch:elasticsearch-rest-6.4:javaagent")
|
||||
hideFromDependabot(":instrumentation:elasticsearch:elasticsearch-rest-7.0:javaagent")
|
||||
hideFromDependabot(":instrumentation:opensearch:opensearch-rest-1.0:javaagent")
|
||||
hideFromDependabot(":instrumentation:elasticsearch:elasticsearch-rest-7.0:library")
|
||||
hideFromDependabot(":instrumentation:elasticsearch:elasticsearch-transport-common:javaagent")
|
||||
hideFromDependabot(":instrumentation:elasticsearch:elasticsearch-transport-common:testing")
|
||||
hideFromDependabot(":instrumentation:elasticsearch:elasticsearch-transport-5.0:javaagent")
|
||||
hideFromDependabot(":instrumentation:elasticsearch:elasticsearch-transport-5.3:javaagent")
|
||||
hideFromDependabot(":instrumentation:elasticsearch:elasticsearch-transport-6.0:javaagent")
|
||||
hideFromDependabot(":instrumentation:elasticsearch:elasticsearch-api-client-7.16:javaagent")
|
||||
hideFromDependabot(":instrumentation:elasticsearch:elasticsearch-api-client-7.16:javaagent-unit-tests")
|
||||
hideFromDependabot(":instrumentation:executors:bootstrap")
|
||||
hideFromDependabot(":instrumentation:executors:javaagent")
|
||||
hideFromDependabot(":instrumentation:executors:testing")
|
||||
|
|
@ -383,6 +383,8 @@ hideFromDependabot(":instrumentation:okhttp:okhttp-3.0:javaagent")
|
|||
hideFromDependabot(":instrumentation:okhttp:okhttp-3.0:library")
|
||||
hideFromDependabot(":instrumentation:okhttp:okhttp-3.0:testing")
|
||||
hideFromDependabot(":instrumentation:opencensus-shim:testing")
|
||||
hideFromDependabot(":instrumentation:opensearch:opensearch-rest-common:javaagent")
|
||||
hideFromDependabot(":instrumentation:opensearch:opensearch-rest-1.0:javaagent")
|
||||
hideFromDependabot(":instrumentation:opentelemetry-api:opentelemetry-api-1.0:javaagent")
|
||||
hideFromDependabot(":instrumentation:opentelemetry-api:opentelemetry-api-1.4:javaagent")
|
||||
hideFromDependabot(":instrumentation:opentelemetry-api:opentelemetry-api-1.10:javaagent")
|
||||
|
|
|
|||
Loading…
Reference in New Issue