Skip to content

Conversation

lbloder
Copy link
Collaborator

@lbloder lbloder commented Sep 23, 2025

  • Sets profilerId in SpanContext when span/transaction is created by OTEL
    • Scopes do not start profiler if profilerId already in SpanContext
  • Stop profiler immediately instead of waiting for the 10s timeout to occur
  • Drop single event (sample) instead of whole chunk if any exception occurs during processing.
  • Improved error handling
  • Fixes for issues discovered in previous PR

💡 Motivation and Context

💚 How did you test it?

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

🔮 Next steps

Copy link
Contributor

🚨 Detected changes in high risk code 🚨

High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:

  • sentry/src/main/java/io/sentry/transport/RateLimiter.java

Copy link
Contributor

github-actions bot commented Sep 23, 2025

Fails
🚫 Please consider adding a changelog entry for the next release.
Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Instructions and example for changelog

Please add an entry to CHANGELOG.md to the "Unreleased" section. Make sure the entry includes this PR's number.

Example:

## Unreleased

- Profiling - OTEL profiling fix, Stabilization, Logging ([#4746](https://github.com/getsentry/sentry-java/pull/4746))

If none of the above apply, you can opt out of this check by adding #skip-changelog to the PR description or adding a skip-changelog label.

Generated by 🚫 dangerJS against 2295cba

Copy link
Contributor

github-actions bot commented Sep 23, 2025

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 366.26 ms 417.02 ms 50.77 ms
Size 1.58 MiB 2.09 MiB 521.70 KiB

Baseline results on branch: feat/continuous-profiling-03

Startup times

Revision Plain With Sentry Diff
42206f4 419.73 ms 494.82 ms 75.09 ms
066d89d 377.51 ms 434.20 ms 56.69 ms
d6f8356 392.08 ms 454.42 ms 62.34 ms
7dcbbbd 459.22 ms 509.85 ms 50.62 ms
f2cd43a 415.48 ms 485.28 ms 69.80 ms

App size

Revision Plain With Sentry Diff
42206f4 1.58 MiB 2.09 MiB 521.84 KiB
066d89d 1.58 MiB 2.09 MiB 521.85 KiB
d6f8356 1.58 MiB 2.09 MiB 521.68 KiB
7dcbbbd 1.58 MiB 2.09 MiB 521.68 KiB
f2cd43a 1.58 MiB 2.09 MiB 521.84 KiB

Previous results on branch: feat/continuous-profiling-04

Startup times

Revision Plain With Sentry Diff
5c219a7 360.48 ms 423.72 ms 63.24 ms
360cb4c 361.89 ms 418.44 ms 56.54 ms

App size

Revision Plain With Sentry Diff
5c219a7 1.58 MiB 2.09 MiB 521.70 KiB
360cb4c 1.58 MiB 2.09 MiB 521.69 KiB

Copy link
Contributor

🚨 Detected changes in high risk code 🚨

High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:

  • sentry/src/main/java/io/sentry/transport/RateLimiter.java

Copy link
Contributor

🚨 Detected changes in high risk code 🚨

High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:

  • sentry/src/main/java/io/sentry/transport/RateLimiter.java

Copy link
Contributor

🚨 Detected changes in high risk code 🚨

High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:

  • sentry/src/main/java/io/sentry/transport/RateLimiter.java

@lbloder
Copy link
Collaborator Author

lbloder commented Sep 23, 2025

@sentry review

@lbloder
Copy link
Collaborator Author

lbloder commented Sep 23, 2025

cursor review

cursor[bot]

This comment was marked as outdated.

Copy link
Member

@adinauer adinauer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

val minTimestamp = samples.minOf { it.timestamp }
val maxTimestamp = samples.maxOf { it.timestamp }
val sampleTimeStamp =
DateUtils.nanosToDate((maxTimestamp * 1000 * 1000 * 1000).toLong()).toInstant()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l Could use DateUtils.secondsToNanos

@lbloder lbloder marked this pull request as ready for review September 26, 2025 06:59
@lbloder lbloder merged commit 242ca41 into feat/continuous-profiling-03 Sep 26, 2025
31 of 36 checks passed
@lbloder lbloder deleted the feat/continuous-profiling-04 branch September 26, 2025 08:26
lbloder added a commit that referenced this pull request Sep 26, 2025
* add readme and info about commit of the source repository

* delete jfr file on jvm exit

* further split into smaller methods

* deduplicate frames in order to save bandwidth, add converter tests

* remove Platform Enum, use string constants instead for compatibility with cross platform frameworks

* implement equals and hashcode for SentryStackFrame to make frame deduplication work

* bump api

* improve error handling, fix start stop start flow

* add new testfile

* calculate ticksPerNanosecond in constructor

* adapt Ratelimiter to check for both ProfileChunk and ProfileChunkUi ratelimiting

* update ratelimiter test to check for both profileChunk and profileChunkUi drops

* use string constant instead of string

* Format code

* add non aggregating event collector to send each event individually, deduplicate stacks

* adapt converter tests to new non-aggregated converter

* Format code

* add logging to loadProfileConverter

* Format code

* fix duplication of events

* catch all exception happening when converting from jfr

* add exists and writable info to log message

* add method to safely delete file

* remove setNative call

* fix test

* fix reference to commit we vendored from

* drop event if it cannot be processed to not lose the whole chunk

* make format

* fix test

* Format code

* Profiling - OTEL profiling fix, Stabilization, Logging (#4746)

* add skipProfiling flag to TransactionOptions to be able to skip profiling and handle cases where profiling has been started by otel

* add profilerId to spanContext so that otel span processor can propagate this to the exporter and SentryTracer

* immediately end profiling when stopProfiler is called

* bump api, fix android api 24 code

* catch all exception happening when converting from jfr

* simplify JavaContinuous profiler by catching AsyncProfiler instantiation exceptions in provider

* add exists and writable info to log message

* add method to safely delete file

* remove setNative call

* fix test

* fix reference to commit we vendored from

* drop event if it cannot be processed to not lose the whole chunk

* Format code

* fix test

* Format code

* fix test

* catch exceptions in startProfiler/stopProfiler

* fallback to threadId -1 if it cannot be resolved

---------

Co-authored-by: Sentry Github Bot <[email protected]>

---------

Co-authored-by: Sentry Github Bot <[email protected]>
lbloder added a commit that referenced this pull request Sep 26, 2025
* delete unused JfrFrame and JfrToSentryProfileconverter

* use passed-in profilingTracesHz parameter instead of hardcoded value

* start profiler before starting the transaction when ProfileLifecycle.TRACE is used to have the profile ID when SentryTracer is created

* use improved way to calculate timestamp of sample

* api dump

* let profile-lifecycle be set from external_options, add tests for SpringBoot autoconfig

* initialize stackTraceFactory only once per chunk

* rename profile data classes, add deserialization and tests

* extract methods in ProfileConverter, fix SentryProfile serialization and make fields private

* use wall=[interval] instead of setting the event to wall and setting the interval separately, this seems to work better and create more samples

* start/stop profiler in OtelSentrySpanProcesser in trace mode for root spans

* add profiler dependency to jakarta-opentelemetry sample, add needed configs

* add dependenies and config to spring-boot-jakarta sample

* remove connection status check

* extract event visitor

* Add enum for ProfileChunk platform

* fallback to default temp directory for profiling on jvm if directory is not configured

* cleanup some minor things

* remove ProfilingInitializer, fix comments

* Format code

* add getter/setter to sample and metadata

* fix compile error

* add comment/todo for deleteOnExit

* Profiling - Deduplication and cleanup (#4681)

* add readme and info about commit of the source repository

* delete jfr file on jvm exit

* further split into smaller methods

* deduplicate frames in order to save bandwidth, add converter tests

* remove Platform Enum, use string constants instead for compatibility with cross platform frameworks

* implement equals and hashcode for SentryStackFrame to make frame deduplication work

* bump api

* improve error handling, fix start stop start flow

* add new testfile

* calculate ticksPerNanosecond in constructor

* adapt Ratelimiter to check for both ProfileChunk and ProfileChunkUi ratelimiting

* update ratelimiter test to check for both profileChunk and profileChunkUi drops

* use string constant instead of string

* Format code

* add non aggregating event collector to send each event individually, deduplicate stacks

* adapt converter tests to new non-aggregated converter

* Format code

* add logging to loadProfileConverter

* Format code

* fix duplication of events

* catch all exception happening when converting from jfr

* add exists and writable info to log message

* add method to safely delete file

* remove setNative call

* fix test

* fix reference to commit we vendored from

* drop event if it cannot be processed to not lose the whole chunk

* make format

* fix test

* Format code

* Profiling - OTEL profiling fix, Stabilization, Logging (#4746)

* add skipProfiling flag to TransactionOptions to be able to skip profiling and handle cases where profiling has been started by otel

* add profilerId to spanContext so that otel span processor can propagate this to the exporter and SentryTracer

* immediately end profiling when stopProfiler is called

* bump api, fix android api 24 code

* catch all exception happening when converting from jfr

* simplify JavaContinuous profiler by catching AsyncProfiler instantiation exceptions in provider

* add exists and writable info to log message

* add method to safely delete file

* remove setNative call

* fix test

* fix reference to commit we vendored from

* drop event if it cannot be processed to not lose the whole chunk

* Format code

* fix test

* Format code

* fix test

* catch exceptions in startProfiler/stopProfiler

* fallback to threadId -1 if it cannot be resolved

---------

Co-authored-by: Sentry Github Bot <[email protected]>

---------

Co-authored-by: Sentry Github Bot <[email protected]>

---------

Co-authored-by: Sentry Github Bot <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants