@@ -13,6 +13,11 @@ use super::router::HttpRouter;
1313use super :: versioning:: VersionPolicy ;
1414use super :: ProbeRegistration ;
1515
16+ #[ cfg( feature = "otel-tracing" ) ]
17+ use crate :: { otel, otel:: TraceDropshot } ;
18+ #[ cfg( feature = "otel-tracing" ) ]
19+ use opentelemetry:: trace:: Span ;
20+
1621use async_stream:: stream;
1722use debug_ignore:: DebugIgnore ;
1823use futures:: future:: {
@@ -730,6 +735,10 @@ impl<C: ServerContext> FusedFuture for HttpServer<C> {
730735/// invoked by Hyper when a new request is received. This function returns a
731736/// Result that either represents a valid HTTP response or an error (which will
732737/// also get turned into an HTTP response).
738+ #[ cfg_attr( feature = "tokio-tracing" , tracing:: instrument(
739+ err,
740+ skip_all,
741+ ) ) ]
733742async fn http_request_handle_wrap < C : ServerContext > (
734743 server : Arc < DropshotState < C > > ,
735744 remote_addr : SocketAddr ,
@@ -774,6 +783,18 @@ async fn http_request_handle_wrap<C: ServerContext>(
774783 }
775784 }
776785
786+ #[ cfg( feature = "otel-tracing" ) ]
787+ let mut span = otel:: create_request_span ( & request) ;
788+ #[ cfg( feature = "otel-tracing" ) ]
789+ span. trace_request ( crate :: otel:: RequestInfo {
790+ id : request_id. clone ( ) ,
791+ local_addr : server. local_addr ,
792+ remote_addr,
793+ method : request. method ( ) . to_string ( ) ,
794+ path : request. uri ( ) . path ( ) . to_string ( ) ,
795+ query : request. uri ( ) . query ( ) . map ( |x| x. to_string ( ) ) ,
796+ } ) ;
797+
777798 trace ! ( request_log, "incoming request" ) ;
778799 #[ cfg( feature = "usdt-probes" ) ]
779800 probes:: request__start!( || {
@@ -790,9 +811,12 @@ async fn http_request_handle_wrap<C: ServerContext>(
790811
791812 // Copy local address to report later during the finish probe, as the
792813 // server is passed by value to the request handler function.
793- #[ cfg( feature = "usdt-probes" ) ]
814+ #[ cfg( any ( feature = "usdt-probes" , feature = "otel-tracing" ) ) ]
794815 let local_addr = server. local_addr ;
795816
817+ #[ cfg( feature = "otel-tracing" ) ]
818+ let span_context = span. span_context ( ) . clone ( ) ;
819+
796820 // In the case the client disconnects early, the scopeguard allows us
797821 // to perform extra housekeeping before this task is dropped.
798822 let on_disconnect = guard ( ( ) , |_| {
@@ -802,6 +826,18 @@ async fn http_request_handle_wrap<C: ServerContext>(
802826 "latency_us" => latency_us,
803827 ) ;
804828
829+ #[ cfg( feature = "otel-tracing" ) ]
830+ span. trace_response ( crate :: otel:: ResponseInfo {
831+ id : request_id. clone ( ) ,
832+ local_addr,
833+ remote_addr,
834+ // 499 is a non-standard code popularized by nginx to mean "client disconnected".
835+ status_code : 499 ,
836+ message : String :: from (
837+ "client disconnected before response returned" ,
838+ ) ,
839+ } ) ;
840+
805841 #[ cfg( feature = "usdt-probes" ) ]
806842 probes:: request__done!( || {
807843 crate :: dtrace:: ResponseInfo {
@@ -823,6 +859,8 @@ async fn http_request_handle_wrap<C: ServerContext>(
823859 & request_id,
824860 request_log. new ( o ! ( ) ) ,
825861 remote_addr,
862+ #[ cfg( feature = "otel-tracing" ) ]
863+ span_context,
826864 )
827865 . await ;
828866
@@ -838,6 +876,17 @@ async fn http_request_handle_wrap<C: ServerContext>(
838876 let message_external = error. external_message ( ) ;
839877 let message_internal = error. internal_message ( ) ;
840878
879+ #[ cfg( feature = "otel-tracing" ) ]
880+ span. trace_response ( crate :: otel:: ResponseInfo {
881+ id : request_id. clone ( ) ,
882+ local_addr,
883+ remote_addr,
884+ status_code : status. as_u16 ( ) ,
885+ message : message_external
886+ . cloned ( )
887+ . unwrap_or_else ( || message_internal. clone ( ) ) ,
888+ } ) ;
889+
841890 #[ cfg( feature = "usdt-probes" ) ]
842891 probes:: request__done!( || {
843892 crate :: dtrace:: ResponseInfo {
@@ -869,6 +918,15 @@ async fn http_request_handle_wrap<C: ServerContext>(
869918 "latency_us" => latency_us,
870919 ) ;
871920
921+ #[ cfg( feature = "otel-tracing" ) ]
922+ span. trace_response ( crate :: otel:: ResponseInfo {
923+ id : request_id. parse ( ) . unwrap ( ) ,
924+ local_addr,
925+ remote_addr,
926+ status_code : response. status ( ) . as_u16 ( ) ,
927+ message : "" . to_string ( ) ,
928+ } ) ;
929+
872930 #[ cfg( feature = "usdt-probes" ) ]
873931 probes:: request__done!( || {
874932 crate :: dtrace:: ResponseInfo {
@@ -887,12 +945,26 @@ async fn http_request_handle_wrap<C: ServerContext>(
887945 Ok ( response)
888946}
889947
948+ #[ cfg_attr( feature = "tokio-tracing" , tracing:: instrument(
949+ err,
950+ skip_all,
951+ fields(
952+ http. method = request. method( ) . as_str( ) . to_string( ) ,
953+ http. uri = request. uri( ) . to_string( ) ,
954+ http. version = format!( "{:#?}" , request. version( ) ) ,
955+ http. headers. accept = format!( "{:#?}" , request. headers( ) [ "accept" ] ) ,
956+ http. headers. host = format!( "{:#?}" , request. headers( ) [ "host" ] ) ,
957+ //http.headers.user_agent = format!("{:#?}", request.headers()["user-agent"]),
958+ ) ,
959+ ) ) ]
890960async fn http_request_handle < C : ServerContext > (
891961 server : Arc < DropshotState < C > > ,
892962 request : Request < hyper:: body:: Incoming > ,
893963 request_id : & str ,
894964 request_log : Logger ,
895965 remote_addr : std:: net:: SocketAddr ,
966+ #[ cfg( feature = "otel-tracing" ) ]
967+ span_context : opentelemetry:: trace:: SpanContext ,
896968) -> Result < Response < Body > , HandlerError > {
897969 // TODO-hardening: is it correct to (and do we correctly) read the entire
898970 // request body even if we decide it's too large and are going to send a 400
@@ -916,6 +988,8 @@ async fn http_request_handle<C: ServerContext>(
916988 endpoint : lookup_result. endpoint ,
917989 request_id : request_id. to_string ( ) ,
918990 log : request_log,
991+ #[ cfg( feature = "otel-tracing" ) ]
992+ span_context : span_context,
919993 } ;
920994 let handler = lookup_result. handler ;
921995
0 commit comments