diff --git a/buildSrc/src/main/java/Config.kt b/buildSrc/src/main/java/Config.kt index 10e361e8d9f..52bc576eaf2 100644 --- a/buildSrc/src/main/java/Config.kt +++ b/buildSrc/src/main/java/Config.kt @@ -94,7 +94,7 @@ object Config { val springBoot3StarterSecurity = "org.springframework.boot:spring-boot-starter-security:$springBoot3Version" val springBoot3StarterJdbc = "org.springframework.boot:spring-boot-starter-jdbc:$springBoot3Version" val springBoot3StarterActuator = "org.springframework.boot:spring-boot-starter-actuator:$springBoot3Version" - val springBoot3StarterOpenTelemetry = "io.opentelemetry.instrumentation:opentelemetry-spring-boot-starter:${OpenTelemetry.otelJavaagentVersion}" + val springBoot3StarterOpenTelemetry = "io.opentelemetry.instrumentation:opentelemetry-spring-boot-starter:${OpenTelemetry.otelInstrumentationVersion}" val springWeb = "org.springframework:spring-webmvc" val springWebflux = "org.springframework:spring-webflux" @@ -158,17 +158,18 @@ object Config { object OpenTelemetry { val otelVersion = "1.41.0" val otelAlphaVersion = "$otelVersion-alpha" - val otelJavaagentVersion = "2.7.0" - val otelJavaagentAlphaVersion = "$otelJavaagentVersion-alpha" + val otelInstrumentationVersion = "2.7.0" + val otelInstrumentationAlphaVersion = "$otelInstrumentationVersion-alpha" val otelSemanticConvetionsVersion = "1.25.0-alpha" // check https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/dependencyManagement/build.gradle.kts#L49 for release version above to find a compatible version val otelSdk = "io.opentelemetry:opentelemetry-sdk:$otelVersion" val otelSemconv = "io.opentelemetry.semconv:opentelemetry-semconv:$otelSemanticConvetionsVersion" val otelSemconvIncubating = "io.opentelemetry.semconv:opentelemetry-semconv-incubating:$otelSemanticConvetionsVersion" - val otelJavaAgent = "io.opentelemetry.javaagent:opentelemetry-javaagent:$otelJavaagentVersion" - val otelJavaAgentExtensionApi = "io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api:$otelJavaagentAlphaVersion" - val otelJavaAgentTooling = "io.opentelemetry.javaagent:opentelemetry-javaagent-tooling:$otelJavaagentAlphaVersion" + val otelJavaAgent = "io.opentelemetry.javaagent:opentelemetry-javaagent:$otelInstrumentationVersion" + val otelJavaAgentExtensionApi = "io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api:$otelInstrumentationAlphaVersion" + val otelJavaAgentTooling = "io.opentelemetry.javaagent:opentelemetry-javaagent-tooling:$otelInstrumentationAlphaVersion" val otelExtensionAutoconfigureSpi = "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:$otelVersion" + val otelExtensionAutoconfigure = "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure:$otelVersion" } } diff --git a/sentry-opentelemetry/sentry-opentelemetry-agent/build.gradle.kts b/sentry-opentelemetry/sentry-opentelemetry-agent/build.gradle.kts index 52a8b071b60..2d4ea259c61 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-agent/build.gradle.kts +++ b/sentry-opentelemetry/sentry-opentelemetry-agent/build.gradle.kts @@ -151,11 +151,11 @@ tasks { attributes.put("Can-Redefine-Classes", "true") attributes.put("Can-Retransform-Classes", "true") attributes.put("Implementation-Vendor", "Sentry") - attributes.put("Implementation-Version", "sentry-${project.version}-otel-${Config.Libs.OpenTelemetry.otelJavaagentVersion}") + attributes.put("Implementation-Version", "sentry-${project.version}-otel-${Config.Libs.OpenTelemetry.otelInstrumentationVersion}") attributes.put("Sentry-Version-Name", project.version) attributes.put("Sentry-Opentelemetry-SDK-Name", Config.Sentry.SENTRY_OPENTELEMETRY_AGENT_SDK_NAME) attributes.put("Sentry-Opentelemetry-Version-Name", Config.Libs.OpenTelemetry.otelVersion) - attributes.put("Sentry-Opentelemetry-Javaagent-Version-Name", Config.Libs.OpenTelemetry.otelJavaagentVersion) + attributes.put("Sentry-Opentelemetry-Javaagent-Version-Name", Config.Libs.OpenTelemetry.otelInstrumentationVersion) } } diff --git a/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/src/main/java/io/sentry/samples/spring/boot/jakarta/CustomJob.java b/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/src/main/java/io/sentry/samples/spring/boot/jakarta/CustomJob.java index 4cd609d67ce..cac83e6d797 100644 --- a/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/src/main/java/io/sentry/samples/spring/boot/jakarta/CustomJob.java +++ b/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/src/main/java/io/sentry/samples/spring/boot/jakarta/CustomJob.java @@ -4,6 +4,7 @@ import io.sentry.spring.jakarta.tracing.SentryTransaction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; /** @@ -17,7 +18,7 @@ public class CustomJob { private static final Logger LOGGER = LoggerFactory.getLogger(CustomJob.class); @SentryCheckIn("monitor_slug_1") - // @Scheduled(fixedRate = 3 * 60 * 1000L) + @Scheduled(fixedRate = 3 * 60 * 1000L) void execute() throws InterruptedException { LOGGER.info("Executing scheduled job"); Thread.sleep(2000L); diff --git a/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/src/main/java/io/sentry/samples/spring/boot/jakarta/PersonController.java b/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/src/main/java/io/sentry/samples/spring/boot/jakarta/PersonController.java index e298b7181b4..8ea9d51f12f 100644 --- a/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/src/main/java/io/sentry/samples/spring/boot/jakarta/PersonController.java +++ b/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/src/main/java/io/sentry/samples/spring/boot/jakarta/PersonController.java @@ -31,8 +31,6 @@ public PersonController(PersonService personService, OpenTelemetry openTelemetry @GetMapping("{id}") @WithSpan("personSpanThroughOtelAnnotation") Person person(@PathVariable Long id) { - ISpan annotationSpan = Sentry.getSpan(); - System.out.println(annotationSpan); Span span = openTelemetry .getTracer("tracerForSpringBootDemo") diff --git a/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/src/main/java/io/sentry/samples/spring/boot/jakarta/SentryDemoApplication.java b/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/src/main/java/io/sentry/samples/spring/boot/jakarta/SentryDemoApplication.java index 587991b0958..7f412eaa0d6 100644 --- a/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/src/main/java/io/sentry/samples/spring/boot/jakarta/SentryDemoApplication.java +++ b/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/src/main/java/io/sentry/samples/spring/boot/jakarta/SentryDemoApplication.java @@ -1,12 +1,21 @@ package io.sentry.samples.spring.boot.jakarta; +import static io.sentry.quartz.SentryJobListener.SENTRY_SLUG_KEY; + import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.trace.Tracer; +import io.sentry.samples.spring.boot.jakarta.quartz.SampleJob; +import java.util.Collections; +import org.quartz.JobDetail; +import org.quartz.SimpleTrigger; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.quartz.CronTriggerFactoryBean; +import org.springframework.scheduling.quartz.JobDetailFactoryBean; +import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean; import org.springframework.web.client.RestClient; import org.springframework.web.client.RestTemplate; import org.springframework.web.reactive.function.client.WebClient; @@ -33,41 +42,34 @@ RestClient restClient(RestClient.Builder builder) { return builder.build(); } - // @Bean - // public JobDetailFactoryBean jobDetail() { - // JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean(); - // jobDetailFactory.setJobClass(SampleJob.class); - // jobDetailFactory.setDurability(true); - // jobDetailFactory.setJobDataAsMap( - // Collections.singletonMap(SENTRY_SLUG_KEY, "monitor_slug_job_detail")); - // return jobDetailFactory; - // } - // - // @Bean - // public SimpleTriggerFactoryBean trigger(JobDetail job) { - // SimpleTriggerFactoryBean trigger = new SimpleTriggerFactoryBean(); - // trigger.setJobDetail(job); - // trigger.setRepeatInterval(2 * 60 * 1000); // every two minutes - // trigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY); - // trigger.setJobDataAsMap( - // Collections.singletonMap(SENTRY_SLUG_KEY, "monitor_slug_simple_trigger")); - // return trigger; - // } - // - // @Bean - // public CronTriggerFactoryBean cronTrigger(JobDetail job) { - // CronTriggerFactoryBean trigger = new CronTriggerFactoryBean(); - // trigger.setJobDetail(job); - // trigger.setCronExpression("0 0/5 * ? * *"); // every five minutes - // return trigger; - // } + @Bean + public JobDetailFactoryBean jobDetail() { + JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean(); + jobDetailFactory.setJobClass(SampleJob.class); + jobDetailFactory.setDurability(true); + jobDetailFactory.setJobDataAsMap( + Collections.singletonMap(SENTRY_SLUG_KEY, "monitor_slug_job_detail")); + return jobDetailFactory; + } + + @Bean + public SimpleTriggerFactoryBean trigger(JobDetail job) { + SimpleTriggerFactoryBean trigger = new SimpleTriggerFactoryBean(); + trigger.setJobDetail(job); + trigger.setRepeatInterval(2 * 60 * 1000); // every two minutes + trigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY); + trigger.setJobDataAsMap( + Collections.singletonMap(SENTRY_SLUG_KEY, "monitor_slug_simple_trigger")); + return trigger; + } - // @Bean - // public Tracer getTracer(OpenTelemetry openTelemetry) { - // GlobalOpenTelemetry.set(openTelemetry); - // return openTelemetry.getTracer("tracerForSpringBootDemo"); - //// return GlobalOpenTelemetry.getTracer("tracerForSpringBootDemo"); - // } + @Bean + public CronTriggerFactoryBean cronTrigger(JobDetail job) { + CronTriggerFactoryBean trigger = new CronTriggerFactoryBean(); + trigger.setJobDetail(job); + trigger.setCronExpression("0 0/5 * ? * *"); // every five minutes + return trigger; + } @Bean public Tracer tracer(OpenTelemetry openTelemetry) { diff --git a/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry/src/main/java/io/sentry/samples/spring/boot/jakarta/SentryDemoApplication.java b/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry/src/main/java/io/sentry/samples/spring/boot/jakarta/SentryDemoApplication.java index feca2a1405b..a6eb46f4c74 100644 --- a/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry/src/main/java/io/sentry/samples/spring/boot/jakarta/SentryDemoApplication.java +++ b/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry/src/main/java/io/sentry/samples/spring/boot/jakarta/SentryDemoApplication.java @@ -1,12 +1,21 @@ package io.sentry.samples.spring.boot.jakarta; +import static io.sentry.quartz.SentryJobListener.SENTRY_SLUG_KEY; + import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.trace.Tracer; +import io.sentry.samples.spring.boot.jakarta.quartz.SampleJob; +import java.util.Collections; +import org.quartz.JobDetail; +import org.quartz.SimpleTrigger; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.quartz.CronTriggerFactoryBean; +import org.springframework.scheduling.quartz.JobDetailFactoryBean; +import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean; import org.springframework.web.client.RestClient; import org.springframework.web.client.RestTemplate; import org.springframework.web.reactive.function.client.WebClient; @@ -33,41 +42,34 @@ RestClient restClient(RestClient.Builder builder) { return builder.build(); } - // @Bean - // public JobDetailFactoryBean jobDetail() { - // JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean(); - // jobDetailFactory.setJobClass(SampleJob.class); - // jobDetailFactory.setDurability(true); - // jobDetailFactory.setJobDataAsMap( - // Collections.singletonMap(SENTRY_SLUG_KEY, "monitor_slug_job_detail")); - // return jobDetailFactory; - // } - // - // @Bean - // public SimpleTriggerFactoryBean trigger(JobDetail job) { - // SimpleTriggerFactoryBean trigger = new SimpleTriggerFactoryBean(); - // trigger.setJobDetail(job); - // trigger.setRepeatInterval(2 * 60 * 1000); // every two minutes - // trigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY); - // trigger.setJobDataAsMap( - // Collections.singletonMap(SENTRY_SLUG_KEY, "monitor_slug_simple_trigger")); - // return trigger; - // } - // - // @Bean - // public CronTriggerFactoryBean cronTrigger(JobDetail job) { - // CronTriggerFactoryBean trigger = new CronTriggerFactoryBean(); - // trigger.setJobDetail(job); - // trigger.setCronExpression("0 0/5 * ? * *"); // every five minutes - // return trigger; - // } + @Bean + public JobDetailFactoryBean jobDetail() { + JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean(); + jobDetailFactory.setJobClass(SampleJob.class); + jobDetailFactory.setDurability(true); + jobDetailFactory.setJobDataAsMap( + Collections.singletonMap(SENTRY_SLUG_KEY, "monitor_slug_job_detail")); + return jobDetailFactory; + } + + @Bean + public SimpleTriggerFactoryBean trigger(JobDetail job) { + SimpleTriggerFactoryBean trigger = new SimpleTriggerFactoryBean(); + trigger.setJobDetail(job); + trigger.setRepeatInterval(2 * 60 * 1000); // every two minutes + trigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY); + trigger.setJobDataAsMap( + Collections.singletonMap(SENTRY_SLUG_KEY, "monitor_slug_simple_trigger")); + return trigger; + } - // @Bean - // public Tracer getTracer(OpenTelemetry openTelemetry) { - // GlobalOpenTelemetry.set(openTelemetry); - // return openTelemetry.getTracer("tracerForSpringBootDemo"); - //// return GlobalOpenTelemetry.getTracer("tracerForSpringBootDemo"); - // } + @Bean + public CronTriggerFactoryBean cronTrigger(JobDetail job) { + CronTriggerFactoryBean trigger = new CronTriggerFactoryBean(); + trigger.setJobDetail(job); + trigger.setCronExpression("0 0/5 * ? * *"); // every five minutes + return trigger; + } @Bean public Tracer tracer() { diff --git a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentryAutoConfigurationTest.kt b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentryAutoConfigurationTest.kt index 44c0bf5e953..822cc06a3a0 100644 --- a/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentryAutoConfigurationTest.kt +++ b/sentry-spring-boot-jakarta/src/test/kotlin/io/sentry/spring/boot/jakarta/SentryAutoConfigurationTest.kt @@ -748,7 +748,6 @@ class SentryAutoConfigurationTest { SentryIntegrationPackageStorage.getInstance().clearStorage() contextRunner.withPropertyValues("sentry.dsn=http://key@localhost/proj", "sentry.auto-init=false") .run { - println(SentryIntegrationPackageStorage.getInstance().integrations) assertTrue(SentryIntegrationPackageStorage.getInstance().integrations.contains("SpringBoot3OpenTelemetryAgentWithoutAutoInit")) } } @@ -758,7 +757,6 @@ class SentryAutoConfigurationTest { SentryIntegrationPackageStorage.getInstance().clearStorage() contextRunner.withPropertyValues("sentry.dsn=http://key@localhost/proj") .run { - println(SentryIntegrationPackageStorage.getInstance().integrations) assertFalse(SentryIntegrationPackageStorage.getInstance().integrations.contains("SpringBoot3OpenTelemetryAgentWithoutAutoInit")) } } @@ -769,7 +767,6 @@ class SentryAutoConfigurationTest { contextRunner.withPropertyValues("sentry.dsn=http://key@localhost/proj", "sentry.auto-init=false") .withClassLoader(FilteredClassLoader(AgentMarker::class.java)) .run { - println(SentryIntegrationPackageStorage.getInstance().integrations) assertFalse(SentryIntegrationPackageStorage.getInstance().integrations.contains("SpringBoot3OpenTelemetryAgentWithoutAutoInit")) } } @@ -781,7 +778,6 @@ class SentryAutoConfigurationTest { .withClassLoader(FilteredClassLoader(AgentMarker::class.java)) .withUserConfiguration(OtelBeanConfig::class.java) .run { - println(SentryIntegrationPackageStorage.getInstance().integrations) assertTrue(SentryIntegrationPackageStorage.getInstance().integrations.contains("SpringBoot3OpenTelemetryNoAgent")) } } @@ -792,7 +788,6 @@ class SentryAutoConfigurationTest { contextRunner.withPropertyValues("sentry.dsn=http://key@localhost/proj") .withClassLoader(FilteredClassLoader(AgentMarker::class.java, OpenTelemetry::class.java)) .run { - println(SentryIntegrationPackageStorage.getInstance().integrations) assertFalse(SentryIntegrationPackageStorage.getInstance().integrations.contains("SpringBoot3OpenTelemetryNoAgent")) } } @@ -804,11 +799,20 @@ class SentryAutoConfigurationTest { .withClassLoader(FilteredClassLoader(AgentMarker::class.java, SentryAutoConfigurationCustomizerProvider::class.java)) .withUserConfiguration(OtelBeanConfig::class.java) .run { - println(SentryIntegrationPackageStorage.getInstance().integrations) assertFalse(SentryIntegrationPackageStorage.getInstance().integrations.contains("SpringBoot3OpenTelemetryNoAgent")) } } + @Test + fun `when AgentMarker is not on the classpath and auto init on, does not run SentryOpenTelemetryAgentWithoutAutoInitConfiguration`() { + SentryIntegrationPackageStorage.getInstance().clearStorage() + contextRunner.withPropertyValues("sentry.dsn=http://key@localhost/proj") + .withClassLoader(FilteredClassLoader(AgentMarker::class.java)) + .run { + assertFalse(SentryIntegrationPackageStorage.getInstance().integrations.contains("SpringBoot3OpenTelemetryAgentWithoutAutoInit")) + } + } + @Test fun `creates quartz config`() { contextRunner.withPropertyValues("sentry.dsn=http://key@localhost/proj", "sentry.enable-automatic-checkins=true")