use std::{ future::Future, pin::Pin, task::{Context, Poll}, }; use futures::FutureExt; use tracing::{debug, debug_span, info, span, warn, Instrument, Level}; use tracing_subscriber::{layer::SubscriberExt, registry::Registry}; use tracing_tree::HierarchicalLayer; fn main() { let layer = HierarchicalLayer::default() .with_writer(std::io::stdout) .with_indent_lines(true) .with_indent_amount(4) .with_thread_names(true) .with_thread_ids(true) .with_verbose_exit(true) .with_verbose_entry(true) .with_span_retrace(true) .with_deferred_spans(true) .with_targets(true); let subscriber = Registry::default().with(layer); tracing::subscriber::set_global_default(subscriber).unwrap(); #[cfg(feature = "tracing-log")] tracing_log::LogTracer::init().unwrap(); let app_span = span!(Level::TRACE, "hierarchical-example", version = %0.1); let _e = app_span.enter(); let server_span = span!(Level::TRACE, "server", host = "localhost", port = 8080); let _e2 = server_span.enter(); info!("starting"); std::thread::sleep(std::time::Duration::from_millis(1000)); info!("listening"); let peer1 = span!(Level::TRACE, "conn", peer_addr = "82.9.9.9", port = 42381); span!(Level::INFO, "empty-span").in_scope(|| { // empty span }); debug!("starting countdowns"); debug_span!("countdowns").in_scope(|| { let mut countdown_a = CountdownFuture { label: "a", count: 3, } .instrument(span!(Level::DEBUG, "countdown_a")) .fuse(); let mut countdown_b = CountdownFuture { label: "b", count: 5, } .instrument(span!(Level::DEBUG, "countdown_b")) .fuse(); // We don't care if the futures are ready, as we poll manually let waker = futures::task::noop_waker(); let mut cx = Context::from_waker(&waker); let _ = countdown_a.poll_unpin(&mut cx); let _ = countdown_b.poll_unpin(&mut cx); std::thread::sleep(std::time::Duration::from_millis(300)); let _ = countdown_b.poll_unpin(&mut cx); let _ = countdown_a.poll_unpin(&mut cx); peer1.in_scope(|| { warn!("peer1 warning"); }); tracing::info!("finished polling countdowns"); }); drop(peer1); tracing::info!("all done!"); info!("exit") } struct CountdownFuture { label: &'static str, count: u32, } impl Future for CountdownFuture { type Output = (); fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { debug!(label=?self.label, count=?self.count, "polling countdown"); self.count -= 1; if self.count == 0 { Poll::Ready(()) } else { cx.waker().wake_by_ref(); Poll::Pending } } }