Skip to content

Commit 71c1ca1

Browse files
authored
Merge branch 'main' into lcian/ai/new-module-rules
2 parents f6f2348 + c8125f3 commit 71c1ca1

File tree

399 files changed

+20999
-953
lines changed

Some content is hidden

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

399 files changed

+20999
-953
lines changed

.craft.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@ targets:
1919
maven:io.sentry:sentry:
2020
maven:io.sentry:sentry-spring:
2121
maven:io.sentry:sentry-spring-jakarta:
22+
# maven:io.sentry:sentry-spring-7:
2223
maven:io.sentry:sentry-spring-boot:
2324
maven:io.sentry:sentry-spring-boot-jakarta:
2425
maven:io.sentry:sentry-spring-boot-starter:
2526
maven:io.sentry:sentry-spring-boot-starter-jakarta:
27+
# maven:io.sentry:sentry-spring-boot-4:
28+
# maven:io.sentry:sentry-spring-boot-4-starter:
2629
maven:io.sentry:sentry-servlet:
2730
maven:io.sentry:sentry-servlet-jakarta:
2831
maven:io.sentry:sentry-logback:
@@ -59,3 +62,4 @@ targets:
5962
maven:io.sentry:sentry-android-replay:
6063
maven:io.sentry:sentry-apollo-4:
6164
maven:io.sentry:sentry-reactor:
65+
maven:io.sentry:sentry-ktor-client:

.cursor/rules/offline.mdc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
alwaysApply: true
2+
alwaysApply: false
33
description: Java SDK Offline behaviour
44
---
55
# Java SDK Offline behaviour

.cursor/rules/opentelemetry.mdc

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
---
2+
alwaysApply: false
3+
description: Java SDK OpenTelemetry Integration
4+
---
5+
# Java SDK OpenTelemetry Integration
6+
7+
## Overview
8+
9+
The Sentry Java SDK provides comprehensive OpenTelemetry integration through multiple modules:
10+
11+
- `sentry-opentelemetry-core`: Core OpenTelemetry integration functionality
12+
- `sentry-opentelemetry-agent`: Java Agent-based integration for automatic instrumentation
13+
- `sentry-opentelemetry-agentless`: Manual instrumentation without Java agent
14+
- `sentry-opentelemetry-agentless-spring`: Spring-specific agentless integration
15+
- `sentry-opentelemetry-bootstrap`: Classes that go into the bootstrap classloader when the agent is used. For agentless they are simply used in the applications classloader.
16+
- `sentry-opentelemetry-agentcustomization`: Classes that help wire up Sentry in OpenTelemetry. These land in the agent classloader when the agent is used. For agentless they are simply used in the application classloader.
17+
18+
## Advantages over using Sentry without OpenTelemetry
19+
20+
- Support for more libraries and frameworks
21+
- See https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation for a list of supported libraries and frameworks
22+
- More automated Performance instrumentation (spans) created
23+
- Using `sentry-opentelemetry-agent` offers most support
24+
- Using `sentry-opentelemetry-agentless-spring` for Spring Boot also has a lot of supported libraries, altough fewer than the agent does
25+
- Note that `sentry-opentelemetry-agentless` will not have any OpenTelemetry auto instrumentation
26+
- Sentry also relies on OpenTelemetry `Context` propagation to propagate Sentry `Scopes`, ensuring e.g. that execution flow for a request shares data and does not leak data into other requests.
27+
- OpenTelemetry also offers better support for distributed tracing since more libraries are supported for attaching tracing information to outgoing requests and picking up incoming tracing information.
28+
29+
## Key Components
30+
31+
### Agent vs Agentless
32+
33+
**Java Agent-based integration**:
34+
- Automatic instrumentation via Java agent
35+
- Can be added to any JAR when starting, no extra dependencies or code changes required. Just add the agent when running the application, e.g. `SENTRY_PROPERTIES_FILE=sentry.properties JAVA_TOOL_OPTIONS="-javaagent:sentry-opentelemetry-agent.jar" java -jar your-application.jar`.
36+
- Uses OpenTelemetry Java agent with Sentry extensions
37+
- Uses bytecode manipulation
38+
39+
**Agentless-Spring integration**:
40+
- Automatic instrumentation setup via Spring Boot
41+
- Dependency needs to be added to the project.
42+
43+
**Agentless integration**:
44+
- Manual instrumentation setup
45+
- Dependency needs to be added to the project.
46+
47+
**Manual Integration**:
48+
While it's possible to manually wire up all the required classes to make Sentry and OpenTelemetry work together, we do not recommend this.
49+
It is instead preferrable to use `SentryAutoConfigurationCustomizerProvider` so the Sentry SDK has a place to manage required classes and update it when changes are needed.
50+
This way customers receive the updated config automatically as oppposed to having to update manually, wire in new classes, remove old ones etc.
51+
52+
### Integration Architecture
53+
54+
Sentry will try to locate certain classes that come with the Sentry OpenTelemetry integration to:
55+
- Determine whether any Sentry OpenTelemetry integration is present
56+
- Determine which mode to use and in turn which Sentry auto instrumentation to suppress
57+
58+
Reflection is used to search for `io.sentry.opentelemetry.OtelContextScopesStorage` and use it instead of `DefaultScopesStorage` when a Sentry OpenTelemetry integration is present at runtime. `IScopesStorage` is used to store Sentry `Scopes` instances. `DefaultScopesStorage` will use a thread local variable to store the current threads' `Scopes` whereas `OtelContextScopesStorage` makes use of OpenTelemetry SDKs `Context`. Sentry OpenTelemetry integrations configure OpenTelemetry to use `SentryOtelThreadLocalStorage` to customize restoring of the previous `Context`.
59+
60+
OpenTelemetry SDK makes use of `io.opentelemetry.context.Scope` in `try-with-resources` statements that call `close` when a code block is finished. Without customization, it would refuse to restore the previous `Context` onto the `ThreadLocal` if the current state of the `ThreadLocal` isn't the same as the one this scope was created for. Sentry changes this behaviour in `SentryScopeImpl` to restore the previous `Context` onto the `ThreadLocal` even if an inner `io.opentelemetry.context.Scope` wasn't properly cleaned up. Our thinking here is to prefer returning to a clean state as opposed to propagating the problem. The unclean state could happen, if `io.opentelemetry.context.Scope` isn't closed, e.g. when forgetting to put it in a `try-with-resources` statement and not calling `close` (e.g. not putting it in a `finally` block in that case).
61+
62+
`SentryContextStorageProvider` looks for any other `ContextStorageProvider` and forwards to that to not override any customized `ContextStorage`. If no other provider is found, `SentryOtelThreadLocalStorage` is used.
63+
64+
`SpanFactoryFactory` is used to configure Sentry to use `io.sentry.opentelemetry.OtelSpanFactory` if the class is present at runtime. Reflection is used to search for it. If the class is not available, we fall back to `DefaultSpanFactory`.
65+
66+
`DefaultSpanFactory` creates a `SentryTracer` instance when creating a transaction and spans are then created directly on the transaction via `startChild`.
67+
`OtelSpanFactory` instead creates an OpenTelemetry span and wraps it using `OtelTransactionSpanForwarder` to simulate a transaction. The `startChild` invocations on `OtelTransactionSpanForwarder` go through `OtelSpanFactory` again to create the child span.
68+
69+
## Configuration
70+
71+
We use `SentryAutoConfigurationCustomizerProvider` to configure OpenTelemetry for use with Sentry and register required classes, hooks etc.
72+
73+
## Span Processing
74+
75+
Both Sentry and OpenTelemetry API can be used to create spans. When using Sentry API, `OtelSpanFactory` is used to indirectly create a OpenTelemetry span.
76+
Regardless of API used, when an OpenTelemetry span is created, it goes through `SentrySampler` for sampling and `OtelSentrySpanProcessor` for `Scopes` forking and ensuring the trace is continued.
77+
When Sentry API is used, sampling is performed in `Scopes.createTransaction` before forwarding the call to `OtelSpanFactory`. The sampling decision and other sampling details are forwarded to `SentrySampler` and `OtelSentrySpanProcessor`.
78+
79+
When a span is finished, regardless of whether Sentry or OpenTelemetry API is used, it goes through `OtelSentrySpanProcessor` to set the end date and then through `BatchSpanProcessor` which will batch spans and then forward them to `SentrySpanExporter`.
80+
81+
`SentrySpanExporter` collects spans, then structures them to create a transaction for the local root span and attaches child spans to form a span tree.
82+
Some OpenTelemetry attributes are transformed into their corresponding Sentry data structure or format.
83+
84+
After creating the transaction with child spans `SentrySpanExporter` uses Sentry API to send the transaction to Sentry. This API call however forces the use of `DefaultSpanFactory` in order to create the required Sentry classes for sending and also to not create an infinite loop where any span created will cause a new span to be created recursively.
85+
86+
## Troubleshooting
87+
88+
To debug forking of `Scopes`, we added a reference to `parent` `Scopes` and a `creator` String to store the reason why `Scopes` were created or forked.

.fossa.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
version: 3
2+
targets:
3+
exclude:
4+
- type: setuptools

.github/ISSUE_TEMPLATE/bug_report_java.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,11 @@ body:
2424
- sentry-spring-boot-jakarta
2525
- sentry-spring-boot-starter
2626
- sentry-spring-boot-starter-jakarta
27+
- sentry-spring-boot-4
28+
- sentry-spring-boot-4-starter
2729
- sentry-spring
2830
- sentry-spring-jakarta
31+
- sentry-spring-7
2932
- sentry-logback
3033
- sentry-log4j2
3134
- sentry-graphql

.github/workflows/agp-matrix.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ jobs:
2828

2929
steps:
3030
- name: Checkout Repo
31-
uses: actions/checkout@v4
31+
uses: actions/checkout@v5
3232
with:
3333
submodules: 'recursive'
3434

3535
- name: Setup Java Version
36-
uses: actions/setup-java@v4
36+
uses: actions/setup-java@v5
3737
with:
3838
distribution: 'temurin'
3939
java-version: '17'

.github/workflows/build.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ jobs:
1919

2020
steps:
2121
- name: Checkout Repo
22-
uses: actions/checkout@v4
22+
uses: actions/checkout@v5
2323
with:
2424
submodules: 'recursive'
2525

2626
- name: Setup Java Version
27-
uses: actions/setup-java@v4
27+
uses: actions/setup-java@v5
2828
with:
2929
distribution: 'temurin'
3030
java-version: '17'
@@ -45,7 +45,7 @@ jobs:
4545
run: make preMerge
4646

4747
- name: Upload coverage to Codecov
48-
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # pin@v4
48+
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # pin@v4
4949
with:
5050
name: sentry-java
5151
fail_ci_if_error: false

.github/workflows/changes-in-high-risk-code.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
high_risk_code: ${{ steps.changes.outputs.high_risk_code }}
1717
high_risk_code_files: ${{ steps.changes.outputs.high_risk_code_files }}
1818
steps:
19-
- uses: actions/checkout@v4
19+
- uses: actions/checkout@v5
2020
- name: Get changed files
2121
id: changes
2222
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2

.github/workflows/codeql-analysis.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ jobs:
2020

2121
steps:
2222
- name: Checkout Repo
23-
uses: actions/checkout@v4
23+
uses: actions/checkout@v5
2424
with:
2525
submodules: 'recursive'
2626

2727
- name: Setup Java Version
28-
uses: actions/setup-java@v4
28+
uses: actions/setup-java@v5
2929
with:
3030
distribution: 'temurin'
3131
java-version: '17'
@@ -36,7 +36,7 @@ jobs:
3636
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
3737

3838
- name: Initialize CodeQL
39-
uses: github/codeql-action/init@76621b61decf072c1cee8dd1ce2d2a82d33c17ed # pin@v2
39+
uses: github/codeql-action/init@f1f6e5f6af878fb37288ce1c627459e94dbf7d01 # pin@v2
4040
with:
4141
languages: 'java'
4242

@@ -45,4 +45,4 @@ jobs:
4545
./gradlew buildForCodeQL --no-build-cache
4646
4747
- name: Perform CodeQL Analysis
48-
uses: github/codeql-action/analyze@76621b61decf072c1cee8dd1ce2d2a82d33c17ed # pin@v2
48+
uses: github/codeql-action/analyze@f1f6e5f6af878fb37288ce1c627459e94dbf7d01 # pin@v2

.github/workflows/enforce-license-compliance.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,21 @@ jobs:
1414
uses: gradle/actions/setup-gradle@017a9effdb900e5b5b2fddfb590a105619dca3c3
1515

1616
- name: Set up Java
17-
uses: actions/setup-java@v4
17+
uses: actions/setup-java@v5
1818
with:
1919
distribution: 'temurin'
2020
java-version: '17'
2121

22+
- name: Checkout
23+
uses: actions/checkout@v4
24+
25+
# TODO: remove this when upstream is fixed
26+
- name: Disable Gradle configuration cache (see https://github.com/fossas/fossa-cli/issues/872)
27+
run: sed -i 's/^org.gradle.configuration-cache=.*/org.gradle.configuration-cache=false/' gradle.properties
28+
2229
- name: 'Enforce License Compliance'
2330
uses: getsentry/action-enforce-license-compliance@main
2431
with:
32+
skip_checkout: 'true'
33+
fossa_test_timeout_seconds: 3600
2534
fossa_api_key: ${{ secrets.FOSSA_API_KEY }}

0 commit comments

Comments
 (0)