Repository navigation
feat: allow custom profilers for sampled transactions - #2253
Open
binaryfire wants to merge 2 commits into
Open
binaryfire wants to merge 2 commits into
binaryfire wants to merge 2 commits into
Conversation
Expose the existing start, stop and profile retrieval operations through ProfilerInterface so integrations can supply their own sample collectors. Keep the Excimer implementation unchanged and make the Profile construction and sample input methods public contracts. Document the sample timestamp base while keeping envelope formatting internal.
Allow integrations to create an independent sample collector for each profiled transaction through profiler_factory. Retain the default Excimer profiler and the existing trace and profile sampling decisions. Log collector failures without losing the transaction, and stop a collector only once when finish is called repeatedly so pending profile data remains intact. Validate options, factory ownership, profile forwarding and failure handling. composer check passes with 1998 tests, 5050 assertions and 11 skips; a stock Excimer and Fiber integration probe also produces a valid profile without unrelated execution samples.
1 of 3 tasks
Contributor
Author
|
I've added the companion docs in getsentry/sentry-docs#19890. It's a draft until the SDK change is released. |
Litarnus
reviewed
Oct 11, 2026
Litarnus
left a comment
Contributor
There was a problem hiding this comment.
Looks very nice, thank you!
We recently added try/catch around user provided callbacks, could you please add it here too? It doesn't have to be anything fancy, a log message is enough
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This follows on from #2190 and #2191, this time for profiling.
Excimer records whichever PHP stack is running when it takes a sample. In an async server, that might belong to a different request. For example, while request A is waiting for I/O, request B can run and have its work included in A’s profile.
An integration can use Excimer’s existing callbacks to separate those samples, but the SDK creates and manages its profiler internally. There isn’t currently a supported way to replace how samples are collected.
This PR adds a
profiler_factoryoption:Here,
RequestProfilerwould be supplied by the framework or application. The factory creates a separate profiler for each sampled transaction. The interface has three methods:start(),stop(), andgetProfile().Sentry still makes the sampling decisions and handles formatting and sending the resulting profile. The integration controls how samples are collected and when its collection resources are released.
Without a factory, the SDK continues to use its existing Excimer profiler. The factory is only called for transactions selected for profiling; this doesn’t add a callback to each stack sample.
Finishing a transaction twice also stops its profiler only once. Previously, the second stop could replace the collected samples with an empty log before the event was serialized.
I tested this with a custom collector using stock Excimer and PHP Fibers. The SDK produced a valid profile containing the intended Fiber’s work and excluding work performed while it was suspended. No Excimer changes were needed.
I ran into this while working on Hypervel, but the extension isn’t tied to it or to Swoole. Other async frameworks can use their own execution context to decide which samples belong to a transaction.
The options documentation will also need an entry for
profiler_factory.