Skip to content

Commit ca3da4b

Browse files
authored
POTEL 52 - Do not ignore certain span origins for OTel without Agent (#3856)
* Auto config for Spring Boot combined with OTel but without agent * try to cleanup otel classloader * make agent, no agent and agent without auto init work for spring boot * Fix ignored instrumentation for OTel without agent; separate sample for no agent * fix test result upload on CI * changelog
1 parent f6257e3 commit ca3da4b

File tree

53 files changed

+1795
-59
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1795
-59
lines changed

.github/workflows/system-tests-backend.yml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,18 @@ jobs:
2121
matrix:
2222
sample: [ "sentry-samples-spring-boot-jakarta" ]
2323
agent: [ "0" ]
24+
agent-auto-init: [ "true" ]
2425
include:
2526
- sample: "sentry-samples-spring-boot"
2627
- sample: "sentry-samples-spring-boot-webflux-jakarta"
2728
- sample: "sentry-samples-spring-boot-webflux"
29+
- sample: "sentry-samples-spring-boot-jakarta-opentelemetry-noagent"
2830
- sample: "sentry-samples-spring-boot-jakarta-opentelemetry"
2931
agent: "1"
32+
agent-auto-init: "true"
33+
- sample: "sentry-samples-spring-boot-jakarta-opentelemetry"
34+
agent: "1"
35+
agent-auto-init: "false"
3036
steps:
3137
- uses: actions/checkout@v4
3238
with:
@@ -86,18 +92,13 @@ jobs:
8692
8793
- name: Start server and run integration test for sentry-cli commands
8894
run: |
89-
test/system-test-sentry-server-start.sh \
90-
> sentry-mock-server.txt 2>&1 & \
91-
test/system-test-spring-server-start.sh "${{ matrix.sample }}" "${{ matrix.agent }}" \
92-
> spring-server.txt 2>&1 & \
93-
test/wait-for-spring.sh && \
94-
./gradlew :sentry-samples:${{ matrix.sample }}:systemTest
95+
test/system-test-sentry-server-start.sh > sentry-mock-server.txt 2>&1 & test/system-test-spring-server-start.sh "${{ matrix.sample }}" "${{ matrix.agent }}" "${{ matrix.agent-auto-init }}" > spring-server.txt 2>&1 & test/wait-for-spring.sh && ./gradlew :sentry-samples:${{ matrix.sample }}:systemTest
9596
9697
- name: Upload test results
9798
if: always()
9899
uses: actions/upload-artifact@v4
99100
with:
100-
name: test-results-${{ matrix.sample }}-system-test
101+
name: test-results-${{ matrix.sample }}-${{ matrix.agent }}-${{ matrix.agent-auto-init }}-system-test
101102
path: |
102103
**/build/reports/*
103104
sentry-mock-server.txt

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
- The `sentry-opentelemetry-extra` module has been removed again, most classes have been moved to `sentry-opentelemetry-bootstrap` which is loaded into the bootstrap classloader (i.e. `null`) when our Java agent is used. The rest has been moved into `sentry-opentelemetry-agentcustomization` and is loaded into the agent classloader when our Java agent is used.
2323
- The `sentry-opentelemetry-bootstrap` and `sentry-opentelemetry-agentcustomization` modules can be used without the agent as well, in which case all classes are loaded into the application classloader. Check out our `sentry-samples-spring-boot-jakarta-opentelemetry-noagent` sample.
2424
- In this mode the SDK makes use of `GlobalOpenTelemetry`
25+
- Add a sample for showcasing Sentry with OpenTelemetry for Spring Boot 3 with our Java agent (`sentry-samples-spring-boot-jakarta-opentelemetry`) ([#3856](https://github.com/getsentry/sentry-java/pull/3828))
26+
- Add a sample for showcasing Sentry with OpenTelemetry for Spring Boot 3 without our Java agent (`sentry-samples-spring-boot-jakarta-opentelemetry-noagent`) ([#3856](https://github.com/getsentry/sentry-java/pull/3856))
2527
- Add `globalHubMode` to options ([#3805](https://github.com/getsentry/sentry-java/pull/3805))
2628
- `globalHubMode` used to only be a param on `Sentry.init`. To make it easier to be used in e.g. Desktop environments, we now additionally added it as an option on SentryOptions that can also be set via `sentry.properties`.
2729
- If both the param on `Sentry.init` and the option are set, the option will win. By default the option is set to `null` meaning whatever is passed to `Sentry.init` takes effect.
@@ -37,6 +39,7 @@
3739

3840
- The Sentry OpenTelemetry Java agent now makes sure Sentry `Scopes` storage is initialized even if the agents auto init is disabled ([#3848](https://github.com/getsentry/sentry-java/pull/3848))
3941
- This is required for all integrations to work together with our OpenTelemetry Java agent if its auto init has been disabled and the SDKs init should be used instead.
42+
- Do not ignore certain span origins for OpenTelemetry without agent ([#3856](https://github.com/getsentry/sentry-java/pull/3856))
4043
- Add `auto.graphql.graphql22` to ignored span origins when using OpenTelemetry ([#3828](https://github.com/getsentry/sentry-java/pull/3828))
4144
- The Spring Boot 3 WebFlux sample now uses our GraphQL v22 integration ([#3828](https://github.com/getsentry/sentry-java/pull/3828))
4245
- Accept manifest integer values when requiring floating values ([#3823](https://github.com/getsentry/sentry-java/pull/3823))

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ apiValidation {
6161
"sentry-samples-spring-boot",
6262
"sentry-samples-spring-boot-jakarta",
6363
"sentry-samples-spring-boot-jakarta-opentelemetry",
64+
"sentry-samples-spring-boot-jakarta-opentelemetry-noagent",
6465
"sentry-samples-spring-boot-webflux",
6566
"sentry-samples-spring-boot-webflux-jakarta",
6667
"sentry-uitest-android",

sentry-opentelemetry/sentry-opentelemetry-agentcustomization/src/main/java/io/sentry/opentelemetry/SentryAutoConfigurationCustomizerProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public void customize(AutoConfigurationCustomizer autoConfiguration) {
4242
options -> {
4343
options.setEnableExternalConfiguration(true);
4444
options.setInitPriority(InitPriority.HIGH);
45-
OpenTelemetryUtil.applyOpenTelemetryOptions(options);
45+
OpenTelemetryUtil.applyOpenTelemetryOptions(options, true);
4646
final @Nullable SdkVersion sdkVersion = createSdkVersion(options, versionInfoHolder);
4747
if (sdkVersion != null) {
4848
options.setSdkVersion(sdkVersion);

sentry-opentelemetry/sentry-opentelemetry-bootstrap/api/sentry-opentelemetry-bootstrap.api

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public final class io/sentry/opentelemetry/InternalSemanticAttributes {
2525

2626
public final class io/sentry/opentelemetry/OpenTelemetryUtil {
2727
public fun <init> ()V
28-
public static fun applyOpenTelemetryOptions (Lio/sentry/SentryOptions;)V
28+
public static fun applyOpenTelemetryOptions (Lio/sentry/SentryOptions;Z)V
2929
}
3030

3131
public final class io/sentry/opentelemetry/OtelContextScopesStorage : io/sentry/IScopesStorage {

sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/OpenTelemetryUtil.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99
@ApiStatus.Experimental
1010
public final class OpenTelemetryUtil {
1111

12-
public static void applyOpenTelemetryOptions(final @Nullable SentryOptions options) {
12+
public static void applyOpenTelemetryOptions(
13+
final @Nullable SentryOptions options, final boolean isAgent) {
1314
if (options != null) {
1415
options.setSpanFactory(SentrySpanFactoryHolder.getSpanFactory());
15-
options.setIgnoredSpanOrigins(SpanUtils.ignoredSpanOriginsForOpenTelemetry());
16+
options.setIgnoredSpanOrigins(SpanUtils.ignoredSpanOriginsForOpenTelemetry(isAgent));
1617
}
1718
}
1819
}

sentry-opentelemetry/sentry-opentelemetry-extra/api/sentry-opentelemetry-extra.api

Whitespace-only changes.
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Sentry Sample Spring Boot 3.0+
2+
3+
Sample application showing how to use Sentry with [Spring boot](http://spring.io/projects/spring-boot) from version `3.0` onwards.
4+
5+
## How to run?
6+
7+
To see events triggered in this sample application in your Sentry dashboard, go to `src/main/resources/application.properties` and replace the test DSN with your own DSN.
8+
9+
Then, execute a command from the module directory:
10+
11+
```
12+
../../gradlew bootRun
13+
```
14+
15+
Make an HTTP request that will trigger events:
16+
17+
```
18+
curl -XPOST --user user:password http://localhost:8080/person/ -H "Content-Type:application/json" -d '{"firstName":"John","lastName":"Smith"}'
19+
```
20+
21+
## GraphQL
22+
23+
The following queries can be used to test the GraphQL integration.
24+
25+
### Greeting
26+
```
27+
{
28+
greeting(name: "crash")
29+
}
30+
```
31+
32+
### Greeting with variables
33+
34+
```
35+
query GreetingQuery($name: String) {
36+
greeting(name: $name)
37+
}
38+
```
39+
variables:
40+
```
41+
{
42+
"name": "crash"
43+
}
44+
```
45+
46+
### Project
47+
48+
```
49+
query ProjectQuery($slug: ID!) {
50+
project(slug: $slug) {
51+
slug
52+
name
53+
repositoryUrl
54+
status
55+
}
56+
}
57+
```
58+
variables:
59+
```
60+
{
61+
"slug": "statuscrash"
62+
}
63+
```
64+
65+
### Mutation
66+
67+
```
68+
mutation AddProjectMutation($slug: ID!) {
69+
addProject(slug: $slug)
70+
}
71+
```
72+
variables:
73+
```
74+
{
75+
"slug": "nocrash",
76+
"name": "nocrash"
77+
}
78+
```
79+
80+
### Subscription
81+
82+
```
83+
subscription SubscriptionNotifyNewTask($slug: ID!) {
84+
notifyNewTask(projectSlug: $slug) {
85+
id
86+
name
87+
assigneeId
88+
assignee {
89+
id
90+
name
91+
}
92+
}
93+
}
94+
```
95+
variables:
96+
```
97+
{
98+
"slug": "crash"
99+
}
100+
```
101+
102+
### Data loader
103+
104+
```
105+
query TasksAndAssigneesQuery($slug: ID!) {
106+
tasks(projectSlug: $slug) {
107+
id
108+
name
109+
assigneeId
110+
assignee {
111+
id
112+
name
113+
}
114+
}
115+
}
116+
```
117+
variables:
118+
```
119+
{
120+
"slug": "crash"
121+
}
122+
```
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import org.jetbrains.kotlin.config.KotlinCompilerVersion
2+
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
3+
4+
plugins {
5+
id(Config.BuildPlugins.springBoot) version Config.springBoot3Version
6+
id(Config.BuildPlugins.springDependencyManagement) version Config.BuildPlugins.springDependencyManagementVersion
7+
kotlin("jvm")
8+
kotlin("plugin.spring") version Config.kotlinVersion
9+
id("com.apollographql.apollo3") version "3.8.2"
10+
}
11+
12+
group = "io.sentry.sample.spring-boot-jakarta"
13+
version = "0.0.1-SNAPSHOT"
14+
java.sourceCompatibility = JavaVersion.VERSION_17
15+
java.targetCompatibility = JavaVersion.VERSION_17
16+
17+
repositories {
18+
mavenCentral()
19+
}
20+
21+
configure<JavaPluginExtension> {
22+
sourceCompatibility = JavaVersion.VERSION_17
23+
targetCompatibility = JavaVersion.VERSION_17
24+
}
25+
26+
tasks.withType<KotlinCompile>().configureEach {
27+
kotlinOptions.jvmTarget = JavaVersion.VERSION_17.toString()
28+
}
29+
30+
tasks.withType<KotlinCompile> {
31+
kotlinOptions {
32+
freeCompilerArgs = listOf("-Xjsr305=strict")
33+
jvmTarget = JavaVersion.VERSION_17.toString()
34+
}
35+
}
36+
37+
dependencies {
38+
implementation(Config.Libs.springBoot3StarterSecurity)
39+
implementation(Config.Libs.springBoot3StarterActuator)
40+
implementation(Config.Libs.springBoot3StarterWeb)
41+
implementation(Config.Libs.springBoot3StarterWebsocket)
42+
implementation(Config.Libs.springBoot3StarterGraphql)
43+
implementation(Config.Libs.springBoot3StarterQuartz)
44+
implementation(Config.Libs.springBoot3StarterWebflux)
45+
implementation(Config.Libs.springBoot3StarterAop)
46+
implementation(Config.Libs.aspectj)
47+
implementation(Config.Libs.springBoot3Starter)
48+
implementation(Config.Libs.kotlinReflect)
49+
implementation(Config.Libs.springBootStarterJdbc)
50+
implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION))
51+
implementation(projects.sentrySpringBootStarterJakarta)
52+
implementation(projects.sentryLogback)
53+
implementation(projects.sentryGraphql22)
54+
implementation(projects.sentryQuartz)
55+
implementation(Config.Libs.springBoot3StarterOpenTelemetry)
56+
implementation(projects.sentryOpentelemetry.sentryOpentelemetryBootstrap)
57+
implementation(projects.sentryOpentelemetry.sentryOpentelemetryAgentcustomization)
58+
59+
// database query tracing
60+
implementation(projects.sentryJdbc)
61+
runtimeOnly(Config.TestLibs.hsqldb)
62+
testImplementation(Config.Libs.springBoot3StarterTest) {
63+
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
64+
}
65+
testImplementation(kotlin(Config.kotlinStdLib))
66+
testImplementation(Config.TestLibs.kotlinTestJunit)
67+
testImplementation("ch.qos.logback:logback-classic:1.3.5")
68+
testImplementation(Config.Libs.slf4jApi2)
69+
testImplementation(Config.Libs.apolloKotlin)
70+
}
71+
72+
dependencyManagement {
73+
imports {
74+
mavenBom("io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom:2.7.0")
75+
}
76+
}
77+
78+
configure<SourceSetContainer> {
79+
test {
80+
java.srcDir("src/test/java")
81+
}
82+
}
83+
84+
tasks.register<Test>("systemTest").configure {
85+
group = "verification"
86+
description = "Runs the System tests"
87+
88+
// maxParallelForks = Runtime.getRuntime().availableProcessors() / 2
89+
maxParallelForks = 1
90+
91+
// Cap JVM args per test
92+
minHeapSize = "128m"
93+
maxHeapSize = "1g"
94+
95+
filter {
96+
includeTestsMatching("io.sentry.systemtest*")
97+
}
98+
}
99+
100+
tasks.named("test").configure {
101+
require(this is Test)
102+
103+
filter {
104+
excludeTestsMatching("io.sentry.systemtest.*")
105+
}
106+
}
107+
108+
apollo {
109+
service("service") {
110+
srcDir("src/test/graphql")
111+
packageName.set("io.sentry.samples.graphql")
112+
outputDirConnection {
113+
connectToKotlinSourceSet("test")
114+
}
115+
}
116+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package io.sentry.samples.spring.boot.jakarta;
2+
3+
import io.sentry.EventProcessor;
4+
import io.sentry.Hint;
5+
import io.sentry.SentryEvent;
6+
import io.sentry.protocol.SentryRuntime;
7+
import org.jetbrains.annotations.NotNull;
8+
import org.springframework.boot.SpringBootVersion;
9+
import org.springframework.stereotype.Component;
10+
11+
/**
12+
* Custom {@link EventProcessor} implementation lets modifying {@link SentryEvent}s before they are
13+
* sent to Sentry.
14+
*/
15+
@Component
16+
public class CustomEventProcessor implements EventProcessor {
17+
private final String springBootVersion;
18+
19+
public CustomEventProcessor(String springBootVersion) {
20+
this.springBootVersion = springBootVersion;
21+
}
22+
23+
public CustomEventProcessor() {
24+
this(SpringBootVersion.getVersion());
25+
}
26+
27+
@Override
28+
public @NotNull SentryEvent process(@NotNull SentryEvent event, @NotNull Hint hint) {
29+
final SentryRuntime runtime = new SentryRuntime();
30+
runtime.setVersion(springBootVersion);
31+
runtime.setName("Spring Boot");
32+
event.getContexts().setRuntime(runtime);
33+
return event;
34+
}
35+
}

0 commit comments

Comments
 (0)