Fix link behavior
MODIFY
instrumentation/jms-1.1/src/latestDepTest/groovy/JMS2Test.groovy
instrumentation/jms-1.1/src/latestDepTest/groovy/JMS2Test.groovy
@@ -44,8 +44,6 @@ import javax.jms.TextMessage
import java.util.concurrent.CountDownLatch
import java.util.concurrent.atomic.AtomicReference
-import static io.opentelemetry.auto.test.utils.TraceUtils.basicSpan
-import static io.opentelemetry.auto.test.utils.TraceUtils.runUnderTrace
import static io.opentelemetry.trace.Span.Kind.CLIENT
import static io.opentelemetry.trace.Span.Kind.CONSUMER
import static io.opentelemetry.trace.Span.Kind.PRODUCER
@@ -109,47 +107,14 @@ class JMS2Test extends AgentTestRunner {
TextMessage receivedMessage = consumer.receive()
- expect:
- receivedMessage.text == messageText
- assertTraces(1) {
- trace(0, 2) {
- producerSpan(it, 0, jmsResourceName)
- consumerSpan(it, 1, jmsResourceName, false, HornetQMessageConsumer, span(0))
- }
- }
-
- cleanup:
- producer.close()
- consumer.close()
-
- where:
- destination | jmsResourceName
- session.createQueue("someQueue") | "Queue someQueue"
- session.createTopic("someTopic") | "Topic someTopic"
- session.createTemporaryQueue() | "Temporary Queue"
- session.createTemporaryTopic() | "Temporary Topic"
- }
-
- def "sending a message to #jmsResourceName and receive under existing parent generates link"() {
- setup:
- def producer = session.createProducer(destination)
- def consumer = session.createConsumer(destination)
-
- producer.send(message)
-
- TextMessage receivedMessage = runUnderTrace("parent") {
- consumer.receive()
- }
-
expect:
receivedMessage.text == messageText
assertTraces(2) {
trace(0, 1) {
producerSpan(it, 0, jmsResourceName)
}
- trace(1, 2) {
- basicSpan(it, 0, "parent")
- consumerSpan(it, 1, jmsResourceName, false, HornetQMessageConsumer, span(0), traces[0][0])
+ trace(1, 1) {
+ consumerSpan(it, 0, jmsResourceName, false, HornetQMessageConsumer, traces[0][0])
}
}
@@ -292,18 +257,17 @@ class JMS2Test extends AgentTestRunner {
}
}
- static consumerSpan(TraceAssert trace, int index, String jmsResourceName, boolean messageListener, Class origin, Object parentSpan, Object linkSpan = null) {
+ static consumerSpan(TraceAssert trace, int index, String jmsResourceName, boolean messageListener, Class origin, Object parentOrLinkSpan) {
trace.span(index) {
if (messageListener) {
operationName "jms.onMessage"
spanKind CONSUMER
+ childOf((SpanData) parentOrLinkSpan)
} else {
operationName "jms.consume"
spanKind CLIENT
- }
- childOf((SpanData) parentSpan)
- if (linkSpan) {
- hasLink((SpanData) linkSpan)
+ parent()
+ hasLink((SpanData) parentOrLinkSpan)
}
errored false

MODIFY
instrumentation/jms-1.1/src/latestDepTest/groovy/SpringTemplateJMS2Test.groovy
instrumentation/jms-1.1/src/latestDepTest/groovy/SpringTemplateJMS2Test.groovy
@@ -36,8 +36,6 @@ import java.util.concurrent.TimeUnit
import static JMS2Test.consumerSpan
import static JMS2Test.producerSpan
-import static io.opentelemetry.auto.test.utils.TraceUtils.basicSpan
-import static io.opentelemetry.auto.test.utils.TraceUtils.runUnderTrace
class SpringTemplateJMS2Test extends AgentTestRunner {
@Shared
@@ -89,36 +87,14 @@ class SpringTemplateJMS2Test extends AgentTestRunner {
template.convertAndSend(destination, messageText)
TextMessage receivedMessage = template.receive(destination)
- expect:
- receivedMessage.text == messageText
- assertTraces(1) {
- trace(0, 2) {
- producerSpan(it, 0, jmsResourceName)
- consumerSpan(it, 1, jmsResourceName, false, HornetQMessageConsumer, span(0))
- }
- }
-
- where:
- destination | jmsResourceName
- session.createQueue("someSpringQueue") | "Queue someSpringQueue"
- }
-
- def "sending a message to #jmsResourceName and receive under existing parent generates link"() {
- setup:
- template.convertAndSend(destination, messageText)
- TextMessage receivedMessage = runUnderTrace("parent") {
- template.receive(destination)
- }
-
expect:
receivedMessage.text == messageText
assertTraces(2) {
trace(0, 1) {
producerSpan(it, 0, jmsResourceName)
}
- trace(1, 2) {
- basicSpan(it, 0, "parent")
- consumerSpan(it, 1, jmsResourceName, false, HornetQMessageConsumer, span(0), traces[0][0])
+ trace(1, 1) {
+ consumerSpan(it, 0, jmsResourceName, false, HornetQMessageConsumer, traces[0][0])
}
}
@@ -144,14 +120,18 @@ class SpringTemplateJMS2Test extends AgentTestRunner {
expect:
receivedMessage.text == "responded!"
- assertTraces(2) {
- trace(0, 2) {
+ assertTraces(4) {
+ trace(0, 1) {
producerSpan(it, 0, jmsResourceName)
- consumerSpan(it, 1, jmsResourceName, false, HornetQMessageConsumer, span(0))
}
- trace(1, 2) {
+ trace(1, 1) {
+ consumerSpan(it, 0, jmsResourceName, false, HornetQMessageConsumer, traces[0][0])
+ }
+ trace(2, 1) {
producerSpan(it, 0, "Temporary Queue") // receive doesn't propagate the trace, so this is a root
- consumerSpan(it, 1, "Temporary Queue", false, HornetQMessageConsumer, span(0))
+ }
+ trace(3, 1) {
+ consumerSpan(it, 0, "Temporary Queue", false, HornetQMessageConsumer, traces[2][0])
}
}

MODIFY
instrumentation/jms-1.1/src/main/java/io/opentelemetry/auto/instrumentation/jms/JMSMessageConsumerInstrumentation.java
instrumentation/jms-1.1/src/main/java/io/opentelemetry/auto/instrumentation/jms/JMSMessageConsumerInstrumentation.java
@@ -112,11 +112,7 @@ public final class JMSMessageConsumerInstrumentation extends Instrumenter.Defaul
// Couldn't extract a context
}
if (spanContext != null) {
- if (TRACER.getCurrentSpan().getContext().isValid()) {
spanBuilder.addLink(spanContext);
- } else {
- spanBuilder.setParent(spanContext);
- }
}
}
final Span span = spanBuilder.startSpan();

MODIFY
instrumentation/jms-1.1/src/test/groovy/JMS1Test.groovy
instrumentation/jms-1.1/src/test/groovy/JMS1Test.groovy
@@ -34,8 +34,6 @@ import javax.jms.TextMessage
import java.util.concurrent.CountDownLatch
import java.util.concurrent.atomic.AtomicReference
-import static io.opentelemetry.auto.test.utils.TraceUtils.basicSpan
-import static io.opentelemetry.auto.test.utils.TraceUtils.runUnderTrace
import static io.opentelemetry.trace.Span.Kind.CLIENT
import static io.opentelemetry.trace.Span.Kind.CONSUMER
import static io.opentelemetry.trace.Span.Kind.PRODUCER
@@ -72,47 +70,14 @@ class JMS1Test extends AgentTestRunner {
TextMessage receivedMessage = consumer.receive()
- expect:
- receivedMessage.text == messageText
- assertTraces(1) {
- trace(0, 2) {
- producerSpan(it, 0, jmsResourceName)
- consumerSpan(it, 1, jmsResourceName, false, ActiveMQMessageConsumer, span(0))
- }
- }
-
- cleanup:
- producer.close()
- consumer.close()
-
- where:
- destination | jmsResourceName
- session.createQueue("someQueue") | "Queue someQueue"
- session.createTopic("someTopic") | "Topic someTopic"
- session.createTemporaryQueue() | "Temporary Queue"
- session.createTemporaryTopic() | "Temporary Topic"
- }
-
- def "sending a message to #jmsResourceName and receive under existing parent generates link"() {
- setup:
- def producer = session.createProducer(destination)
- def consumer = session.createConsumer(destination)
-
- producer.send(message)
-
- TextMessage receivedMessage = runUnderTrace("parent") {
- consumer.receive()
- }
-
expect:
receivedMessage.text == messageText
assertTraces(2) {
trace(0, 1) {
producerSpan(it, 0, jmsResourceName)
}
- trace(1, 2) {
- basicSpan(it, 0, "parent")
- consumerSpan(it, 1, jmsResourceName, false, ActiveMQMessageConsumer, span(0), traces[0][0])
+ trace(1, 1) {
+ consumerSpan(it, 0, jmsResourceName, false, ActiveMQMessageConsumer, traces[0][0])
}
}
@@ -309,18 +274,17 @@ class JMS1Test extends AgentTestRunner {
}
}
- static consumerSpan(TraceAssert trace, int index, String jmsResourceName, boolean messageListener, Class origin, Object parentSpan, Object linkSpan = null) {
+ static consumerSpan(TraceAssert trace, int index, String jmsResourceName, boolean messageListener, Class origin, Object parentOrLinkedSpan) {
trace.span(index) {
if (messageListener) {
operationName "jms.onMessage"
spanKind CONSUMER
+ childOf((SpanData) parentOrLinkedSpan)
} else {
operationName "jms.consume"
spanKind CLIENT
- }
- childOf((SpanData) parentSpan)
- if (linkSpan) {
- hasLink((SpanData) linkSpan)
+ parent()
+ hasLink((SpanData) parentOrLinkedSpan)
}
errored false
tags {

MODIFY
instrumentation/jms-1.1/src/test/groovy/SpringTemplateJMS1Test.groovy
instrumentation/jms-1.1/src/test/groovy/SpringTemplateJMS1Test.groovy
@@ -28,8 +28,6 @@ import java.util.concurrent.TimeUnit
import static JMS1Test.consumerSpan
import static JMS1Test.producerSpan
-import static io.opentelemetry.auto.test.utils.TraceUtils.basicSpan
-import static io.opentelemetry.auto.test.utils.TraceUtils.runUnderTrace
class SpringTemplateJMS1Test extends AgentTestRunner {
@Shared
@@ -63,36 +61,14 @@ class SpringTemplateJMS1Test extends AgentTestRunner {
template.convertAndSend(destination, messageText)
TextMessage receivedMessage = template.receive(destination)
- expect:
- receivedMessage.text == messageText
- assertTraces(1) {
- trace(0, 2) {
- producerSpan(it, 0, jmsResourceName)
- consumerSpan(it, 1, jmsResourceName, false, ActiveMQMessageConsumer, span(0))
- }
- }
-
- where:
- destination | jmsResourceName
- session.createQueue("someSpringQueue") | "Queue someSpringQueue"
- }
-
- def "sending a message to #jmsResourceName and receive under existing parent generates link"() {
- setup:
- template.convertAndSend(destination, messageText)
- TextMessage receivedMessage = runUnderTrace("parent") {
- template.receive(destination)
- }
-
expect:
receivedMessage.text == messageText
assertTraces(2) {
trace(0, 1) {
producerSpan(it, 0, jmsResourceName)
}
- trace(1, 2) {
- basicSpan(it, 0, "parent")
- consumerSpan(it, 1, jmsResourceName, false, ActiveMQMessageConsumer, span(0), traces[0][0])
+ trace(1, 1) {
+ consumerSpan(it, 0, jmsResourceName, false, ActiveMQMessageConsumer, traces[0][0])
}
}
@@ -122,14 +98,18 @@ class SpringTemplateJMS1Test extends AgentTestRunner {
expect:
receivedMessage.text == "responded!"
- assertTraces(2) {
- trace(0, 2) {
+ assertTraces(4) {
+ trace(0, 1) {
producerSpan(it, 0, jmsResourceName)
- consumerSpan(it, 1, jmsResourceName, false, ActiveMQMessageConsumer, span(0))
}
- trace(1, 2) {
+ trace(1, 1) {
+ consumerSpan(it, 0, jmsResourceName, false, ActiveMQMessageConsumer, traces[0][0])
+ }
+ trace(2, 1) {
producerSpan(it, 0, "Temporary Queue") // receive doesn't propagate the trace, so this is a root
- consumerSpan(it, 1, "Temporary Queue", false, ActiveMQMessageConsumer, span(0))
+ }
+ trace(3, 1) {
+ consumerSpan(it, 0, "Temporary Queue", false, ActiveMQMessageConsumer, traces[2][0])
}
}

MODIFY
instrumentation/kafka-clients-0.11/src/main/java/io/opentelemetry/auto/instrumentation/kafka_clients/TracingIterator.java
instrumentation/kafka-clients-0.11/src/main/java/io/opentelemetry/auto/instrumentation/kafka_clients/TracingIterator.java
@@ -70,7 +70,11 @@ public class TracingIterator implements Iterator<ConsumerRecord> {
try {
if (next != null) {
- final Span.Builder spanBuilder = TRACER.spanBuilder(operationName).setSpanKind(CONSUMER);
+ final boolean consumer = !TRACER.getCurrentSpan().getContext().isValid();
+ final Span.Builder spanBuilder = TRACER.spanBuilder(operationName);
+ if (consumer) {
+ spanBuilder.setSpanKind(CONSUMER);
+ }
SpanContext spanContext = null;
try {
spanContext = TRACER.getHttpTextFormat().extract(next.headers(), GETTER);
@@ -78,10 +82,10 @@ public class TracingIterator implements Iterator<ConsumerRecord> {
// Couldn't extract a context
}
if (spanContext != null) {
- if (TRACER.getCurrentSpan().getContext().isValid()) {
- spanBuilder.addLink(spanContext);
- } else {
+ if (consumer) {
spanBuilder.setParent(spanContext);
+ } else {
+ spanBuilder.addLink(spanContext);
}
}
final Span span = spanBuilder.startSpan();

MODIFY
instrumentation/rabbitmq-amqp-2.7/src/main/java/io/opentelemetry/auto/instrumentation/rabbitmq/amqp/RabbitChannelInstrumentation.java
instrumentation/rabbitmq-amqp-2.7/src/main/java/io/opentelemetry/auto/instrumentation/rabbitmq/amqp/RabbitChannelInstrumentation.java
@@ -51,7 +51,6 @@ import io.opentelemetry.auto.instrumentation.api.Tags;
import io.opentelemetry.auto.tooling.Instrumenter;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
-import io.opentelemetry.trace.SpanContext;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
@@ -257,19 +256,11 @@ public class RabbitChannelInstrumentation extends Instrumenter.Default {
final Map<String, Object> headers = response.getProps().getHeaders();
if (headers != null) {
- SpanContext spanContext = null;
try {
- spanContext = TRACER.getHttpTextFormat().extract(headers, GETTER);
+ spanBuilder.addLink(TRACER.getHttpTextFormat().extract(headers, GETTER));
} catch (final IllegalArgumentException e) {
// couldn't extract a context
}
- if (spanContext != null) {
- if (TRACER.getCurrentSpan().getContext().isValid()) {
- spanBuilder.addLink(spanContext);
- } else {
- spanBuilder.setParent(spanContext);
- }
- }
}
}

MODIFY
instrumentation/rabbitmq-amqp-2.7/src/test/groovy/RabbitMQTest.groovy
instrumentation/rabbitmq-amqp-2.7/src/test/groovy/RabbitMQTest.groovy
@@ -151,13 +151,15 @@ class RabbitMQTest extends AgentTestRunner {
new String(response.getBody()) == "Hello, world!"
and:
- assertTraces(2) {
+ assertTraces(3) {
trace(0, 1) {
rabbitSpan(it, 0, "queue.declare")
}
- trace(1, 2) {
+ trace(1, 1) {
rabbitSpan(it, 0, "basic.publish <default> -> <generated>")
- rabbitSpan(it, 1, "basic.get <generated>", span(0))
+ }
+ trace(2, 1) {
+ rabbitSpan(it, 0, "basic.get <generated>", null, traces[1][0])
}
}
}
@@ -300,13 +302,15 @@ class RabbitMQTest extends AgentTestRunner {
message == "foo"
and:
- assertTraces(2) {
+ assertTraces(3) {
trace(0, 1) {
rabbitSpan(it, "queue.declare")
}
- trace(1, 2) {
+ trace(1, 1) {
rabbitSpan(it, 0, "basic.publish <default> -> some-routing-queue")
- rabbitSpan(it, 1, "basic.get $queue.name", span(0))
+ }
+ trace(2, 1) {
+ rabbitSpan(it, 0, "basic.get $queue.name", null, traces[1][0])
}
}
}

Fix link behavior (#223)