Skip to content

Commit a9dfdcc

Browse files
Merge pull request #6232 from DataDog/bbujon/otel-span-kind
Store OpenTelemetry span kind as tag instead of span type
2 parents 6067ac3 + 3c85c5d commit a9dfdcc

File tree

6 files changed

+91
-100
lines changed

6 files changed

+91
-100
lines changed

dd-java-agent/instrumentation/opentelemetry/opentelemetry-1.4/src/main/java/datadog/trace/instrumentation/opentelemetry14/trace/OtelConventions.java

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package datadog.trace.instrumentation.opentelemetry14.trace;
22

33
import static datadog.trace.api.DDTags.ANALYTICS_SAMPLE_RATE;
4+
import static datadog.trace.bootstrap.instrumentation.api.Tags.SPAN_KIND;
45
import static datadog.trace.bootstrap.instrumentation.api.Tags.SPAN_KIND_CLIENT;
56
import static datadog.trace.bootstrap.instrumentation.api.Tags.SPAN_KIND_CONSUMER;
67
import static datadog.trace.bootstrap.instrumentation.api.Tags.SPAN_KIND_PRODUCER;
@@ -13,6 +14,7 @@
1314
import static java.util.Locale.ROOT;
1415

1516
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
17+
import datadog.trace.bootstrap.instrumentation.api.Tags;
1618
import io.opentelemetry.api.trace.SpanKind;
1719
import javax.annotation.Nullable;
1820
import org.slf4j.Logger;
@@ -22,20 +24,17 @@ public final class OtelConventions {
2224
static final String SPAN_KIND_INTERNAL = "internal";
2325
private static final Logger LOGGER = LoggerFactory.getLogger(OtelConventions.class);
2426
private static final String OPERATION_NAME_SPECIFIC_ATTRIBUTE = "operation.name";
25-
private static final String SERVICE_NAME_SPECIFIC_ATTRIBUTE = "service.name";
26-
private static final String RESOURCE_NAME_SPECIFIC_ATTRIBUTE = "resource.name";
27-
private static final String SPAN_TYPE_SPECIFIC_ATTRIBUTES = "span.type";
2827
private static final String ANALYTICS_EVENT_SPECIFIC_ATTRIBUTES = "analytics.event";
2928

3029
private OtelConventions() {}
3130

3231
/**
33-
* Convert OpenTelemetry {@link SpanKind} to Datadog span type.
32+
* Convert OpenTelemetry {@link SpanKind} to {@link Tags#SPAN_KIND} value.
3433
*
3534
* @param spanKind The OpenTelemetry span kind to convert.
36-
* @return The related Datadog span type.
35+
* @return The {@link Tags#SPAN_KIND} value.
3736
*/
38-
public static String toSpanType(SpanKind spanKind) {
37+
public static String toSpanKindTagValue(SpanKind spanKind) {
3938
switch (spanKind) {
4039
case CLIENT:
4140
return SPAN_KIND_CLIENT;
@@ -53,16 +52,16 @@ public static String toSpanType(SpanKind spanKind) {
5352
}
5453

5554
/**
56-
* Convert Datadog span type to OpenTelemetry {@link SpanKind}.
55+
* Convert {@link Tags#SPAN_KIND} value to OpenTelemetry {@link SpanKind}.
5756
*
58-
* @param spanType The span type to convert.
57+
* @param spanKind The {@link Tags#SPAN_KIND} value to convert.
5958
* @return The related OpenTelemetry {@link SpanKind}.
6059
*/
61-
public static SpanKind toSpanKind(String spanType) {
62-
if (spanType == null) {
60+
public static SpanKind toOtelSpanKind(String spanKind) {
61+
if (spanKind == null) {
6362
return INTERNAL;
6463
}
65-
switch (spanType) {
64+
switch (spanKind) {
6665
case SPAN_KIND_CLIENT:
6766
return CLIENT;
6867
case SPAN_KIND_SERVER:
@@ -77,26 +76,17 @@ public static SpanKind toSpanKind(String spanType) {
7776
}
7877

7978
public static void applyConventions(AgentSpan span) {
80-
String serviceName = getStringAttribute(span, SERVICE_NAME_SPECIFIC_ATTRIBUTE);
81-
if (serviceName != null) {
82-
span.setServiceName(serviceName);
83-
}
84-
String resourceName = getStringAttribute(span, RESOURCE_NAME_SPECIFIC_ATTRIBUTE);
85-
if (resourceName != null) {
86-
span.setResourceName(resourceName);
87-
}
88-
String spanType = getStringAttribute(span, SPAN_TYPE_SPECIFIC_ATTRIBUTES);
89-
if (spanType != null) {
90-
span.setSpanType(spanType);
91-
}
79+
// The following attributes are already handled by tag interceptors:
80+
// - service.name
81+
// - resource.name
82+
// - span.type
83+
// TODO Remaining questions:
84+
// - Do the attributes must be added has tag or intercepted?
85+
// - Does operation name method blocked if operation.name is present?
9286
Boolean analyticsEvent = getBooleanAttribute(span, ANALYTICS_EVENT_SPECIFIC_ATTRIBUTES);
9387
if (analyticsEvent != null) {
9488
span.setMetric(ANALYTICS_SAMPLE_RATE, analyticsEvent ? 1 : 0);
9589
}
96-
applyOperationName(span);
97-
}
98-
99-
private static void applyOperationName(AgentSpan span) {
10090
String operationName = getStringAttribute(span, OPERATION_NAME_SPECIFIC_ATTRIBUTE);
10191
if (operationName == null) {
10292
operationName = computeOperationName(span);
@@ -105,7 +95,9 @@ private static void applyOperationName(AgentSpan span) {
10595
}
10696

10797
private static String computeOperationName(AgentSpan span) {
108-
SpanKind spanKind = toSpanKind(span.getSpanType());
98+
Object spanKingTag = span.getTag(SPAN_KIND);
99+
SpanKind spanKind =
100+
spanKingTag instanceof String ? toOtelSpanKind((String) spanKingTag) : INTERNAL;
109101
/*
110102
* HTTP convention: https://opentelemetry.io/docs/specs/otel/trace/semantic_conventions/http/
111103
*/

dd-java-agent/instrumentation/opentelemetry/opentelemetry-1.4/src/main/java/datadog/trace/instrumentation/opentelemetry14/trace/OtelSpanBuilder.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package datadog.trace.instrumentation.opentelemetry14.trace;
22

3-
import static datadog.trace.instrumentation.opentelemetry14.trace.OtelConventions.toSpanType;
3+
import static datadog.trace.bootstrap.instrumentation.api.Tags.SPAN_KIND;
4+
import static datadog.trace.instrumentation.opentelemetry14.trace.OtelConventions.toSpanKindTagValue;
45
import static datadog.trace.instrumentation.opentelemetry14.trace.OtelExtractedContext.extract;
56
import static io.opentelemetry.api.trace.SpanKind.INTERNAL;
67

@@ -113,7 +114,7 @@ public <T> SpanBuilder setAttribute(AttributeKey<T> key, T value) {
113114
@Override
114115
public SpanBuilder setSpanKind(SpanKind spanKind) {
115116
if (spanKind != null) {
116-
this.delegate.withSpanType(toSpanType(spanKind));
117+
this.delegate.withTag(SPAN_KIND, toSpanKindTagValue(spanKind));
117118
this.spanKindSet = true;
118119
}
119120
return this;

dd-java-agent/instrumentation/opentelemetry/opentelemetry-1.4/src/test/groovy/OpenTelemetry14ConventionsTest.groovy

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import io.opentelemetry.context.Context
55
import io.opentelemetry.context.ThreadLocalContextStorage
66
import spock.lang.Subject
77

8-
import static datadog.trace.bootstrap.instrumentation.api.Tags.SPAN_KIND_CLIENT
9-
import static datadog.trace.bootstrap.instrumentation.api.Tags.SPAN_KIND_SERVER
10-
import static datadog.trace.instrumentation.opentelemetry14.trace.OtelConventions.toSpanType
8+
import static datadog.trace.bootstrap.instrumentation.api.Tags.SPAN_KIND
9+
import static datadog.trace.instrumentation.opentelemetry14.trace.OtelConventions.SPAN_KIND_INTERNAL
10+
import static datadog.trace.instrumentation.opentelemetry14.trace.OtelConventions.toSpanKindTagValue
1111
import static io.opentelemetry.api.trace.SpanKind.CLIENT
1212
import static io.opentelemetry.api.trace.SpanKind.CONSUMER
1313
import static io.opentelemetry.api.trace.SpanKind.INTERNAL
@@ -38,9 +38,15 @@ class OpenTelemetry14ConventionsTest extends AgentTestRunner {
3838
trace(1) {
3939
span {
4040
parent()
41-
spanType toSpanType(kind == null ? INTERNAL : kind)
4241
operationName "$expectedOperationName"
4342
resourceName "some-name"
43+
tags {
44+
defaultTags()
45+
"$SPAN_KIND" "${toSpanKindTagValue(kind == null ? INTERNAL : kind)}"
46+
attributes.forEach { key, value->
47+
tag(key, value)
48+
}
49+
}
4450
}
4551
}
4652
}
@@ -91,28 +97,26 @@ class OpenTelemetry14ConventionsTest extends AgentTestRunner {
9197
tracer.spanBuilder("some-name")
9298
.setAttribute("service.name", "my-service")
9399
.setAttribute("resource.name", "/my-resource")
94-
.setAttribute("span.type", "$type")
100+
.setAttribute("span.type", "http")
95101
.startSpan()
96102
.end()
97103

98-
99104
then:
100105
assertTraces(1) {
101106
trace(1) {
102107
span {
103108
parent()
104-
spanType "$type"
105-
operationName "$expectedOperationName"
109+
operationName "internal"
106110
resourceName "/my-resource"
107111
serviceName "my-service"
112+
spanType "http"
113+
tags {
114+
defaultTags()
115+
"$SPAN_KIND" "$SPAN_KIND_INTERNAL"
116+
}
108117
}
109118
}
110119
}
111-
112-
where:
113-
type | expectedOperationName
114-
SPAN_KIND_SERVER | "server.request"
115-
SPAN_KIND_CLIENT | "client.request"
116120
}
117121

118122
def "test span analytics.event specific tag"() {
@@ -129,9 +133,9 @@ class OpenTelemetry14ConventionsTest extends AgentTestRunner {
129133
span {
130134
parent()
131135
operationName "internal"
132-
spanType "internal"
133136
tags {
134137
defaultTags()
138+
"$SPAN_KIND" "$SPAN_KIND_INTERNAL"
135139
if (value != null) {
136140
"analytics.event" value
137141
"$DDTags.ANALYTICS_SAMPLE_RATE" expectedMetric

0 commit comments

Comments
 (0)