@@ -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,7 @@ 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( err, skip_all, ) ) ]
733739async fn http_request_handle_wrap < C : ServerContext > (
734740 server : Arc < DropshotState < C > > ,
735741 remote_addr : SocketAddr ,
@@ -774,6 +780,18 @@ async fn http_request_handle_wrap<C: ServerContext>(
774780 }
775781 }
776782
783+ #[ cfg( feature = "otel-tracing" ) ]
784+ let mut span = otel:: create_request_span ( & request) ;
785+ #[ cfg( feature = "otel-tracing" ) ]
786+ span. trace_request ( crate :: otel:: RequestInfo {
787+ id : request_id. clone ( ) ,
788+ local_addr : server. local_addr ,
789+ remote_addr,
790+ method : request. method ( ) . to_string ( ) ,
791+ path : request. uri ( ) . path ( ) . to_string ( ) ,
792+ query : request. uri ( ) . query ( ) . map ( |x| x. to_string ( ) ) ,
793+ } ) ;
794+
777795 trace ! ( request_log, "incoming request" ) ;
778796 #[ cfg( feature = "usdt-probes" ) ]
779797 probes:: request__start!( || {
@@ -790,9 +808,12 @@ async fn http_request_handle_wrap<C: ServerContext>(
790808
791809 // Copy local address to report later during the finish probe, as the
792810 // server is passed by value to the request handler function.
793- #[ cfg( feature = "usdt-probes" ) ]
811+ #[ cfg( any ( feature = "usdt-probes" , feature = "otel-tracing" ) ) ]
794812 let local_addr = server. local_addr ;
795813
814+ #[ cfg( feature = "otel-tracing" ) ]
815+ let span_context = span. span_context ( ) . clone ( ) ;
816+
796817 // In the case the client disconnects early, the scopeguard allows us
797818 // to perform extra housekeeping before this task is dropped.
798819 let on_disconnect = guard ( ( ) , |_| {
@@ -802,6 +823,18 @@ async fn http_request_handle_wrap<C: ServerContext>(
802823 "latency_us" => latency_us,
803824 ) ;
804825
826+ #[ cfg( feature = "otel-tracing" ) ]
827+ span. trace_response ( crate :: otel:: ResponseInfo {
828+ id : request_id. clone ( ) ,
829+ local_addr,
830+ remote_addr,
831+ // 499 is a non-standard code popularized by nginx to mean "client disconnected".
832+ status_code : 499 ,
833+ message : String :: from (
834+ "client disconnected before response returned" ,
835+ ) ,
836+ } ) ;
837+
805838 #[ cfg( feature = "usdt-probes" ) ]
806839 probes:: request__done!( || {
807840 crate :: dtrace:: ResponseInfo {
@@ -823,6 +856,8 @@ async fn http_request_handle_wrap<C: ServerContext>(
823856 & request_id,
824857 request_log. new ( o ! ( ) ) ,
825858 remote_addr,
859+ #[ cfg( feature = "otel-tracing" ) ]
860+ span_context,
826861 )
827862 . await ;
828863
@@ -838,6 +873,17 @@ async fn http_request_handle_wrap<C: ServerContext>(
838873 let message_external = error. external_message ( ) ;
839874 let message_internal = error. internal_message ( ) ;
840875
876+ #[ cfg( feature = "otel-tracing" ) ]
877+ span. trace_response ( crate :: otel:: ResponseInfo {
878+ id : request_id. clone ( ) ,
879+ local_addr,
880+ remote_addr,
881+ status_code : status. as_u16 ( ) ,
882+ message : message_external
883+ . cloned ( )
884+ . unwrap_or_else ( || message_internal. clone ( ) ) ,
885+ } ) ;
886+
841887 #[ cfg( feature = "usdt-probes" ) ]
842888 probes:: request__done!( || {
843889 crate :: dtrace:: ResponseInfo {
@@ -869,6 +915,15 @@ async fn http_request_handle_wrap<C: ServerContext>(
869915 "latency_us" => latency_us,
870916 ) ;
871917
918+ #[ cfg( feature = "otel-tracing" ) ]
919+ span. trace_response ( crate :: otel:: ResponseInfo {
920+ id : request_id. parse ( ) . unwrap ( ) ,
921+ local_addr,
922+ remote_addr,
923+ status_code : response. status ( ) . as_u16 ( ) ,
924+ message : "" . to_string ( ) ,
925+ } ) ;
926+
872927 #[ cfg( feature = "usdt-probes" ) ]
873928 probes:: request__done!( || {
874929 crate :: dtrace:: ResponseInfo {
@@ -887,12 +942,26 @@ async fn http_request_handle_wrap<C: ServerContext>(
887942 Ok ( response)
888943}
889944
945+ #[ cfg_attr( feature = "tokio-tracing" , tracing:: instrument(
946+ err,
947+ skip_all,
948+ fields(
949+ http. method = request. method( ) . as_str( ) . to_string( ) ,
950+ http. uri = request. uri( ) . to_string( ) ,
951+ http. version = format!( "{:#?}" , request. version( ) ) ,
952+ http. headers. accept = format!( "{:#?}" , request. headers( ) [ "accept" ] ) ,
953+ http. headers. host = format!( "{:#?}" , request. headers( ) [ "host" ] ) ,
954+ //http.headers.user_agent = format!("{:#?}", request.headers()["user-agent"]),
955+ ) ,
956+ ) ) ]
890957async fn http_request_handle < C : ServerContext > (
891958 server : Arc < DropshotState < C > > ,
892959 request : Request < hyper:: body:: Incoming > ,
893960 request_id : & str ,
894961 request_log : Logger ,
895962 remote_addr : std:: net:: SocketAddr ,
963+ #[ cfg( feature = "otel-tracing" ) ]
964+ span_context : opentelemetry:: trace:: SpanContext ,
896965) -> Result < Response < Body > , HandlerError > {
897966 // TODO-hardening: is it correct to (and do we correctly) read the entire
898967 // request body even if we decide it's too large and are going to send a 400
@@ -916,6 +985,8 @@ async fn http_request_handle<C: ServerContext>(
916985 endpoint : lookup_result. endpoint ,
917986 request_id : request_id. to_string ( ) ,
918987 log : request_log,
988+ #[ cfg( feature = "otel-tracing" ) ]
989+ span_context : span_context,
919990 } ;
920991 let handler = lookup_result. handler ;
921992
0 commit comments