Skip to content

Commit 28ce4d1

Browse files
committed
ref: Add profiling to span first
1 parent 7ada1f3 commit 28ce4d1

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

sentry_sdk/traces.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515

1616
import sentry_sdk
1717
from sentry_sdk.consts import SPANDATA
18+
from sentry_sdk.profiler.continuous_profiler import (
19+
get_profiler_id,
20+
try_autostart_continuous_profiler,
21+
try_profile_lifecycle_trace_start,
22+
)
1823
from sentry_sdk.tracing_utils import Baggage
1924
from sentry_sdk.utils import (
2025
capture_internal_exceptions,
@@ -28,6 +33,7 @@
2833
if TYPE_CHECKING:
2934
from typing import Any, Callable, Iterator, Optional, ParamSpec, TypeVar, Union
3035
from sentry_sdk._types import Attributes, AttributeValue
36+
from sentry_sdk.profiler.continuous_profiler import ContinuousProfile
3137

3238
P = ParamSpec("P")
3339
R = TypeVar("R")
@@ -232,6 +238,7 @@ class StreamedSpan:
232238
"_baggage",
233239
"_sample_rand",
234240
"_sample_rate",
241+
"_continuous_profile",
235242
)
236243

237244
def __init__(
@@ -284,6 +291,10 @@ def __init__(
284291

285292
self._update_active_thread()
286293

294+
self._continuous_profile: "Optional[ContinuousProfile]" = None
295+
self._start_profile()
296+
self._set_profile_id(get_profiler_id())
297+
287298
self._start()
288299

289300
def __repr__(self) -> str:
@@ -340,6 +351,11 @@ def _end(self, end_timestamp: "Optional[Union[float, datetime]]" = None) -> None
340351
# This span is already finished, ignore.
341352
return
342353

354+
# Stop the profiler
355+
if self._is_segment() and self._continuous_profile is not None:
356+
with capture_internal_exceptions():
357+
self._continuous_profile.stop()
358+
343359
# Detach from scope
344360
if self._active:
345361
with capture_internal_exceptions():
@@ -528,6 +544,24 @@ def _get_trace_context(self) -> "dict[str, Any]":
528544

529545
return context
530546

547+
def _set_profile_id(self, profiler_id: "Optional[str]") -> None:
548+
if profiler_id is not None:
549+
self.set_attribute("sentry.profiler_id", profiler_id)
550+
551+
def _start_profile(self) -> None:
552+
if not self._is_segment():
553+
return
554+
555+
try_autostart_continuous_profiler()
556+
557+
self._continuous_profile = try_profile_lifecycle_trace_start()
558+
559+
# Typically, the profiler is set when the segment is created. But when
560+
# using the auto lifecycle, the profiler isn't running when the first
561+
# segment is started. So make sure we update the profiler id on it.
562+
if self._continuous_profile is not None:
563+
self._set_profile_id(get_profiler_id())
564+
531565

532566
class NoOpStreamedSpan(StreamedSpan):
533567
__slots__ = (

0 commit comments

Comments
 (0)