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