elasticsarch-rest: add stable semconv request method handling (#9345)

This commit is contained in:
Lauri Tulmin 2023-08-30 18:34:11 +03:00 committed by GitHub
parent 0c40a4466b
commit bcd693f614
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 3 deletions

View File

@ -9,10 +9,14 @@ 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.api.instrumenter.http.HttpClientAttributesExtractorBuilder;
import io.opentelemetry.instrumentation.api.internal.HttpConstants;
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.ElasticsearchRestInstrumenterFactory;
import io.opentelemetry.instrumentation.elasticsearch.rest.internal.ElasticsearchRestRequest;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.elasticsearch.client.Response;
public final class ElasticsearchRest7TelemetryBuilder {
@ -22,6 +26,7 @@ public final class ElasticsearchRest7TelemetryBuilder {
private final OpenTelemetry openTelemetry;
private final List<AttributesExtractor<ElasticsearchRestRequest, Response>> attributesExtractors =
new ArrayList<>();
private Set<String> knownMethods = HttpConstants.KNOWN_METHODS;
ElasticsearchRest7TelemetryBuilder(OpenTelemetry openTelemetry) {
this.openTelemetry = openTelemetry;
@ -38,6 +43,25 @@ public final class ElasticsearchRest7TelemetryBuilder {
return this;
}
/**
* Configures the instrumentation to recognize an alternative set of HTTP request methods.
*
* <p>By default, this instrumentation defines "known" methods as the ones listed in <a
* href="https://www.rfc-editor.org/rfc/rfc9110.html#name-methods">RFC9110</a> and the PATCH
* method defined in <a href="https://www.rfc-editor.org/rfc/rfc5789.html">RFC5789</a>.
*
* <p>Note: calling this method <b>overrides</b> the default known method sets completely; it does
* not supplement it.
*
* @param knownMethods A set of recognized HTTP request methods.
* @see HttpClientAttributesExtractorBuilder#setKnownMethods(Set)
*/
@CanIgnoreReturnValue
public ElasticsearchRest7TelemetryBuilder setKnownMethods(Set<String> knownMethods) {
this.knownMethods = new HashSet<>(knownMethods);
return this;
}
/**
* Returns a new {@link ElasticsearchRest7Telemetry} with the settings of this {@link
* ElasticsearchRest7TelemetryBuilder}.
@ -45,7 +69,7 @@ public final class ElasticsearchRest7TelemetryBuilder {
public ElasticsearchRest7Telemetry build() {
Instrumenter<ElasticsearchRestRequest, Response> instrumenter =
ElasticsearchRestInstrumenterFactory.create(
openTelemetry, INSTRUMENTATION_NAME, attributesExtractors, false);
openTelemetry, INSTRUMENTATION_NAME, attributesExtractors, knownMethods, false);
return new ElasticsearchRest7Telemetry(instrumenter);
}

View File

@ -9,6 +9,7 @@ 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.CommonConfig;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import java.util.Collections;
import org.elasticsearch.client.Response;
@ -27,6 +28,7 @@ public final class ElasticsearchRestJavaagentInstrumenterFactory {
GlobalOpenTelemetry.get(),
instrumentationName,
Collections.emptyList(),
CommonConfig.get().getKnownHttpRequestMethods(),
CAPTURE_SEARCH_QUERY);
}
}

View File

@ -6,16 +6,20 @@
package io.opentelemetry.instrumentation.elasticsearch.rest.internal;
import static io.opentelemetry.instrumentation.api.internal.AttributesExtractorUtil.internalSet;
import static io.opentelemetry.instrumentation.api.internal.HttpConstants._OTHER;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.internal.HttpAttributes;
import io.opentelemetry.instrumentation.api.instrumenter.network.internal.NetworkAttributes;
import io.opentelemetry.instrumentation.api.instrumenter.url.internal.UrlAttributes;
import io.opentelemetry.instrumentation.api.internal.SemconvStability;
import io.opentelemetry.instrumentation.api.internal.cache.Cache;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Nullable;
import org.apache.http.HttpHost;
import org.elasticsearch.client.Response;
@ -31,6 +35,12 @@ public class ElasticsearchClientAttributeExtractor
private static final Cache<String, AttributeKey<String>> pathPartKeysCache = Cache.bounded(64);
private final Set<String> knownMethods;
ElasticsearchClientAttributeExtractor(Set<String> knownMethods) {
this.knownMethods = new HashSet<>(knownMethods);
}
private static void setServerAttributes(AttributesBuilder attributes, Response response) {
HttpHost host = response.getHost();
if (host != null) {
@ -79,7 +89,18 @@ public class ElasticsearchClientAttributeExtractor
@Override
public void onStart(
AttributesBuilder attributes, Context parentContext, ElasticsearchRestRequest request) {
internalSet(attributes, SemanticAttributes.HTTP_METHOD, request.getMethod());
String method = request.getMethod();
if (SemconvStability.emitStableHttpSemconv()) {
if (method == null || knownMethods.contains(method)) {
internalSet(attributes, HttpAttributes.HTTP_REQUEST_METHOD, method);
} else {
internalSet(attributes, HttpAttributes.HTTP_REQUEST_METHOD, _OTHER);
internalSet(attributes, HttpAttributes.HTTP_REQUEST_METHOD_ORIGINAL, method);
}
}
if (SemconvStability.emitOldHttpSemconv()) {
internalSet(attributes, SemanticAttributes.HTTP_METHOD, method);
}
setPathPartsAttributes(attributes, request);
}

View File

@ -11,6 +11,7 @@ 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 java.util.Set;
import org.elasticsearch.client.Response;
/**
@ -25,11 +26,12 @@ public final class ElasticsearchRestInstrumenterFactory {
OpenTelemetry opentelemetry,
String instrumentationName,
List<AttributesExtractor<ElasticsearchRestRequest, Response>> attributesExtractors,
Set<String> knownMethods,
boolean captureSearchQuery) {
ElasticsearchDbAttributesGetter dbClientAttributesGetter =
new ElasticsearchDbAttributesGetter(captureSearchQuery);
ElasticsearchClientAttributeExtractor esClientAtrributesExtractor =
new ElasticsearchClientAttributeExtractor();
new ElasticsearchClientAttributeExtractor(knownMethods);
ElasticsearchSpanNameExtractor nameExtractor =
new ElasticsearchSpanNameExtractor(dbClientAttributesGetter);