1010 RequestExtractor ,
1111 _filter_headers ,
1212 _is_json_content_type ,
13+ request_body_within_bounds ,
1314)
1415from sentry_sdk .integrations .logging import ignore_logger
1516from sentry_sdk .scope import should_send_default_pii
16- from sentry_sdk .traces import SegmentSource , StreamedSpan
17+ from sentry_sdk .traces import NoOpStreamedSpan , SegmentSource , StreamedSpan
1718from sentry_sdk .tracing import TransactionSource
1819from sentry_sdk .tracing_utils import has_span_streaming_enabled
1920from sentry_sdk .utils import (
2021 CONTEXTVARS_ERROR_MESSAGE ,
2122 HAS_REAL_CONTEXTVARS ,
23+ AnnotatedValue ,
2224 capture_internal_exceptions ,
2325 ensure_integration_enabled ,
2426 event_from_exception ,
@@ -155,14 +157,16 @@ def _handle_request_impl(self: "RequestHandler") -> "Generator[None, None, None]
155157 )
156158
157159 with span_ctx as span :
158- if isinstance (span , StreamedSpan ):
160+ if isinstance (span , StreamedSpan ) and not isinstance (
161+ span , NoOpStreamedSpan
162+ ):
159163 with capture_internal_exceptions ():
160164 for attr , value in _get_request_attributes (self .request ).items ():
161165 span .set_attribute (attr , value )
162166
163167 method = getattr (self , self .request .method .lower (), None )
164168 if method is not None :
165- span_name = transaction_from_function (method ) or ""
169+ span_name = transaction_from_function (method )
166170 if span_name :
167171 span .name = span_name
168172 span .set_attribute (
@@ -173,7 +177,9 @@ def _handle_request_impl(self: "RequestHandler") -> "Generator[None, None, None]
173177 try :
174178 yield
175179 finally :
176- if isinstance (span , StreamedSpan ):
180+ if isinstance (span , StreamedSpan ) and not isinstance (
181+ span , NoOpStreamedSpan
182+ ):
177183 with capture_internal_exceptions ():
178184 status_int = self .get_status ()
179185 span .set_attribute (SPANDATA .HTTP_STATUS_CODE , status_int )
@@ -188,7 +194,7 @@ def _get_request_attributes(request: "Any") -> "Dict[str, Any]":
188194
189195 headers = _filter_headers (dict (request .headers ), use_annotated_value = False )
190196 for header , value in headers .items ():
191- attributes [f"http.request.header .{ header .lower ()} " ] = value
197+ attributes [f"{ SPANDATA . HTTP_REQUEST_HEADER } .{ header .lower ()} " ] = value
192198
193199 if request .query :
194200 attributes [SPANDATA .HTTP_QUERY ] = request .query
@@ -200,15 +206,34 @@ def _get_request_attributes(request: "Any") -> "Dict[str, Any]":
200206 )
201207
202208 if request .protocol :
203- attributes ["network.protocol.name" ] = request .protocol
209+ attributes [SPANDATA . NETWORK_PROTOCOL_NAME ] = request .protocol
204210
205211 if should_send_default_pii () and request .remote_ip :
206- attributes ["client.address" ] = request .remote_ip
207- attributes ["user.ip_address" ] = request .remote_ip
212+ attributes [SPANDATA .CLIENT_ADDRESS ] = request .remote_ip
213+ attributes [SPANDATA .USER_IP_ADDRESS ] = request .remote_ip
214+
215+ with capture_internal_exceptions ():
216+ raw_data = _get_tornado_request_data (request )
217+ body_data = raw_data .value if isinstance (raw_data , AnnotatedValue ) else raw_data
218+ if body_data is not None :
219+ attributes [SPANDATA .HTTP_REQUEST_BODY_DATA ] = body_data
208220
209221 return attributes
210222
211223
224+ def _get_tornado_request_data (
225+ request : "Any" ,
226+ ) -> "Union[Optional[str], AnnotatedValue]" :
227+ body = request .body
228+ if not body :
229+ return None
230+
231+ if not request_body_within_bounds (sentry_sdk .get_client (), len (body )):
232+ return AnnotatedValue .substituted_because_over_size_limit ()
233+
234+ return body .decode ("utf-8" , "replace" )
235+
236+
212237@ensure_integration_enabled (TornadoIntegration )
213238def _capture_exception (ty : type , value : BaseException , tb : "Any" ) -> None :
214239 if isinstance (value , HTTPError ):
0 commit comments