1 cfg_trace! { 2 cfg_rt! { 3 use core::{ 4 pin::Pin, 5 task::{Context, Poll}, 6 }; 7 use pin_project_lite::pin_project; 8 use std::future::Future; 9 pub(crate) use tracing::instrument::Instrumented; 10 11 #[inline] 12 #[track_caller] 13 pub(crate) fn task<F>(task: F, kind: &'static str, name: Option<&str>) -> Instrumented<F> { 14 use tracing::instrument::Instrument; 15 let location = std::panic::Location::caller(); 16 let span = tracing::trace_span!( 17 target: "tokio::task", 18 "runtime.spawn", 19 %kind, 20 task.name = %name.unwrap_or_default(), 21 loc.file = location.file(), 22 loc.line = location.line(), 23 loc.col = location.column(), 24 ); 25 task.instrument(span) 26 } 27 28 pub(crate) fn async_op<P,F>(inner: P, resource_span: tracing::Span, source: &str, poll_op_name: &'static str, inherits_child_attrs: bool) -> InstrumentedAsyncOp<F> 29 where P: FnOnce() -> F { 30 resource_span.in_scope(|| { 31 let async_op_span = tracing::trace_span!("runtime.resource.async_op", source = source, inherits_child_attrs = inherits_child_attrs); 32 let enter = async_op_span.enter(); 33 let async_op_poll_span = tracing::trace_span!("runtime.resource.async_op.poll"); 34 let inner = inner(); 35 drop(enter); 36 let tracing_ctx = AsyncOpTracingCtx { 37 async_op_span, 38 async_op_poll_span, 39 resource_span: resource_span.clone(), 40 }; 41 InstrumentedAsyncOp { 42 inner, 43 tracing_ctx, 44 poll_op_name, 45 } 46 }) 47 } 48 49 #[derive(Debug, Clone)] 50 pub(crate) struct AsyncOpTracingCtx { 51 pub(crate) async_op_span: tracing::Span, 52 pub(crate) async_op_poll_span: tracing::Span, 53 pub(crate) resource_span: tracing::Span, 54 } 55 56 57 pin_project! { 58 #[derive(Debug, Clone)] 59 pub(crate) struct InstrumentedAsyncOp<F> { 60 #[pin] 61 pub(crate) inner: F, 62 pub(crate) tracing_ctx: AsyncOpTracingCtx, 63 pub(crate) poll_op_name: &'static str 64 } 65 } 66 67 impl<F: Future> Future for InstrumentedAsyncOp<F> { 68 type Output = F::Output; 69 70 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { 71 let this = self.project(); 72 let poll_op_name = &*this.poll_op_name; 73 let _res_enter = this.tracing_ctx.resource_span.enter(); 74 let _async_op_enter = this.tracing_ctx.async_op_span.enter(); 75 let _async_op_poll_enter = this.tracing_ctx.async_op_poll_span.enter(); 76 trace_poll_op!(poll_op_name, this.inner.poll(cx)) 77 } 78 } 79 } 80 } 81 cfg_time! { 82 #[track_caller] 83 pub(crate) fn caller_location() -> Option<&'static std::panic::Location<'static>> { 84 #[cfg(all(tokio_unstable, feature = "tracing"))] 85 return Some(std::panic::Location::caller()); 86 #[cfg(not(all(tokio_unstable, feature = "tracing")))] 87 None 88 } 89 } 90 91 cfg_not_trace! { 92 cfg_rt! { 93 #[inline] 94 pub(crate) fn task<F>(task: F, _: &'static str, _name: Option<&str>) -> F { 95 // nop 96 task 97 } 98 } 99 } 100