use bytes::{buf::Writer, BytesMut};
use std::{
io,
sync::{Arc, Mutex, MutexGuard},
};
use tracing_subscriber::fmt::{format::DefaultFields, MakeWriter};
pub(crate) struct Logger<W>(pub Arc<Mutex<W>>);
impl<W> Clone for Logger<W> {
fn clone(&self) -> Self { Self(Arc::clone(&self.0)) }
}
#[derive(Debug)]
pub(crate) struct MutexGuardWriter2<'a, W>(MutexGuard<'a, W>);
impl<'a, W> MakeWriter<'a> for Logger<W>
where
W: io::Write + 'a,
{
type Writer = MutexGuardWriter2<'a, W>;
fn make_writer(&'a self) -> Self::Writer { MutexGuardWriter2(self.0.lock().expect("lock poisoned")) }
}
impl<'a, W> io::Write for MutexGuardWriter2<'a, W>
where
W: io::Write,
{
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
#[inline]
fn flush(&mut self) -> io::Result<()> { self.0.flush() }
#[inline]
fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> { self.0.write_vectored(bufs) }
#[inline]
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { self.0.write_all(buf) }
#[inline]
fn write_fmt(&mut self, fmt: std::fmt::Arguments<'_>) -> io::Result<()> { self.0.write_fmt(fmt) }
}
#[allow(clippy::type_complexity)]
pub(crate) fn default_subscriber(
log_level: tracing::Level,
) -> (
tracing_subscriber::FmtSubscriber<
DefaultFields,
tracing_subscriber::fmt::format::Format,
tracing::level_filters::LevelFilter,
Logger<Writer<BytesMut>>,
>,
Logger<bytes::buf::Writer<BytesMut>>,
) {
use bytes::BufMut;
let data = BytesMut::with_capacity(1000);
let make_writer = Logger(Arc::new(Mutex::new(data.writer())));
#[cfg(feature = "capture_tracing")]
let filter = tracing_subscriber::filter::EnvFilter::default()
.add_directive(tracing_subscriber::filter::LevelFilter::INFO.into())
.add_directive(log_level.into());
let subscriber = tracing_subscriber::fmt::SubscriberBuilder::default()
.with_env_filter(filter)
.with_max_level(log_level)
.with_writer(make_writer.clone())
.finish();
(subscriber, make_writer)
}