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