Move rest of non-specd attributes to experimental (#2402)

This commit is contained in:
Trask Stalnaker 2021-02-26 20:50:47 -08:00 committed by GitHub
parent fd55ce226a
commit 03bfaee5eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 282 additions and 195 deletions

View File

@ -52,3 +52,9 @@ dependencies {
latestDepTestLibrary group: 'org.apache.camel', name: 'camel-undertow', version: '2.+' latestDepTestLibrary group: 'org.apache.camel', name: 'camel-undertow', version: '2.+'
latestDepTestLibrary group: 'org.apache.camel', name: 'camel-aws', version: '2.+' latestDepTestLibrary group: 'org.apache.camel', name: 'camel-aws', version: '2.+'
} }
tasks.withType(Test) {
// TODO run tests both with and without experimental span attributes
jvmArgs "-Dotel.instrumentation.apache-camel.experimental-span-attributes=true"
jvmArgs "-Dotel.instrumentation.aws-sdk.experimental-span-attributes=true"
}

View File

@ -26,6 +26,7 @@ package io.opentelemetry.javaagent.instrumentation.apachecamel.decorators;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.api.trace.StatusCode; import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.javaagent.instrumentation.apachecamel.CamelDirection; import io.opentelemetry.javaagent.instrumentation.apachecamel.CamelDirection;
import io.opentelemetry.javaagent.instrumentation.apachecamel.SpanDecorator; import io.opentelemetry.javaagent.instrumentation.apachecamel.SpanDecorator;
import java.util.Collections; import java.util.Collections;
@ -39,6 +40,11 @@ import org.apache.camel.util.URISupport;
/** An abstract base implementation of the {@link SpanDecorator} interface. */ /** An abstract base implementation of the {@link SpanDecorator} interface. */
class BaseSpanDecorator implements SpanDecorator { class BaseSpanDecorator implements SpanDecorator {
static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get()
.getBooleanProperty(
"otel.instrumentation.apache-camel.experimental-span-attributes", false);
static final String DEFAULT_OPERATION_NAME = "CamelOperation"; static final String DEFAULT_OPERATION_NAME = "CamelOperation";
/** /**
@ -92,7 +98,9 @@ class BaseSpanDecorator implements SpanDecorator {
@Override @Override
public void pre(Span span, Exchange exchange, Endpoint endpoint, CamelDirection camelDirection) { public void pre(Span span, Exchange exchange, Endpoint endpoint, CamelDirection camelDirection) {
span.setAttribute("apache-camel.uri", URISupport.sanitizeUri(endpoint.getEndpointUri())); if (CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES) {
span.setAttribute("apache-camel.uri", URISupport.sanitizeUri(endpoint.getEndpointUri()));
}
} }
@Override @Override

View File

@ -64,19 +64,21 @@ class KafkaSpanDecorator extends MessagingSpanDecorator {
span.setAttribute(SemanticAttributes.MESSAGING_KAFKA_PARTITION, partition); span.setAttribute(SemanticAttributes.MESSAGING_KAFKA_PARTITION, partition);
} }
String partitionKey = (String) exchange.getIn().getHeader(PARTITION_KEY); if (CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES) {
if (partitionKey != null) { String partitionKey = (String) exchange.getIn().getHeader(PARTITION_KEY);
span.setAttribute("apache-camel.kafka.partitionKey", partitionKey); if (partitionKey != null) {
} span.setAttribute("apache-camel.kafka.partitionKey", partitionKey);
}
String key = (String) exchange.getIn().getHeader(KEY); String key = (String) exchange.getIn().getHeader(KEY);
if (key != null) { if (key != null) {
span.setAttribute("apache-camel.kafka.key", key); span.setAttribute("apache-camel.kafka.key", key);
} }
String offset = getValue(exchange, OFFSET, Long.class); String offset = getValue(exchange, OFFSET, Long.class);
if (offset != null) { if (offset != null) {
span.setAttribute("apache-camel.kafka.offset", offset); span.setAttribute("apache-camel.kafka.offset", offset);
}
} }
} }

View File

@ -84,3 +84,8 @@ test {
if (!testLatestDeps) { if (!testLatestDeps) {
test.dependsOn test_before_1_11_106 test.dependsOn test_before_1_11_106
} }
tasks.withType(Test) {
// TODO run tests both with and without experimental span attributes
jvmArgs "-Dotel.instrumentation.aws-sdk.experimental-span-attributes=true"
}

View File

@ -14,12 +14,17 @@ import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context; import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.TextMapSetter; import io.opentelemetry.context.propagation.TextMapSetter;
import io.opentelemetry.extension.aws.AwsXrayPropagator; import io.opentelemetry.extension.aws.AwsXrayPropagator;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.tracer.HttpClientTracer; import io.opentelemetry.instrumentation.api.tracer.HttpClientTracer;
import java.net.URI; import java.net.URI;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
public class AwsSdkClientTracer extends HttpClientTracer<Request<?>, Request<?>, Response<?>> { public class AwsSdkClientTracer extends HttpClientTracer<Request<?>, Request<?>, Response<?>> {
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get()
.getBooleanProperty("otel.instrumentation.aws-sdk.experimental-span-attributes", false);
static final String COMPONENT_NAME = "java-aws-sdk"; static final String COMPONENT_NAME = "java-aws-sdk";
private static final AwsSdkClientTracer TRACER = new AwsSdkClientTracer(); private static final AwsSdkClientTracer TRACER = new AwsSdkClientTracer();
@ -56,25 +61,29 @@ public class AwsSdkClientTracer extends HttpClientTracer<Request<?>, Request<?>,
AmazonWebServiceRequest originalRequest = request.getOriginalRequest(); AmazonWebServiceRequest originalRequest = request.getOriginalRequest();
Class<?> awsOperation = originalRequest.getClass(); Class<?> awsOperation = originalRequest.getClass();
span.setAttribute("aws.agent", COMPONENT_NAME); if (CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES) {
span.setAttribute("aws.service", awsServiceName); span.setAttribute("aws.agent", COMPONENT_NAME);
span.setAttribute("aws.operation", awsOperation.getSimpleName()); span.setAttribute("aws.service", awsServiceName);
span.setAttribute("aws.endpoint", request.getEndpoint().toString()); span.setAttribute("aws.operation", awsOperation.getSimpleName());
span.setAttribute("aws.endpoint", request.getEndpoint().toString());
if (requestMeta != null) { if (requestMeta != null) {
span.setAttribute("aws.bucket.name", requestMeta.getBucketName()); span.setAttribute("aws.bucket.name", requestMeta.getBucketName());
span.setAttribute("aws.queue.url", requestMeta.getQueueUrl()); span.setAttribute("aws.queue.url", requestMeta.getQueueUrl());
span.setAttribute("aws.queue.name", requestMeta.getQueueName()); span.setAttribute("aws.queue.name", requestMeta.getQueueName());
span.setAttribute("aws.stream.name", requestMeta.getStreamName()); span.setAttribute("aws.stream.name", requestMeta.getStreamName());
span.setAttribute("aws.table.name", requestMeta.getTableName()); span.setAttribute("aws.table.name", requestMeta.getTableName());
}
} }
return context; return context;
} }
@Override @Override
public void onResponse(Span span, Response<?> response) { public void onResponse(Span span, Response<?> response) {
if (response != null && response.getAwsResponse() instanceof AmazonWebServiceResponse) { if (CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES
AmazonWebServiceResponse awsResp = (AmazonWebServiceResponse) response.getAwsResponse(); && response != null
&& response.getAwsResponse() instanceof AmazonWebServiceResponse) {
AmazonWebServiceResponse<?> awsResp = (AmazonWebServiceResponse<?>) response.getAwsResponse();
span.setAttribute("aws.requestId", awsResp.getRequestId()); span.setAttribute("aws.requestId", awsResp.getRequestId());
} }
super.onResponse(span, response); super.onResponse(span, response);

View File

@ -39,3 +39,8 @@ dependencies {
testImplementation group: 'org.elasticsearch.plugin', name: 'transport-netty3-client', version: '5.0.0' testImplementation group: 'org.elasticsearch.plugin', name: 'transport-netty3-client', version: '5.0.0'
testImplementation group: 'org.elasticsearch.client', name: 'transport', version: '5.0.0' testImplementation group: 'org.elasticsearch.client', name: 'transport', version: '5.0.0'
} }
tasks.withType(Test) {
// TODO run tests both with and without experimental span attributes
jvmArgs "-Dotel.instrumentation.elasticsearch.experimental-span-attributes=true"
}

View File

@ -9,6 +9,7 @@ import static io.opentelemetry.javaagent.instrumentation.elasticsearch.transport
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context; import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.tracer.utils.NetPeerUtils; import io.opentelemetry.instrumentation.api.tracer.utils.NetPeerUtils;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionListener;
@ -26,6 +27,11 @@ import org.elasticsearch.action.support.replication.ReplicationResponse;
public class TransportActionListener<T extends ActionResponse> implements ActionListener<T> { public class TransportActionListener<T extends ActionResponse> implements ActionListener<T> {
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get()
.getBooleanProperty(
"otel.instrumentation.elasticsearch.experimental-span-attributes", false);
private final ActionListener<T> listener; private final ActionListener<T> listener;
private final Context context; private final Context context;
@ -36,27 +42,29 @@ public class TransportActionListener<T extends ActionResponse> implements Action
onRequest(actionRequest); onRequest(actionRequest);
} }
private void onRequest(ActionRequest request) { private void onRequest(ActionRequest<?> request) {
Span span = Span.fromContext(context); if (CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES) {
Span span = Span.fromContext(context);
if (request instanceof IndicesRequest) { if (request instanceof IndicesRequest) {
IndicesRequest req = (IndicesRequest) request; IndicesRequest req = (IndicesRequest) request;
String[] indices = req.indices(); String[] indices = req.indices();
if (indices != null && indices.length > 0) { if (indices != null && indices.length > 0) {
span.setAttribute("elasticsearch.request.indices", String.join(",", indices)); span.setAttribute("elasticsearch.request.indices", String.join(",", indices));
}
} }
} if (request instanceof SearchRequest) {
if (request instanceof SearchRequest) { SearchRequest req = (SearchRequest) request;
SearchRequest req = (SearchRequest) request; String[] types = req.types();
String[] types = req.types(); if (types != null && types.length > 0) {
if (types != null && types.length > 0) { span.setAttribute("elasticsearch.request.search.types", String.join(",", types));
span.setAttribute("elasticsearch.request.search.types", String.join(",", types)); }
}
if (request instanceof DocumentRequest) {
DocumentRequest<?> req = (DocumentRequest<?>) request;
span.setAttribute("elasticsearch.request.write.type", req.type());
span.setAttribute("elasticsearch.request.write.routing", req.routing());
} }
}
if (request instanceof DocumentRequest) {
DocumentRequest req = (DocumentRequest) request;
span.setAttribute("elasticsearch.request.write.type", req.type());
span.setAttribute("elasticsearch.request.write.routing", req.routing());
} }
} }
@ -71,45 +79,48 @@ public class TransportActionListener<T extends ActionResponse> implements Action
SemanticAttributes.NET_PEER_PORT, (long) response.remoteAddress().getPort()); SemanticAttributes.NET_PEER_PORT, (long) response.remoteAddress().getPort());
} }
if (response instanceof GetResponse) { if (CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES) {
GetResponse resp = (GetResponse) response; if (response instanceof GetResponse) {
span.setAttribute("elasticsearch.type", resp.getType()); GetResponse resp = (GetResponse) response;
span.setAttribute("elasticsearch.id", resp.getId()); span.setAttribute("elasticsearch.type", resp.getType());
span.setAttribute("elasticsearch.version", resp.getVersion()); span.setAttribute("elasticsearch.id", resp.getId());
} span.setAttribute("elasticsearch.version", resp.getVersion());
}
if (response instanceof BroadcastResponse) {
BroadcastResponse resp = (BroadcastResponse) response; if (response instanceof BroadcastResponse) {
span.setAttribute("elasticsearch.shard.broadcast.total", resp.getTotalShards()); BroadcastResponse resp = (BroadcastResponse) response;
span.setAttribute("elasticsearch.shard.broadcast.successful", resp.getSuccessfulShards()); span.setAttribute("elasticsearch.shard.broadcast.total", resp.getTotalShards());
span.setAttribute("elasticsearch.shard.broadcast.failed", resp.getFailedShards()); span.setAttribute("elasticsearch.shard.broadcast.successful", resp.getSuccessfulShards());
} span.setAttribute("elasticsearch.shard.broadcast.failed", resp.getFailedShards());
}
if (response instanceof ReplicationResponse) {
ReplicationResponse resp = (ReplicationResponse) response; if (response instanceof ReplicationResponse) {
span.setAttribute("elasticsearch.shard.replication.total", resp.getShardInfo().getTotal()); ReplicationResponse resp = (ReplicationResponse) response;
span.setAttribute( span.setAttribute("elasticsearch.shard.replication.total", resp.getShardInfo().getTotal());
"elasticsearch.shard.replication.successful", resp.getShardInfo().getSuccessful()); span.setAttribute(
span.setAttribute("elasticsearch.shard.replication.failed", resp.getShardInfo().getFailed()); "elasticsearch.shard.replication.successful", resp.getShardInfo().getSuccessful());
} span.setAttribute(
"elasticsearch.shard.replication.failed", resp.getShardInfo().getFailed());
if (response instanceof IndexResponse) { }
span.setAttribute(
"elasticsearch.response.status", ((IndexResponse) response).status().getStatus()); if (response instanceof IndexResponse) {
} span.setAttribute(
"elasticsearch.response.status", ((IndexResponse) response).status().getStatus());
if (response instanceof BulkShardResponse) { }
BulkShardResponse resp = (BulkShardResponse) response;
span.setAttribute("elasticsearch.shard.bulk.id", resp.getShardId().getId()); if (response instanceof BulkShardResponse) {
span.setAttribute("elasticsearch.shard.bulk.index", resp.getShardId().getIndexName()); BulkShardResponse resp = (BulkShardResponse) response;
} span.setAttribute("elasticsearch.shard.bulk.id", resp.getShardId().getId());
span.setAttribute("elasticsearch.shard.bulk.index", resp.getShardId().getIndexName());
if (response instanceof BaseNodesResponse) { }
BaseNodesResponse resp = (BaseNodesResponse) response;
if (resp.hasFailures()) { if (response instanceof BaseNodesResponse) {
span.setAttribute("elasticsearch.node.failures", resp.failures().size()); BaseNodesResponse<?> resp = (BaseNodesResponse<?>) response;
if (resp.hasFailures()) {
span.setAttribute("elasticsearch.node.failures", resp.failures().size());
}
span.setAttribute("elasticsearch.node.cluster.name", resp.getClusterName().value());
} }
span.setAttribute("elasticsearch.node.cluster.name", resp.getClusterName().value());
} }
tracer().end(span); tracer().end(span);

View File

@ -44,3 +44,8 @@ dependencies {
latestDepTestLibrary group: 'org.elasticsearch.client', name: 'transport', version: '5.+' latestDepTestLibrary group: 'org.elasticsearch.client', name: 'transport', version: '5.+'
latestDepTestLibrary group: 'org.springframework.data', name: 'spring-data-elasticsearch', version: '3.0.+' latestDepTestLibrary group: 'org.springframework.data', name: 'spring-data-elasticsearch', version: '3.0.+'
} }
tasks.withType(Test) {
// TODO run tests both with and without experimental span attributes
jvmArgs "-Dotel.instrumentation.elasticsearch.experimental-span-attributes=true"
}

View File

@ -9,6 +9,7 @@ import static io.opentelemetry.javaagent.instrumentation.elasticsearch.transport
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context; import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.tracer.utils.NetPeerUtils; import io.opentelemetry.instrumentation.api.tracer.utils.NetPeerUtils;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionListener;
@ -26,6 +27,11 @@ import org.elasticsearch.action.support.replication.ReplicationResponse;
public class TransportActionListener<T extends ActionResponse> implements ActionListener<T> { public class TransportActionListener<T extends ActionResponse> implements ActionListener<T> {
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get()
.getBooleanProperty(
"otel.instrumentation.elasticsearch.experimental-span-attributes", false);
private final ActionListener<T> listener; private final ActionListener<T> listener;
private final Context context; private final Context context;
@ -37,27 +43,29 @@ public class TransportActionListener<T extends ActionResponse> implements Action
} }
private void onRequest(ActionRequest request) { private void onRequest(ActionRequest request) {
Span span = Span.fromContext(context); if (CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES) {
Span span = Span.fromContext(context);
if (request instanceof IndicesRequest) { if (request instanceof IndicesRequest) {
IndicesRequest req = (IndicesRequest) request; IndicesRequest req = (IndicesRequest) request;
String[] indices = req.indices(); String[] indices = req.indices();
if (indices != null && indices.length > 0) { if (indices != null && indices.length > 0) {
span.setAttribute("elasticsearch.request.indices", String.join(",", indices)); span.setAttribute("elasticsearch.request.indices", String.join(",", indices));
}
} }
} if (request instanceof SearchRequest) {
if (request instanceof SearchRequest) { SearchRequest req = (SearchRequest) request;
SearchRequest req = (SearchRequest) request; String[] types = req.types();
String[] types = req.types(); if (types != null && types.length > 0) {
if (types != null && types.length > 0) { span.setAttribute("elasticsearch.request.search.types", String.join(",", types));
span.setAttribute("elasticsearch.request.search.types", String.join(",", types)); }
}
if (request instanceof DocWriteRequest) {
DocWriteRequest<?> req = (DocWriteRequest<?>) request;
span.setAttribute("elasticsearch.request.write.type", req.type());
span.setAttribute("elasticsearch.request.write.routing", req.routing());
span.setAttribute("elasticsearch.request.write.version", req.version());
} }
}
if (request instanceof DocWriteRequest) {
DocWriteRequest req = (DocWriteRequest) request;
span.setAttribute("elasticsearch.request.write.type", req.type());
span.setAttribute("elasticsearch.request.write.routing", req.routing());
span.setAttribute("elasticsearch.request.write.version", req.version());
} }
} }
@ -72,45 +80,48 @@ public class TransportActionListener<T extends ActionResponse> implements Action
SemanticAttributes.NET_PEER_PORT, (long) response.remoteAddress().getPort()); SemanticAttributes.NET_PEER_PORT, (long) response.remoteAddress().getPort());
} }
if (response instanceof GetResponse) { if (CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES) {
GetResponse resp = (GetResponse) response; if (response instanceof GetResponse) {
span.setAttribute("elasticsearch.type", resp.getType()); GetResponse resp = (GetResponse) response;
span.setAttribute("elasticsearch.id", resp.getId()); span.setAttribute("elasticsearch.type", resp.getType());
span.setAttribute("elasticsearch.version", resp.getVersion()); span.setAttribute("elasticsearch.id", resp.getId());
} span.setAttribute("elasticsearch.version", resp.getVersion());
}
if (response instanceof BroadcastResponse) {
BroadcastResponse resp = (BroadcastResponse) response; if (response instanceof BroadcastResponse) {
span.setAttribute("elasticsearch.shard.broadcast.total", resp.getTotalShards()); BroadcastResponse resp = (BroadcastResponse) response;
span.setAttribute("elasticsearch.shard.broadcast.successful", resp.getSuccessfulShards()); span.setAttribute("elasticsearch.shard.broadcast.total", resp.getTotalShards());
span.setAttribute("elasticsearch.shard.broadcast.failed", resp.getFailedShards()); span.setAttribute("elasticsearch.shard.broadcast.successful", resp.getSuccessfulShards());
} span.setAttribute("elasticsearch.shard.broadcast.failed", resp.getFailedShards());
}
if (response instanceof ReplicationResponse) {
ReplicationResponse resp = (ReplicationResponse) response; if (response instanceof ReplicationResponse) {
span.setAttribute("elasticsearch.shard.replication.total", resp.getShardInfo().getTotal()); ReplicationResponse resp = (ReplicationResponse) response;
span.setAttribute( span.setAttribute("elasticsearch.shard.replication.total", resp.getShardInfo().getTotal());
"elasticsearch.shard.replication.successful", resp.getShardInfo().getSuccessful()); span.setAttribute(
span.setAttribute("elasticsearch.shard.replication.failed", resp.getShardInfo().getFailed()); "elasticsearch.shard.replication.successful", resp.getShardInfo().getSuccessful());
} span.setAttribute(
"elasticsearch.shard.replication.failed", resp.getShardInfo().getFailed());
if (response instanceof IndexResponse) { }
span.setAttribute(
"elasticsearch.response.status", ((IndexResponse) response).status().getStatus()); if (response instanceof IndexResponse) {
} span.setAttribute(
"elasticsearch.response.status", ((IndexResponse) response).status().getStatus());
if (response instanceof BulkShardResponse) { }
BulkShardResponse resp = (BulkShardResponse) response;
span.setAttribute("elasticsearch.shard.bulk.id", resp.getShardId().getId()); if (response instanceof BulkShardResponse) {
span.setAttribute("elasticsearch.shard.bulk.index", resp.getShardId().getIndexName()); BulkShardResponse resp = (BulkShardResponse) response;
} span.setAttribute("elasticsearch.shard.bulk.id", resp.getShardId().getId());
span.setAttribute("elasticsearch.shard.bulk.index", resp.getShardId().getIndexName());
if (response instanceof BaseNodesResponse) { }
BaseNodesResponse resp = (BaseNodesResponse) response;
if (resp.hasFailures()) { if (response instanceof BaseNodesResponse) {
span.setAttribute("elasticsearch.node.failures", resp.failures().size()); BaseNodesResponse<?> resp = (BaseNodesResponse<?>) response;
if (resp.hasFailures()) {
span.setAttribute("elasticsearch.node.failures", resp.failures().size());
}
span.setAttribute("elasticsearch.node.cluster.name", resp.getClusterName().value());
} }
span.setAttribute("elasticsearch.node.cluster.name", resp.getClusterName().value());
} }
tracer().end(span); tracer().end(span);

View File

@ -42,3 +42,8 @@ dependencies {
latestDepTestLibrary group: 'org.elasticsearch.plugin', name: 'transport-netty4-client', version: '(6.1,6.5)' latestDepTestLibrary group: 'org.elasticsearch.plugin', name: 'transport-netty4-client', version: '(6.1,6.5)'
latestDepTestLibrary group: 'org.elasticsearch.client', name: 'transport', version: '(6.1,6.5)' latestDepTestLibrary group: 'org.elasticsearch.client', name: 'transport', version: '(6.1,6.5)'
} }
tasks.withType(Test) {
// TODO run tests both with and without experimental span attributes
jvmArgs "-Dotel.instrumentation.elasticsearch.experimental-span-attributes=true"
}

View File

@ -9,6 +9,7 @@ import static io.opentelemetry.javaagent.instrumentation.elasticsearch.transport
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context; import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.tracer.utils.NetPeerUtils; import io.opentelemetry.instrumentation.api.tracer.utils.NetPeerUtils;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionListener;
@ -30,6 +31,11 @@ import org.elasticsearch.action.support.replication.ReplicationResponse;
*/ */
public class TransportActionListener<T extends ActionResponse> implements ActionListener<T> { public class TransportActionListener<T extends ActionResponse> implements ActionListener<T> {
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get()
.getBooleanProperty(
"otel.instrumentation.elasticsearch.experimental-span-attributes", false);
private final ActionListener<T> listener; private final ActionListener<T> listener;
private final Context context; private final Context context;
@ -41,26 +47,28 @@ public class TransportActionListener<T extends ActionResponse> implements Action
} }
private void onRequest(ActionRequest request) { private void onRequest(ActionRequest request) {
Span span = Span.fromContext(context); if (CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES) {
if (request instanceof IndicesRequest) { Span span = Span.fromContext(context);
IndicesRequest req = (IndicesRequest) request; if (request instanceof IndicesRequest) {
String[] indices = req.indices(); IndicesRequest req = (IndicesRequest) request;
if (indices != null && indices.length > 0) { String[] indices = req.indices();
span.setAttribute("elasticsearch.request.indices", String.join(",", indices)); if (indices != null && indices.length > 0) {
span.setAttribute("elasticsearch.request.indices", String.join(",", indices));
}
} }
} if (request instanceof SearchRequest) {
if (request instanceof SearchRequest) { SearchRequest req = (SearchRequest) request;
SearchRequest req = (SearchRequest) request; String[] types = req.types();
String[] types = req.types(); if (types != null && types.length > 0) {
if (types != null && types.length > 0) { span.setAttribute("elasticsearch.request.search.types", String.join(",", types));
span.setAttribute("elasticsearch.request.search.types", String.join(",", types)); }
}
if (request instanceof DocWriteRequest) {
DocWriteRequest<?> req = (DocWriteRequest<?>) request;
span.setAttribute("elasticsearch.request.write.type", req.type());
span.setAttribute("elasticsearch.request.write.routing", req.routing());
span.setAttribute("elasticsearch.request.write.version", req.version());
} }
}
if (request instanceof DocWriteRequest) {
DocWriteRequest req = (DocWriteRequest) request;
span.setAttribute("elasticsearch.request.write.type", req.type());
span.setAttribute("elasticsearch.request.write.routing", req.routing());
span.setAttribute("elasticsearch.request.write.version", req.version());
} }
} }
@ -77,45 +85,48 @@ public class TransportActionListener<T extends ActionResponse> implements Action
SemanticAttributes.NET_PEER_PORT, (long) response.remoteAddress().getPort()); SemanticAttributes.NET_PEER_PORT, (long) response.remoteAddress().getPort());
} }
if (response instanceof GetResponse) { if (CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES) {
GetResponse resp = (GetResponse) response; if (response instanceof GetResponse) {
span.setAttribute("elasticsearch.type", resp.getType()); GetResponse resp = (GetResponse) response;
span.setAttribute("elasticsearch.id", resp.getId()); span.setAttribute("elasticsearch.type", resp.getType());
span.setAttribute("elasticsearch.version", resp.getVersion()); span.setAttribute("elasticsearch.id", resp.getId());
} span.setAttribute("elasticsearch.version", resp.getVersion());
}
if (response instanceof BroadcastResponse) {
BroadcastResponse resp = (BroadcastResponse) response; if (response instanceof BroadcastResponse) {
span.setAttribute("elasticsearch.shard.broadcast.total", resp.getTotalShards()); BroadcastResponse resp = (BroadcastResponse) response;
span.setAttribute("elasticsearch.shard.broadcast.successful", resp.getSuccessfulShards()); span.setAttribute("elasticsearch.shard.broadcast.total", resp.getTotalShards());
span.setAttribute("elasticsearch.shard.broadcast.failed", resp.getFailedShards()); span.setAttribute("elasticsearch.shard.broadcast.successful", resp.getSuccessfulShards());
} span.setAttribute("elasticsearch.shard.broadcast.failed", resp.getFailedShards());
}
if (response instanceof ReplicationResponse) {
ReplicationResponse resp = (ReplicationResponse) response; if (response instanceof ReplicationResponse) {
span.setAttribute("elasticsearch.shard.replication.total", resp.getShardInfo().getTotal()); ReplicationResponse resp = (ReplicationResponse) response;
span.setAttribute( span.setAttribute("elasticsearch.shard.replication.total", resp.getShardInfo().getTotal());
"elasticsearch.shard.replication.successful", resp.getShardInfo().getSuccessful()); span.setAttribute(
span.setAttribute("elasticsearch.shard.replication.failed", resp.getShardInfo().getFailed()); "elasticsearch.shard.replication.successful", resp.getShardInfo().getSuccessful());
} span.setAttribute(
"elasticsearch.shard.replication.failed", resp.getShardInfo().getFailed());
if (response instanceof IndexResponse) { }
span.setAttribute(
"elasticsearch.response.status", ((IndexResponse) response).status().getStatus()); if (response instanceof IndexResponse) {
} span.setAttribute(
"elasticsearch.response.status", ((IndexResponse) response).status().getStatus());
if (response instanceof BulkShardResponse) { }
BulkShardResponse resp = (BulkShardResponse) response;
span.setAttribute("elasticsearch.shard.bulk.id", resp.getShardId().getId()); if (response instanceof BulkShardResponse) {
span.setAttribute("elasticsearch.shard.bulk.index", resp.getShardId().getIndexName()); BulkShardResponse resp = (BulkShardResponse) response;
} span.setAttribute("elasticsearch.shard.bulk.id", resp.getShardId().getId());
span.setAttribute("elasticsearch.shard.bulk.index", resp.getShardId().getIndexName());
if (response instanceof BaseNodesResponse) { }
BaseNodesResponse resp = (BaseNodesResponse) response;
if (resp.hasFailures()) { if (response instanceof BaseNodesResponse) {
span.setAttribute("elasticsearch.node.failures", resp.failures().size()); BaseNodesResponse<?> resp = (BaseNodesResponse<?>) response;
if (resp.hasFailures()) {
span.setAttribute("elasticsearch.node.failures", resp.failures().size());
}
span.setAttribute("elasticsearch.node.cluster.name", resp.getClusterName().value());
} }
span.setAttribute("elasticsearch.node.cluster.name", resp.getClusterName().value());
} }
tracer().end(context); tracer().end(context);

View File

@ -7,12 +7,19 @@ package io.opentelemetry.javaagent.instrumentation.elasticsearch.transport;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context; import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.tracer.DatabaseClientTracer; import io.opentelemetry.instrumentation.api.tracer.DatabaseClientTracer;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import org.elasticsearch.action.Action; import org.elasticsearch.action.Action;
public class ElasticsearchTransportClientTracer public class ElasticsearchTransportClientTracer
extends DatabaseClientTracer<Void, Action<?, ?, ?>, String> { extends DatabaseClientTracer<Void, Action<?, ?, ?>, String> {
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get()
.getBooleanProperty(
"otel.instrumentation.elasticsearch.experimental-span-attributes", false);
private static final ElasticsearchTransportClientTracer TRACER = private static final ElasticsearchTransportClientTracer TRACER =
new ElasticsearchTransportClientTracer(); new ElasticsearchTransportClientTracer();
@ -21,9 +28,11 @@ public class ElasticsearchTransportClientTracer
} }
public void onRequest(Context context, Class<?> action, Class<?> request) { public void onRequest(Context context, Class<?> action, Class<?> request) {
Span span = Span.fromContext(context); if (CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES) {
span.setAttribute("elasticsearch.action", action.getSimpleName()); Span span = Span.fromContext(context);
span.setAttribute("elasticsearch.request", request.getSimpleName()); span.setAttribute("elasticsearch.action", action.getSimpleName());
span.setAttribute("elasticsearch.request", request.getSimpleName());
}
} }
@Override @Override