1 use std::{
2     future::Future,
3     io,
4     sync::{Arc, Mutex},
5 };
6 
7 use serde::{de::DeserializeOwned, Deserialize};
8 use tracing_subscriber::prelude::*;
9 use tracing_subscriber::{filter::Targets, fmt::MakeWriter};
10 
11 #[derive(Deserialize, Eq, PartialEq, Debug)]
12 #[serde(deny_unknown_fields)]
13 pub(crate) struct TracingEvent<T> {
14     pub(crate) fields: T,
15     pub(crate) target: String,
16     pub(crate) level: String,
17 }
18 
19 /// Run an async closure and capture the tracing output it produces.
capture_tracing<T, F, Fut>(f: F) -> Vec<TracingEvent<T>> where F: Fn() -> Fut, Fut: Future, T: DeserializeOwned,20 pub(crate) async fn capture_tracing<T, F, Fut>(f: F) -> Vec<TracingEvent<T>>
21 where
22     F: Fn() -> Fut,
23     Fut: Future,
24     T: DeserializeOwned,
25 {
26     let (make_writer, handle) = TestMakeWriter::new();
27 
28     let subscriber = tracing_subscriber::registry().with(
29         tracing_subscriber::fmt::layer()
30             .with_writer(make_writer)
31             .with_target(true)
32             .without_time()
33             .with_ansi(false)
34             .json()
35             .flatten_event(false)
36             .with_filter("axum=trace".parse::<Targets>().unwrap()),
37     );
38 
39     let guard = tracing::subscriber::set_default(subscriber);
40 
41     f().await;
42 
43     drop(guard);
44 
45     handle
46         .take()
47         .lines()
48         .map(|line| serde_json::from_str(line).unwrap())
49         .collect()
50 }
51 
52 struct TestMakeWriter {
53     write: Arc<Mutex<Option<Vec<u8>>>>,
54 }
55 
56 impl TestMakeWriter {
new() -> (Self, Handle)57     fn new() -> (Self, Handle) {
58         let write = Arc::new(Mutex::new(Some(Vec::<u8>::new())));
59 
60         (
61             Self {
62                 write: write.clone(),
63             },
64             Handle { write },
65         )
66     }
67 }
68 
69 impl<'a> MakeWriter<'a> for TestMakeWriter {
70     type Writer = Writer<'a>;
71 
make_writer(&'a self) -> Self::Writer72     fn make_writer(&'a self) -> Self::Writer {
73         Writer(self)
74     }
75 }
76 
77 struct Writer<'a>(&'a TestMakeWriter);
78 
79 impl<'a> io::Write for Writer<'a> {
write(&mut self, buf: &[u8]) -> io::Result<usize>80     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
81         match &mut *self.0.write.lock().unwrap() {
82             Some(vec) => {
83                 let len = buf.len();
84                 vec.extend(buf);
85                 Ok(len)
86             }
87             None => Err(io::Error::new(
88                 io::ErrorKind::Other,
89                 "inner writer has been taken",
90             )),
91         }
92     }
93 
flush(&mut self) -> io::Result<()>94     fn flush(&mut self) -> io::Result<()> {
95         Ok(())
96     }
97 }
98 
99 struct Handle {
100     write: Arc<Mutex<Option<Vec<u8>>>>,
101 }
102 
103 impl Handle {
take(self) -> String104     fn take(self) -> String {
105         let vec = self.write.lock().unwrap().take().unwrap();
106         String::from_utf8(vec).unwrap()
107     }
108 }
109