Skip to content

Commit 18608d6

Browse files
authored
Java Continuous Profiling (#15154)
<!-- Use this checklist to make sure your PR is ready for merge. You may delete any sections you don't need. --> ## DESCRIBE YOUR PR Adds docs for Continuous Profiling on JVM (getsentry/sentry-java#2635) ## IS YOUR CHANGE URGENT? Help us prioritize incoming PRs by letting us know when the change needs to go live. - [ ] Urgent deadline (GA date, etc.): <!-- ENTER DATE HERE --> - [ ] Other deadline: <!-- ENTER DATE HERE --> - [ ] None: Not urgent, can wait up to 1 week+ ## SLA - Teamwork makes the dream work, so please add a reviewer to your PRs. - Please give the docs team up to 1 week to review your PR unless you've added an urgent due date to it. Thanks in advance for your help! ## PRE-MERGE CHECKLIST *Make sure you've checked the following before merging your changes:* - [ ] Checked Vercel preview for correctness, including links - [ ] PR was reviewed and approved by any necessary SMEs (subject matter experts) - [ ] PR was reviewed and approved by a member of the [Sentry docs team](https://github.com/orgs/getsentry/teams/docs) ## LEGAL BOILERPLATE <!-- Sentry employees and contractors can delete or ignore this section. --> Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. and is gonna need some rights from me in order to utilize my contributions in this here PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms. ## EXTRA RESOURCES - [Sentry Docs contributor guide](https://docs.sentry.io/contributing/)
1 parent d2614b4 commit 18608d6

File tree

17 files changed

+591
-16
lines changed

17 files changed

+591
-16
lines changed

docs/platforms/java/common/configuration/options.mdx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,3 +284,20 @@ Controls whether the SDK should propagate the W3C `traceparent` HTTP header alon
284284
Set this boolean to `false` to disable tracing for `OPTIONS` requests. This options default value will likely be changed in the next major version, meaning you will have to set it to `true` if you want to keep tracing `OPTIONS` requests.
285285

286286
</SdkOption>
287+
288+
## Profiling Options
289+
290+
<SdkOption name="profileSessionSampleRate" type="float" availableSince="8.23.0">
291+
292+
A number between `0` and `1`, controlling the percentage chance that the session will be profiled. (`0` represents 0%, `1` represents 100%.) The default is null (disabled).
293+
294+
</SdkOption>
295+
296+
<SdkOption name="profileLifecycle" type="enum" defaultValue="manual" availableSince="8.23.0">
297+
298+
Whether the continuous profiling lifecycle is controlled manually or based on the trace lifecycle. Possible values are:
299+
300+
- `manual`: **default** Profiler must be started and stopped through `Sentry.startProfiler()` and `Sentry.stopProfiler()` APIs
301+
- `trace`: Profiler is started and stopped automatically whenever a sampled trace starts or finishes
302+
303+
</SdkOption>
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
title: Set Up Java Profiling
3+
sidebar_title: Profiling
4+
description: "Learn how to enable profiling in your app if it is not already set up."
5+
sidebar_order: 5000
6+
supported:
7+
- java
8+
---
9+
10+
<PlatformContent includePath="profiling/index/preface" />
11+
<PlatformContent includePath="profiling/index/why-profiling" />
12+
13+
<Alert>
14+
15+
Continuous profiling is available starting in SDK version `8.23.0` for macOS and Linux.
16+
17+
</Alert>
18+
19+
<Alert level="warning">
20+
Versions < `8.26.0` use [async-profiler](https://github.com/async-profiler/async-profiler) in version 3 and thus only support Java up to JDK 22. Starting with `8.26.0` we upgraded to [async-profiler](https://github.com/async-profiler/async-profiler) 4.2 enabling support for all Java versions up to JDK 25.
21+
</Alert>
22+
23+
## Install
24+
25+
In addition to your typical Sentry dependencies, you will need to add `sentry-async-profiler` as a dependency:
26+
27+
```groovy {tabTitle:Gradle}
28+
implementation 'io.sentry:sentry-async-profiler:{{@inject packages.version('sentry.java.async-profiler', '8.23.0') }}'
29+
```
30+
```xml {tabTitle:Maven}
31+
<dependency>
32+
<groupId>io.sentry</groupId>
33+
<artifactId>sentry-async-profiler</artifactId>
34+
<version>{{@inject packages.version('sentry.java.async-profiler', '8.23.0') }}</version>
35+
</dependency>
36+
```
37+
38+
## Enabling Continuous Profiling
39+
40+
Continuous profiling supports two modes - `manual` and `trace`. The two modes are mutually exclusive, and cannot be used at the same time.
41+
42+
In `manual` mode, the profiling data collection can be managed via calls to `Sentry.startProfiler()` and `Sentry.stopProfiler()`. You are entirely in control of when the profiler runs.
43+
44+
In `trace` mode, the profiler manages its own start and stop calls, which are based on spans: the profiler continues to run while there is at least one active span, and stops when there are no active spans.
45+
46+
<PlatformContent includePath="profiling/automatic-instrumentation-setup" />
47+
48+
### Managing Profile Sampling Rates
49+
50+
Sentry SDK supports an additional `profileSessionSampleRate` that must be set to a non-zero value to enable continuous profiling. This can be used to control session sampling rates at the service level as the sampling decision is evaluated only once at SDK initialization.
51+
52+
This is useful for cases where you deploy your service many times, but would only like a subset of those deployments to be profiled. In a single service environment we recommend to set this to 1.0.
53+
54+
### Manage Storage Location for Profiles
55+
The files generated by the underlying profiler are temporarily stored. By default we use the directory `System.getProperty("java.io.tmpdir")/profiling_traces`. This path can be configured by setting the `profilingTracesDirPath` option.
56+
57+
## Platform Support
58+
59+
Continuous profiling for Java is currently supported on:
60+
61+
- macOS
62+
- Linux
63+
64+
The profiler uses [async-profiler](https://github.com/async-profiler/async-profiler) under the hood to collect profiling data.
65+

docs/product/explore/profiling/index.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Profiling helps you quickly identify performance bottlenecks, enabling you to bu
3434
- [React Native [beta]](/platforms/react-native/profiling/)
3535
- [Flutter [experimental, iOS and macOS only]](/platforms/dart/guides/flutter/profiling/)
3636
- [.NET [experimental]](/platforms/dotnet/profiling/)
37+
- [JVM (Java and other JVM based languages)](/platforms/java/profiling/)
3738

3839
</Alert>
3940

platform-includes/getting-started-config/java.mdx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,3 @@
1-
<OnboardingOptionButtons
2-
options={[
3-
'error-monitoring',
4-
'performance',
5-
'profiling',
6-
'logs',
7-
]}
8-
/>
9-
101
<OnboardingOption optionId="opentelemetry" hideForThisOption>
112
Configuration should happen as early as possible in your application's lifecycle.
123

@@ -26,6 +17,12 @@ Sentry.init(options -> {
2617
// We recommend adjusting this value in production.
2718
options.setTracesSampleRate(1.0);
2819
// ___PRODUCT_OPTION_END___ performance
20+
// ___PRODUCT_OPTION_START___ profiling
21+
22+
// Enable profiling
23+
options.setProfileSessionSampleRate(1.0);
24+
options.setProfileLifecycle(ProfileLifecycle.TRACE);
25+
// ___PRODUCT_OPTION_END___ profiling
2926
// ___PRODUCT_OPTION_START___ logs
3027

3128
// Enable logs to be sent to Sentry
@@ -50,6 +47,12 @@ Sentry.init { options ->
5047
// We recommend adjusting this value in production.
5148
options.tracesSampleRate = 1.0
5249
// ___PRODUCT_OPTION_END___ performance
50+
// ___PRODUCT_OPTION_START___ profiling
51+
52+
// Enable profiling
53+
options.profileSessionSampleRate = 1.0
54+
options.profileLifecycle = ProfileLifecycle.TRACE
55+
// ___PRODUCT_OPTION_END___ profiling
5356
// ___PRODUCT_OPTION_START___ logs
5457

5558
// Enable logs to be sent to Sentry

platform-includes/getting-started-config/java.spring-boot.mdx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ sentry.send-default-pii=true
1616
# We recommend adjusting this value in production.
1717
sentry.traces-sample-rate=1.0
1818
# ___PRODUCT_OPTION_END___ performance
19+
// ___PRODUCT_OPTION_START___ profiling
20+
21+
# Enable profiling
22+
sentry.profile-session-sample-rate=1.0
23+
sentry.profile-lifecycle=TRACE
24+
// ___PRODUCT_OPTION_END___ profiling
1925
```
2026

2127
```yaml {filename:application.yml}
@@ -32,6 +38,12 @@ sentry:
3238
# We recommend adjusting this value in production.
3339
tracesSampleRate: 1.0
3440
# ___PRODUCT_OPTION_END___ performance
41+
// ___PRODUCT_OPTION_START___ profiling
42+
43+
# Enable profiling
44+
profileSessionSampleRate: 1.0
45+
profileLifecycle: TRACE
46+
// ___PRODUCT_OPTION_END___ profiling
3547
```
3648

3749
By default, only unhandled exceptions are sent to Sentry. This behavior can be tuned through configuring the `sentry.exception-resolver-order` property. For example, setting it to `-2147483647` (the value of `org.springframework.core.Ordered#HIGHEST_PRECEDENCE`) ensures exceptions that have been handled by exception resolvers with higher order are sent to Sentry - including ones handled by `@ExceptionHandler` annotated methods.

platform-includes/getting-started-config/java.spring.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,5 +196,10 @@ The SDK can be configured using a `sentry.properties` file:
196196

197197
```properties {filename:sentry.properties}
198198
traces-sample-rate=1.0
199+
// ___PRODUCT_OPTION_START___ profiling
200+
# Enable profiling
201+
profile-session-sample-rate=1.0
202+
profile-lifecycle=TRACE
203+
// ___PRODUCT_OPTION_END___ profiling
199204
```
200205
</OnboardingOption>

platform-includes/getting-started-config/opentelemetry/java.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,11 @@ send-default-pii=true
1010
# ___PRODUCT_OPTION_START___ performance
1111
traces-sample-rate=1.0
1212
# ___PRODUCT_OPTION_END___ performance
13+
// ___PRODUCT_OPTION_START___ profiling
14+
15+
# Enable profiling
16+
profile-session-sample-rate=1.0
17+
profile-lifecycle=TRACE
18+
// ___PRODUCT_OPTION_END___ profiling
1319
```
1420
</OnboardingOption>

platform-includes/getting-started-install/java.jul.mdx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<OnboardingOptionButtons
2-
options={["error-monitoring", "performance", {id: "opentelemetry", checked: true}]}
2+
options={["error-monitoring", "performance", {id: "opentelemetry", checked: true}, "profiling"]}
33
/>
44

55
```xml {tabTitle:Maven}
@@ -8,14 +8,27 @@
88
<artifactId>sentry-jul</artifactId>
99
<version>{{@inject packages.version('sentry.java.jul', '4.1.0') }}</version>
1010
</dependency>
11+
// ___PRODUCT_OPTION_START___ profiling
12+
<dependency>
13+
<groupId>io.sentry</groupId>
14+
<artifactId>sentry-async-profiler</artifactId>
15+
<version>{{@inject packages.version('sentry.java.async-profiler', '8.23.0') }}</version>
16+
</dependency>
17+
// ___PRODUCT_OPTION_END___ profiling
1118
```
1219

1320
```groovy {tabTitle:Gradle}
1421
implementation 'io.sentry:sentry-jul:{{@inject packages.version('sentry.java.jul', '4.1.0') }}'
22+
// ___PRODUCT_OPTION_START___ profiling
23+
implementation 'io.sentry:sentry-async-profiler:{{@inject packages.version('sentry.java.async-profiler', '8.23.0') }}'
24+
// ___PRODUCT_OPTION_END___ profiling
1525
```
1626

1727
```scala {tabTitle: SBT}
1828
libraryDependencies += "io.sentry" % "sentry-jul" % "{{@inject packages.version('sentry.java.jul', '4.1.0') }}"
29+
// ___PRODUCT_OPTION_START___ profiling
30+
libraryDependencies += "io.sentry" % "sentry-async-profiler" % "{{@inject packages.version('sentry.java.async-profiler', '8.23.0') }}"
31+
// ___PRODUCT_OPTION_END___ profiling
1932
```
2033

2134
For other dependency managers, see the [central Maven repository](https://search.maven.org/artifact/io.sentry/sentry-jul).

platform-includes/getting-started-install/java.log4j2.mdx

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<OnboardingOptionButtons
2-
options={["error-monitoring", "performance", {id: "opentelemetry", checked: true}]}
2+
options={["error-monitoring", "performance", {id: "opentelemetry", checked: true}, "profiling"]}
33
/>
44

55
```xml {tabTitle:Maven Plugin}{filename:pom.xml}
@@ -35,6 +35,15 @@
3535
</execution>
3636
</executions>
3737
</plugin>
38+
// ___PRODUCT_OPTION_START___ profiling
39+
<dependencies>
40+
<dependency>
41+
<groupId>io.sentry</groupId>
42+
<artifactId>sentry-async-profiler</artifactId>
43+
<version>{{@inject packages.version('sentry.java.async-profiler', '8.23.0') }}</version>
44+
</dependency>
45+
</dependencies>
46+
// ___PRODUCT_OPTION_END___ profiling
3847
```
3948

4049
```xml {tabTitle:Maven}
@@ -43,20 +52,38 @@
4352
<artifactId>sentry-log4j2</artifactId>
4453
<version>{{@inject packages.version('sentry.java.log4j2', '4.2.0') }}</version>
4554
</dependency>
55+
// ___PRODUCT_OPTION_START___ profiling
56+
<dependency>
57+
<groupId>io.sentry</groupId>
58+
<artifactId>sentry-async-profiler</artifactId>
59+
<version>{{@inject packages.version('sentry.java.async-profiler', '8.23.0') }}</version>
60+
</dependency>
61+
// ___PRODUCT_OPTION_END___ profiling
4662
```
4763

4864
```groovy {tabTitle:Gradle Plugin}
4965
plugins {
5066
id "io.sentry.jvm.gradle" version "{{@inject packages.version('sentry.java.android.gradle-plugin', '3.12.0') }}"
5167
}
68+
// ___PRODUCT_OPTION_START___ profiling
69+
dependencies {
70+
implementation 'io.sentry:sentry-async-profiler:{{@inject packages.version('sentry.java.async-profiler', '8.23.0') }}'
71+
}
72+
// ___PRODUCT_OPTION_END___ profiling
5273
```
5374

5475
```groovy {tabTitle:Gradle}
5576
implementation 'io.sentry:sentry-log4j2:{{@inject packages.version('sentry.java.log4j2', '4.2.0') }}'
77+
// ___PRODUCT_OPTION_START___ profiling
78+
implementation 'io.sentry:sentry-async-profiler:{{@inject packages.version('sentry.java.async-profiler', '8.23.0') }}'
79+
// ___PRODUCT_OPTION_END___ profiling
5680
```
5781

5882
```scala {tabTitle: SBT}
5983
libraryDependencies += "io.sentry" % "sentry-log4j2" % "{{@inject packages.version('sentry.java.log4j2', '4.2.0') }}"
84+
// ___PRODUCT_OPTION_START___ profiling
85+
libraryDependencies += "io.sentry" % "sentry-async-profiler" % "{{@inject packages.version('sentry.java.async-profiler', '8.23.0') }}"
86+
// ___PRODUCT_OPTION_END___ profiling
6087
```
6188

6289
For other dependency managers see the [central Maven repository](https://search.maven.org/artifact/io.sentry/sentry-log4j2).

platform-includes/getting-started-install/java.logback.mdx

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<OnboardingOptionButtons
2-
options={["error-monitoring", "performance", {id: "opentelemetry", checked: true}]}
2+
options={["error-monitoring", "performance", {id: "opentelemetry", checked: true}, "profiling"]}
33
/>
44

55
```xml {tabTitle:Maven Plugin}{filename:pom.xml}
@@ -35,6 +35,15 @@
3535
</execution>
3636
</executions>
3737
</plugin>
38+
// ___PRODUCT_OPTION_START___ profiling
39+
<dependencies>
40+
<dependency>
41+
<groupId>io.sentry</groupId>
42+
<artifactId>sentry-async-profiler</artifactId>
43+
<version>{{@inject packages.version('sentry.java.async-profiler', '8.23.0') }}</version>
44+
</dependency>
45+
</dependencies>
46+
// ___PRODUCT_OPTION_END___ profiling
3847
```
3948

4049
```xml {tabTitle:Maven}
@@ -43,20 +52,38 @@
4352
<artifactId>sentry-logback</artifactId>
4453
<version>{{@inject packages.version('sentry.java.logback', '4.2.0') }}</version>
4554
</dependency>
55+
// ___PRODUCT_OPTION_START___ profiling
56+
<dependency>
57+
<groupId>io.sentry</groupId>
58+
<artifactId>sentry-async-profiler</artifactId>
59+
<version>{{@inject packages.version('sentry.java.async-profiler', '8.23.0') }}</version>
60+
</dependency>
61+
// ___PRODUCT_OPTION_END___ profiling
4662
```
4763

4864
```groovy {tabTitle:Gradle Plugin}
4965
plugins {
5066
id "io.sentry.jvm.gradle" version "{{@inject packages.version('sentry.java.android.gradle-plugin', '3.12.0') }}"
5167
}
68+
// ___PRODUCT_OPTION_START___ profiling
69+
dependencies {
70+
implementation 'io.sentry:sentry-async-profiler:{{@inject packages.version('sentry.java.async-profiler', '8.23.0') }}'
71+
}
72+
// ___PRODUCT_OPTION_END___ profiling
5273
```
5374

5475
```groovy {tabTitle:Gradle}
5576
implementation 'io.sentry:sentry-logback:{{@inject packages.version('sentry.java.logback', '4.2.0') }}'
77+
// ___PRODUCT_OPTION_START___ profiling
78+
implementation 'io.sentry:sentry-async-profiler:{{@inject packages.version('sentry.java.async-profiler', '8.23.0') }}'
79+
// ___PRODUCT_OPTION_END___ profiling
5680
```
5781

5882
```scala {tabTitle: SBT}
5983
libraryDependencies += "io.sentry" % "sentry-logback" % "{{@inject packages.version('sentry.java.logback', '4.2.0') }}"
84+
// ___PRODUCT_OPTION_START___ profiling
85+
libraryDependencies += "io.sentry" % "sentry-async-profiler" % "{{@inject packages.version('sentry.java.async-profiler', '8.23.0') }}"
86+
// ___PRODUCT_OPTION_END___ profiling
6087
```
6188

6289
For other dependency managers, see the [central Maven repository](https://search.maven.org/artifact/io.sentry/sentry-logback).

0 commit comments

Comments
 (0)