1111import sentry_sdk
1212from sentry_sdk ._compat import PY37 , check_uwsgi_thread_support
1313from sentry_sdk ._metrics_batcher import MetricsBatcher
14+ from sentry_sdk ._span_batcher import SpanBatcher
1415from sentry_sdk .utils import (
1516 AnnotatedValue ,
1617 ContextVar ,
3132)
3233from sentry_sdk .serializer import serialize
3334from sentry_sdk .tracing import trace
35+ from sentry_sdk .tracing_utils import has_span_streaming_enabled
3436from sentry_sdk .transport import BaseHttpTransport , make_transport
3537from sentry_sdk .consts import (
3638 SPANDATA ,
6769 from sentry_sdk .scope import Scope
6870 from sentry_sdk .session import Session
6971 from sentry_sdk .spotlight import SpotlightClient
72+ from sentry_sdk .traces import StreamedSpan
7073 from sentry_sdk .transport import Transport , Item
7174 from sentry_sdk ._log_batcher import LogBatcher
7275 from sentry_sdk ._metrics_batcher import MetricsBatcher
@@ -188,6 +191,7 @@ def __init__(self, options: "Optional[Dict[str, Any]]" = None) -> None:
188191 self .monitor : "Optional[Monitor]" = None
189192 self .log_batcher : "Optional[LogBatcher]" = None
190193 self .metrics_batcher : "Optional[MetricsBatcher]" = None
194+ self .span_batcher : "Optional[SpanBatcher]" = None
191195 self .integrations : "dict[str, Integration]" = {}
192196
193197 def __getstate__ (self , * args : "Any" , ** kwargs : "Any" ) -> "Any" :
@@ -224,6 +228,9 @@ def _capture_log(self, log: "Log", scope: "Scope") -> None:
224228 def _capture_metric (self , metric : "Metric" , scope : "Scope" ) -> None :
225229 pass
226230
231+ def _capture_span (self , span : "StreamedSpan" , scope : "Scope" ) -> None :
232+ pass
233+
227234 def capture_session (self , * args : "Any" , ** kwargs : "Any" ) -> None :
228235 return None
229236
@@ -399,6 +406,13 @@ def _record_lost_event(
399406 record_lost_func = _record_lost_event ,
400407 )
401408
409+ self .span_batcher = None
410+ if has_span_streaming_enabled (self .options ):
411+ self .span_batcher = SpanBatcher (
412+ capture_func = _capture_envelope ,
413+ record_lost_func = _record_lost_event ,
414+ )
415+
402416 max_request_body_size = ("always" , "never" , "small" , "medium" )
403417 if self .options ["max_request_body_size" ] not in max_request_body_size :
404418 raise ValueError (
@@ -909,7 +923,10 @@ def capture_event(
909923 return return_value
910924
911925 def _capture_telemetry (
912- self , telemetry : "Optional[Union[Log, Metric]]" , ty : str , scope : "Scope"
926+ self ,
927+ telemetry : "Optional[Union[Log, Metric, StreamedSpan]]" ,
928+ ty : str ,
929+ scope : "Scope" ,
913930 ) -> None :
914931 # Capture attributes-based telemetry (logs, metrics, spansV2)
915932 if telemetry is None :
@@ -934,6 +951,8 @@ def _capture_telemetry(
934951 batcher = self .log_batcher
935952 elif ty == "metric" :
936953 batcher = self .metrics_batcher # type: ignore
954+ elif ty == "span" :
955+ batcher = self .span_batcher # type: ignore
937956
938957 if batcher is not None :
939958 batcher .add (telemetry ) # type: ignore
@@ -944,6 +963,9 @@ def _capture_log(self, log: "Optional[Log]", scope: "Scope") -> None:
944963 def _capture_metric (self , metric : "Optional[Metric]" , scope : "Scope" ) -> None :
945964 self ._capture_telemetry (metric , "metric" , scope )
946965
966+ def _capture_span (self , span : "Optional[StreamedSpan]" , scope : "Scope" ) -> None :
967+ self ._capture_telemetry (span , "span" , scope )
968+
947969 def capture_session (
948970 self ,
949971 session : "Session" ,
@@ -993,6 +1015,8 @@ def close(
9931015 self .log_batcher .kill ()
9941016 if self .metrics_batcher is not None :
9951017 self .metrics_batcher .kill ()
1018+ if self .span_batcher is not None :
1019+ self .span_batcher .kill ()
9961020 if self .monitor :
9971021 self .monitor .kill ()
9981022 self .transport .kill ()
@@ -1018,6 +1042,8 @@ def flush(
10181042 self .log_batcher .flush ()
10191043 if self .metrics_batcher is not None :
10201044 self .metrics_batcher .flush ()
1045+ if self .span_batcher is not None :
1046+ self .span_batcher .flush ()
10211047 self .transport .flush (timeout = timeout , callback = callback )
10221048
10231049 def __enter__ (self ) -> "_Client" :
0 commit comments