pipette/
trace.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! [`tracing`] support.
5
6use std::sync::Arc;
7use tracing_subscriber::filter::Targets;
8use tracing_subscriber::fmt::format::FmtSpan;
9use tracing_subscriber::layer::SubscriberExt;
10use tracing_subscriber::util::SubscriberInitExt;
11
12/// Initialize tracing, returning a mesh pipe to read logs from.
13pub fn init_tracing() -> mesh::pipe::ReadPipe {
14    let (log_read, log_write) = mesh::pipe::pipe();
15    let targets = Targets::new()
16        .with_default(tracing::level_filters::LevelFilter::DEBUG)
17        .with_target("mesh_remote", tracing::level_filters::LevelFilter::INFO);
18
19    tracing_subscriber::fmt()
20        .compact()
21        .with_ansi(false)
22        .with_timer(tracing_subscriber::fmt::time::uptime())
23        .with_writer(Arc::new(TracingWriter(log_write)))
24        .with_max_level(tracing::level_filters::LevelFilter::DEBUG)
25        .with_span_events(FmtSpan::NEW | FmtSpan::CLOSE)
26        .log_internal_errors(true)
27        .finish()
28        .with(targets)
29        .init();
30
31    tracing::info!("tracing initialized");
32    log_read
33}
34
35struct TracingWriter(mesh::pipe::WritePipe);
36
37impl std::io::Write for &TracingWriter {
38    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
39        // Note that this will fail if the pipe fills up. This is probably fine
40        // for this use case.
41        self.0.write_nonblocking(buf)
42    }
43
44    fn flush(&mut self) -> std::io::Result<()> {
45        Ok(())
46    }
47}