Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(profiling): Introduce continuous profiling mode #2830

Open
wants to merge 31 commits into
base: master
Choose a base branch
from

Conversation

Zylphrex
Copy link
Member

This is a new profiling mode that is mutually exclusive from the existing profiling modes. In the current profiling modes, a profile is always directly attached to a transaction. This new mode will continuously emit chunks of profiling data that will be connected to the span data.

This is a new profiling mode that is mutually exclusive from the existing
profiling modes. In the current profiling modes, a profile is always directly
attached to a transaction. This new mode will continuously emit chunks of
profiling data that will be connected to the span data.
Zylphrex added a commit that referenced this pull request Mar 18, 2024
As per getsentry/rfc#75, this adds the thread data to the spans. This will be
needed for the continuous profiling mode in #2830.
Zylphrex added a commit that referenced this pull request Mar 20, 2024
As per getsentry/rfc#75, this adds the thread data to the spans. This will be
needed for the continuous profiling mode in #2830.
@Zylphrex Zylphrex marked this pull request as ready for review May 7, 2024 13:44
@Zylphrex Zylphrex requested review from antonpirker, sentrivana and a team May 7, 2024 13:44
Copy link
Contributor

@sentrivana sentrivana left a comment

Choose a reason for hiding this comment

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

Left a few comments, but in general looks great to me

@@ -0,0 +1,543 @@
import atexit
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we put this file in a new profiler folder together with the original profiler.py just to have it a bit more organized? We can export the user-facing API like stop_profiler in profiler/__init__.py.

Comment on lines +382 to +389
else:
try:
setup_continuous_profiler(
self.options,
capture_func=_capture_envelope,
)
except Exception as e:
logger.debug("Can not set up continuous profiler. (%s)", e)
Copy link
Contributor

Choose a reason for hiding this comment

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

So the continuous profiler is always enabled unless the user wants to use the old profiler, and there is no way to turn all profilers off if I read this correctly -- does this have any consequences for the user (e.g. quota)?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah ok, the user has to explicitly provide _experiments["continuous_profiling_auto_start"] for the profiler to kick off right? Then disregard.

Comment on lines 108 to 111
ProfileContext = TypedDict(
"ProfileContext",
{"profile_id": str},
{"profiler_id": str},
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is ProfileContext even used anywhere? Can't find any occurrences

import threading
import time
from collections import defaultdict
from unittest import mock # python 3.3 and above
Copy link
Contributor

Choose a reason for hiding this comment

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

We only support 3.5+ so no need for the comment

Suggested change
from unittest import mock # python 3.3 and above
from unittest import mock

experiments.get("continuous_profiling_mode") or default_profiler_mode
)

frequency = DEFAULT_SAMPLING_FREQUENCY
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make sense to make this configurable?

self.thread = None
return

def run(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

Unless I missed anything, run seems to be the same for both the thread- and gevent-based profiler, is there anything speaking against putting it in the parent ContinuousProfiler class?

if self.buffer is not None:
self.buffer.flush()

def teardown(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment as above for run

@@ -0,0 +1,237 @@
import threading
Copy link
Contributor

Choose a reason for hiding this comment

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

If you decide to go with the new profiler folder in the sdk that I suggested above, it'd make sense to do the same with test_continuous_profiler.py and test_profiler.py in the tests.

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.

None yet

2 participants