Skip to content

Commit 950bb5e

Browse files
authored
Fix missing link attributes when using the Java agent (#15143)
1 parent c0b075a commit 950bb5e

File tree

3 files changed

+101
-7
lines changed
  • instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src
  • testing-common/src/main/java/io/opentelemetry/instrumentation/testing/internal

3 files changed

+101
-7
lines changed

instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/trace/ApplicationSpanBuilder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ public SpanBuilder addLink(SpanContext applicationSpanContext) {
5050
@Override
5151
@CanIgnoreReturnValue
5252
public SpanBuilder addLink(SpanContext applicationSpanContext, Attributes applicationAttributes) {
53-
agentBuilder.addLink(Bridging.toAgent(applicationSpanContext));
53+
agentBuilder.addLink(
54+
Bridging.toAgent(applicationSpanContext), Bridging.toAgent(applicationAttributes));
5455
return this;
5556
}
5657

instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TracerTest.java

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@
2020
import io.opentelemetry.api.GlobalOpenTelemetry;
2121
import io.opentelemetry.api.common.Attributes;
2222
import io.opentelemetry.api.trace.Span;
23+
import io.opentelemetry.api.trace.SpanContext;
2324
import io.opentelemetry.api.trace.Tracer;
2425
import io.opentelemetry.context.Context;
2526
import io.opentelemetry.context.Scope;
2627
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
2728
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
2829
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
30+
import io.opentelemetry.sdk.trace.data.LinkData;
2931
import io.opentelemetry.sdk.trace.data.StatusData;
3032
import java.io.PrintWriter;
3133
import java.io.StringWriter;
@@ -322,4 +324,95 @@ void testTracerBuilder() {
322324
.hasInstrumentationScopeInfo(
323325
InstrumentationScopeInfo.builder("test").setVersion("1.2.3").build())));
324326
}
327+
328+
@Test
329+
@DisplayName("capture span link without attributes")
330+
void captureSpanLinkWithoutAttributes() {
331+
// When
332+
Tracer tracer = GlobalOpenTelemetry.getTracer("test");
333+
Span linkedSpan = tracer.spanBuilder("linked").startSpan();
334+
linkedSpan.end();
335+
SpanContext linkedSpanContext = linkedSpan.getSpanContext();
336+
337+
Span testSpan = tracer.spanBuilder("test").addLink(linkedSpanContext).startSpan();
338+
testSpan.end();
339+
340+
// Then
341+
testing.waitAndAssertTraces(
342+
trace ->
343+
trace.hasSpansSatisfyingExactly(
344+
span -> span.hasName("linked").hasNoParent().hasTotalAttributeCount(0)),
345+
trace ->
346+
trace.hasSpansSatisfyingExactly(
347+
span ->
348+
span.hasName("test")
349+
.hasNoParent()
350+
.hasTotalAttributeCount(0)
351+
.hasLinksSatisfying(
352+
links -> {
353+
assertThat(links).hasSize(1);
354+
LinkData link = links.get(0);
355+
assertThat(link.getSpanContext().getTraceId())
356+
.isEqualTo(linkedSpanContext.getTraceId());
357+
assertThat(link.getSpanContext().getSpanId())
358+
.isEqualTo(linkedSpanContext.getSpanId());
359+
assertThat(link.getSpanContext().getTraceFlags().asByte())
360+
.isEqualTo(linkedSpanContext.getTraceFlags().asByte());
361+
assertThat(link.getSpanContext().isRemote())
362+
.isEqualTo(linkedSpanContext.isRemote());
363+
assertThat(link.getAttributes().size()).isEqualTo(0);
364+
})));
365+
}
366+
367+
@Test
368+
@DisplayName("capture span link with attributes")
369+
void captureSpanLinkWithAttributes() {
370+
// When
371+
Tracer tracer = GlobalOpenTelemetry.getTracer("test");
372+
Span linkedSpan = tracer.spanBuilder("linked").startSpan();
373+
linkedSpan.end();
374+
SpanContext linkedSpanContext = linkedSpan.getSpanContext();
375+
376+
Attributes linkAttributes =
377+
Attributes.builder()
378+
.put("string", "1")
379+
.put("long", 2L)
380+
.put("double", 3.0)
381+
.put("boolean", true)
382+
.build();
383+
Span testSpan =
384+
tracer.spanBuilder("test").addLink(linkedSpanContext, linkAttributes).startSpan();
385+
testSpan.end();
386+
387+
// Then
388+
testing.waitAndAssertTraces(
389+
trace ->
390+
trace.hasSpansSatisfyingExactly(
391+
span -> span.hasName("linked").hasNoParent().hasTotalAttributeCount(0)),
392+
trace ->
393+
trace.hasSpansSatisfyingExactly(
394+
span ->
395+
span.hasName("test")
396+
.hasNoParent()
397+
.hasTotalAttributeCount(0)
398+
.hasLinksSatisfying(
399+
links -> {
400+
assertThat(links).hasSize(1);
401+
LinkData link = links.get(0);
402+
assertThat(link.getSpanContext().getTraceId())
403+
.isEqualTo(linkedSpanContext.getTraceId());
404+
assertThat(link.getSpanContext().getSpanId())
405+
.isEqualTo(linkedSpanContext.getSpanId());
406+
assertThat(link.getSpanContext().getTraceFlags().asByte())
407+
.isEqualTo(linkedSpanContext.getTraceFlags().asByte());
408+
assertThat(link.getSpanContext().isRemote())
409+
.isEqualTo(linkedSpanContext.isRemote());
410+
assertThat(link.getTotalAttributeCount()).isEqualTo(4);
411+
Attributes attrs = link.getAttributes();
412+
assertThat(attrs.get(stringKey("string"))).isEqualTo("1");
413+
assertThat(attrs.get(longKey("long"))).isEqualTo(2L);
414+
assertThat(attrs.get(doubleKey("double"))).isEqualTo(3.0);
415+
assertThat(attrs.get(booleanKey("boolean"))).isEqualTo(true);
416+
})));
417+
}
325418
}

testing-common/src/main/java/io/opentelemetry/instrumentation/testing/internal/TelemetryConverter.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public static List<SpanData> getSpanData(Collection<ResourceSpans> allResourceSp
109109
SpanContext.create(
110110
traceId,
111111
bytesToHex(span.getSpanId().toByteArray()),
112-
TraceFlags.getDefault(),
112+
TraceFlags.fromByte((byte) span.getFlags()),
113113
extractTraceState(span.getTraceState())))
114114
// TODO is it ok to use default trace flags and default trace state here?
115115
.setParentSpanContext(
@@ -152,7 +152,7 @@ public static List<SpanData> getSpanData(Collection<ResourceSpans> allResourceSp
152152
SpanContext.create(
153153
bytesToHex(link.getTraceId().toByteArray()),
154154
bytesToHex(link.getSpanId().toByteArray()),
155-
TraceFlags.getDefault(),
155+
TraceFlags.fromByte((byte) link.getFlags()),
156156
extractTraceState(link.getTraceState())),
157157
fromProto(link.getAttributesList()),
158158
link.getDroppedAttributesCount() + link.getAttributesCount()))
@@ -307,8 +307,8 @@ private static LogRecordData createLogData(
307307
SpanContext.create(
308308
bytesToHex(logRecord.getTraceId().toByteArray()),
309309
bytesToHex(logRecord.getSpanId().toByteArray()),
310-
TraceFlags.getDefault(),
311-
TraceState.getDefault()))
310+
TraceFlags.fromByte((byte) logRecord.getFlags()),
311+
TraceState.getDefault())) // logs proto doesn't have trace state
312312
.setSeverity(fromProto(logRecord.getSeverityNumber()))
313313
.setSeverityText(logRecord.getSeverityText())
314314
.setAttributes(fromProto(logRecord.getAttributesList()));
@@ -333,8 +333,8 @@ private static LogRecordData createExtendedLogData(
333333
SpanContext.create(
334334
bytesToHex(logRecord.getTraceId().toByteArray()),
335335
bytesToHex(logRecord.getSpanId().toByteArray()),
336-
TraceFlags.getDefault(),
337-
TraceState.getDefault()))
336+
TraceFlags.fromByte((byte) logRecord.getFlags()),
337+
TraceState.getDefault())) // logs proto doesn't have trace state
338338
.setSeverity(fromProto(logRecord.getSeverityNumber()))
339339
.setSeverityText(logRecord.getSeverityText())
340340
.setEventName(logRecord.getEventName())

0 commit comments

Comments
 (0)