@@ -487,7 +487,7 @@ def get_default_span_details(scope: dict) -> Tuple[str, dict]:
487
487
488
488
489
489
def _collect_target_attribute (
490
- scope : typing .Dict [str , typing .Any ]
490
+ scope : typing .Dict [str , typing .Any ],
491
491
) -> typing .Optional [str ]:
492
492
"""
493
493
Returns the target path as defined by the Semantic Conventions.
@@ -814,6 +814,7 @@ async def __call__(
814
814
def _get_otel_receive (self , server_span_name , scope , receive ):
815
815
if self .exclude_receive_span :
816
816
return receive
817
+
817
818
@wraps (receive )
818
819
async def otel_receive ():
819
820
with self .tracer .start_as_current_span (
@@ -858,7 +859,6 @@ async def otel_send(message: dict[str, Any]):
858
859
elif message ["type" ] == "websocket.send" :
859
860
status_code = 200
860
861
861
- # Conditional send_span creation
862
862
if not self .exclude_send_span :
863
863
with self .tracer .start_as_current_span (
864
864
" " .join ((server_span_name , scope ["type" ], "send" ))
@@ -867,7 +867,11 @@ async def otel_send(message: dict[str, Any]):
867
867
self .client_response_hook (send_span , scope , message )
868
868
869
869
if send_span .is_recording ():
870
- send_span .set_attribute ("asgi.event.type" , message ["type" ])
870
+ if message ["type" ] == "http.response.start" :
871
+ expecting_trailers = message .get ("trailers" , False )
872
+ send_span .set_attribute (
873
+ "asgi.event.type" , message ["type" ]
874
+ )
871
875
if status_code :
872
876
set_status_code (
873
877
send_span ,
@@ -876,40 +880,43 @@ async def otel_send(message: dict[str, Any]):
876
880
self ._sem_conv_opt_in_mode ,
877
881
)
878
882
879
- # Server span logic always applied
880
- if server_span .is_recording () and "headers" in message :
881
- if server_span .kind == trace .SpanKind .SERVER :
882
- custom_response_attributes = (
883
- collect_custom_headers_attributes (
884
- message ,
885
- self .http_capture_headers_sanitize_fields ,
886
- self .http_capture_headers_server_response ,
887
- normalise_response_header_name ,
888
- )
889
- if self .http_capture_headers_server_response
890
- else {}
891
- )
892
- if len (custom_response_attributes ) > 0 :
893
- server_span .set_attributes (custom_response_attributes )
894
-
895
- if status_code :
896
- # We record metrics only once
897
- set_status_code (
898
- server_span ,
899
- status_code ,
900
- duration_attrs ,
901
- self ._sem_conv_opt_in_mode ,
902
- )
883
+ if (
884
+ server_span .is_recording ()
885
+ and server_span .kind == trace .SpanKind .SERVER
886
+ and "headers" in message
887
+ ):
888
+ custom_response_attributes = (
889
+ collect_custom_headers_attributes (
890
+ message ,
891
+ self .http_capture_headers_sanitize_fields ,
892
+ self .http_capture_headers_server_response ,
893
+ normalise_response_header_name ,
894
+ )
895
+ if self .http_capture_headers_server_response
896
+ else {}
897
+ )
898
+ if len (custom_response_attributes ) > 0 :
899
+ server_span .set_attributes (
900
+ custom_response_attributes
901
+ )
902
+
903
+ if status_code :
904
+ set_status_code (
905
+ server_span ,
906
+ status_code ,
907
+ duration_attrs ,
908
+ self ._sem_conv_opt_in_mode ,
909
+ )
903
910
904
- propagator = get_global_response_propagator ()
905
- if propagator :
906
- propagator .inject (
907
- message ,
908
- context = set_span_in_context (
909
- server_span , trace .context_api .Context ()
910
- ),
911
- setter = asgi_setter ,
912
- )
911
+ propagator = get_global_response_propagator ()
912
+ if propagator :
913
+ propagator .inject (
914
+ message ,
915
+ context = set_span_in_context (
916
+ server_span , trace .context_api .Context ()
917
+ ),
918
+ setter = asgi_setter ,
919
+ )
913
920
914
921
content_length = asgi_getter .get (message , "content-length" )
915
922
if content_length :
0 commit comments