Skip to content

Commit 6d5f1cd

Browse files
committed
Allow setup to run on tracing-appender non-blocking thread
1 parent c297a37 commit 6d5f1cd

3 files changed

Lines changed: 87 additions & 0 deletions

File tree

tracing-appender/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,14 @@ pub fn non_blocking<T: Write + Send + 'static>(writer: T) -> (NonBlocking, Worke
195195
NonBlocking::new(writer)
196196
}
197197

198+
/// Convenience function for creating a non-blocking, off-thread writer with setup.
199+
pub fn non_blocking_with_setup<T: Write + Send + 'static>(
200+
writer: T,
201+
setup: impl FnOnce() + Send + 'static,
202+
) -> (NonBlocking, WorkerGuard) {
203+
NonBlocking::new_with_setup(writer, setup)
204+
}
205+
198206
#[derive(Debug)]
199207
pub(crate) enum Msg {
200208
Line(Vec<u8>),

tracing-appender/src/non_blocking.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,14 @@ impl NonBlocking {
146146
NonBlockingBuilder::default().finish(writer)
147147
}
148148

149+
/// Returns a new `NonBlocking` writer wrapping the provided `writer` with the provided `setup` function.
150+
pub fn new_with_setup<T: Write + Send + 'static>(
151+
writer: T,
152+
setup: impl FnOnce() + Send + 'static,
153+
) -> (NonBlocking, WorkerGuard) {
154+
NonBlockingBuilder::default().finish_with_setup(writer, setup)
155+
}
156+
149157
fn create<T: Write + Send + 'static>(
150158
writer: T,
151159
buffered_lines_limit: usize,
@@ -173,6 +181,34 @@ impl NonBlocking {
173181
)
174182
}
175183

184+
fn create_with_setup<T: Write + Send + 'static>(
185+
writer: T,
186+
setup: impl FnOnce() + Send + 'static,
187+
buffered_lines_limit: usize,
188+
is_lossy: bool,
189+
thread_name: String,
190+
) -> (NonBlocking, WorkerGuard) {
191+
let (sender, receiver) = bounded(buffered_lines_limit);
192+
193+
let (shutdown_sender, shutdown_receiver) = bounded(0);
194+
195+
let worker = Worker::new(receiver, writer, shutdown_receiver);
196+
let worker_guard = WorkerGuard::new(
197+
worker.worker_thread_with_setup(thread_name, setup),
198+
sender.clone(),
199+
shutdown_sender,
200+
);
201+
202+
(
203+
Self {
204+
channel: sender,
205+
error_counter: ErrorCounter(Arc::new(AtomicUsize::new(0))),
206+
is_lossy,
207+
},
208+
worker_guard,
209+
)
210+
}
211+
176212
/// Returns a counter for the number of times logs where dropped. This will always return zero if
177213
/// `NonBlocking` is not lossy.
178214
pub fn error_counter(&self) -> ErrorCounter {
@@ -223,6 +259,20 @@ impl NonBlockingBuilder {
223259
self.thread_name,
224260
)
225261
}
262+
263+
pub fn finish_with_setup<T: Write + Send + 'static>(
264+
self,
265+
writer: T,
266+
setup: impl FnOnce() + Send + 'static,
267+
) -> (NonBlocking, WorkerGuard) {
268+
NonBlocking::create_with_setup(
269+
writer,
270+
setup,
271+
self.buffered_lines_limit,
272+
self.is_lossy,
273+
self.thread_name,
274+
)
275+
}
226276
}
227277

228278
impl Default for NonBlockingBuilder {

tracing-appender/src/worker.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,33 @@ impl<T: Write + Send + 'static> Worker<T> {
8989
})
9090
.expect("failed to spawn `tracing-appender` non-blocking worker thread")
9191
}
92+
93+
/// Creates a worker thread that processes a channel until it's disconnected
94+
pub(crate) fn worker_thread_with_setup(
95+
mut self,
96+
name: String,
97+
setup: impl FnOnce() + Send + 'static,
98+
) -> std::thread::JoinHandle<()> {
99+
thread::Builder::new()
100+
.name(name)
101+
.spawn(move || {
102+
setup();
103+
loop {
104+
match self.work() {
105+
Ok(WorkerState::Continue) | Ok(WorkerState::Empty) => {}
106+
Ok(WorkerState::Shutdown) | Ok(WorkerState::Disconnected) => {
107+
let _ = self.shutdown.recv();
108+
break;
109+
}
110+
Err(_) => {
111+
// TODO: Expose a metric for IO Errors, or print to stderr
112+
}
113+
}
114+
}
115+
if let Err(e) = self.writer.flush() {
116+
eprintln!("Failed to flush. Error: {}", e);
117+
}
118+
})
119+
.expect("failed to spawn `tracing-appender` non-blocking worker thread")
120+
}
92121
}

0 commit comments

Comments
 (0)