Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,6 @@ import kotlin.test.Test
import kotlin.test.assertEquals
import org.junit.Before

/**
* System tests for Kafka queue instrumentation on the OTel Jakarta noagent sample.
*
* The Sentry Kafka auto-configuration (`SentryKafkaQueueConfiguration`) is intentionally suppressed
* when `io.sentry.opentelemetry.SentryAutoConfigurationCustomizerProvider` is on the classpath, so
* the Sentry `SentryKafkaProducer` and `SentryKafkaRecordInterceptor` must not be wired.
*
* These tests produce a Kafka message end-to-end and assert that Sentry-style `queue.publish` /
* `queue.process` spans/transactions are *not* emitted. Any Kafka telemetry in OTel mode must come
* from the OTel Kafka instrumentation, not from the Sentry Kafka integration.
*
* Requires:
* - The sample app running with `--spring.profiles.active=kafka`
* - A Kafka broker at localhost:9092
* - The mock Sentry server at localhost:8000
*/
class KafkaOtelCoexistenceSystemTest {
lateinit var testHelper: TestHelper

Expand All @@ -37,9 +21,21 @@ class KafkaOtelCoexistenceSystemTest {
restClient.produceKafkaMessage("otel-coexistence-test")
assertEquals(200, restClient.lastKnownStatusCode)

testHelper.ensureNoTransactionReceived { transaction, _ ->
transaction.contexts.trace?.operation == "queue.process" ||
transaction.spans.any { span -> span.op == "queue.publish" }
testHelper.ensureTransactionReceived { transaction, _ ->
transaction.transaction == "GET /kafka/produce" &&
transaction.sdk?.integrationSet?.contains("SpringKafka") != true &&
transaction.spans.any { span ->
span.op == "queue.publish" &&
span.origin == "auto.opentelemetry" &&
span.data?.get("messaging.system") == "kafka"
}
}

testHelper.ensureTransactionReceived { transaction, _ ->
transaction.contexts.trace?.operation == "queue.process" &&
transaction.contexts.trace?.origin == "auto.opentelemetry" &&
transaction.contexts.trace?.data?.get("messaging.system") == "kafka" &&
transaction.sdk?.integrationSet?.contains("SpringKafka") != true
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,6 @@ import kotlin.test.Test
import kotlin.test.assertEquals
import org.junit.Before

/**
* System tests for Kafka queue instrumentation on the OTel Jakarta sample.
*
* The Sentry Kafka auto-configuration (`SentryKafkaQueueConfiguration`) is intentionally suppressed
* when `io.sentry.opentelemetry.SentryAutoConfigurationCustomizerProvider` is on the classpath, so
* the Sentry `SentryKafkaProducer` and `SentryKafkaRecordInterceptor` must not be wired.
*
* These tests produce a Kafka message end-to-end and assert that Sentry-style `queue.publish` /
* `queue.process` spans/transactions are *not* emitted. Any Kafka telemetry in OTel mode must come
* from the OTel Kafka instrumentation, not from the Sentry Kafka integration.
*
* Requires:
* - The sample app running with `--spring.profiles.active=kafka`
* - A Kafka broker at localhost:9092
* - The mock Sentry server at localhost:8000
*/
class KafkaOtelCoexistenceSystemTest {
lateinit var testHelper: TestHelper

Expand All @@ -37,9 +21,21 @@ class KafkaOtelCoexistenceSystemTest {
restClient.produceKafkaMessage("otel-coexistence-test")
assertEquals(200, restClient.lastKnownStatusCode)

testHelper.ensureNoTransactionReceived { transaction, _ ->
transaction.contexts.trace?.operation == "queue.process" ||
transaction.spans.any { span -> span.op == "queue.publish" }
testHelper.ensureTransactionReceived { transaction, _ ->
transaction.transaction == "GET /kafka/produce" &&
transaction.sdk?.integrationSet?.contains("SpringKafka") != true &&
transaction.spans.any { span ->
span.op == "queue.publish" &&
span.origin == "auto.opentelemetry" &&
span.data?.get("messaging.system") == "kafka"
}
}

testHelper.ensureTransactionReceived { transaction, _ ->
transaction.contexts.trace?.operation == "queue.process" &&
transaction.contexts.trace?.origin == "auto.opentelemetry" &&
transaction.contexts.trace?.data?.get("messaging.system") == "kafka" &&
transaction.sdk?.integrationSet?.contains("SpringKafka") != true
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,10 @@ static class SentryCacheConfiguration {
"io.sentry.kafka.SentryKafkaProducer"
})
@ConditionalOnProperty(name = "sentry.enable-queue-tracing", havingValue = "true")
@ConditionalOnMissingClass("io.sentry.opentelemetry.SentryAutoConfigurationCustomizerProvider")
@ConditionalOnMissingClass({
"io.sentry.opentelemetry.SentryAutoConfigurationCustomizerProvider",
"io.sentry.opentelemetry.agent.AgentMarker"
})
@Open
static class SentryKafkaQueueConfiguration {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.sentry.spring.boot.jakarta

import io.sentry.kafka.SentryKafkaProducer
import io.sentry.opentelemetry.SentryAutoConfigurationCustomizerProvider
import io.sentry.opentelemetry.agent.AgentMarker
import io.sentry.spring.jakarta.kafka.SentryKafkaConsumerBeanPostProcessor
import io.sentry.spring.jakarta.kafka.SentryKafkaProducerBeanPostProcessor
import kotlin.test.Test
Expand All @@ -28,20 +29,27 @@ class SentryKafkaAutoConfigurationTest {
"sentry.debug=false",
)

/** Hide the OTel customizer so conditions evaluate as "no OTel present". */
private val noOtelClassLoader =
FilteredClassLoader(
SentryAutoConfigurationCustomizerProvider::class.java,
AgentMarker::class.java,
)

private val noOtelCustomizerClassLoader =
FilteredClassLoader(SentryAutoConfigurationCustomizerProvider::class.java)

private val noSentryKafkaClassLoader =
FilteredClassLoader(
SentryKafkaProducer::class.java,
SentryAutoConfigurationCustomizerProvider::class.java,
AgentMarker::class.java,
)

private val noSpringKafkaClassLoader =
FilteredClassLoader(
KafkaTemplate::class.java,
SentryAutoConfigurationCustomizerProvider::class.java,
AgentMarker::class.java,
)

@Test
Expand Down Expand Up @@ -96,6 +104,17 @@ class SentryKafkaAutoConfigurationTest {
}
}

@Test
fun `does not register Kafka BPPs when OpenTelemetry agent is present`() {
contextRunner
.withClassLoader(noOtelCustomizerClassLoader)
.withPropertyValues("sentry.enable-queue-tracing=true")
.run { context ->
assertThat(context).doesNotHaveBean(SentryKafkaProducerBeanPostProcessor::class.java)
assertThat(context).doesNotHaveBean(SentryKafkaConsumerBeanPostProcessor::class.java)
}
}

@Test
fun `does not register Kafka BPPs when OpenTelemetry integration is present`() {
contextRunner.withPropertyValues("sentry.enable-queue-tracing=true").run { context ->
Expand Down
Loading