From 3028cdb5d1099455d3f76d09a4b9b75026111f2a Mon Sep 17 00:00:00 2001 From: Giacomo Pasini <21265557+zeegomo@users.noreply.github.com> Date: Tue, 7 Nov 2023 15:24:02 +0100 Subject: [PATCH] Add option to provide custom writer to the logger backend (#518) * Add option to provide custom writer to the logger backend * fmt --- nomos-services/log/src/lib.rs | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/nomos-services/log/src/lib.rs b/nomos-services/log/src/lib.rs index 46f2115f..8ccfa7fa 100644 --- a/nomos-services/log/src/lib.rs +++ b/nomos-services/log/src/lib.rs @@ -1,7 +1,10 @@ // std use futures::StreamExt; +use std::fmt::{Debug, Formatter}; +use std::io::Write; use std::net::SocketAddr; use std::path::PathBuf; +use std::sync::{Arc, Mutex}; // crates use serde::{Deserialize, Serialize}; use tracing::{error, Level}; @@ -21,6 +24,37 @@ pub struct Logger { worker_guard: Option, } +/// This is a wrapper around a writer to allow cloning which is +/// required by contract by Overwatch for a configuration struct +#[derive(Clone)] +pub struct SharedWriter { + inner: Arc>>, +} + +impl Write for SharedWriter { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.inner.lock().unwrap().write(buf) + } + + fn flush(&mut self) -> std::io::Result<()> { + self.inner.lock().unwrap().flush() + } +} + +impl SharedWriter { + pub fn new(writer: W) -> Self { + Self { + inner: Arc::new(Mutex::new(Box::new(writer))), + } + } +} + +impl Debug for SharedWriter { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("SharedWriter").finish() + } +} + #[derive(Clone, Debug, Serialize, Deserialize)] pub enum LoggerBackend { Gelf { @@ -32,6 +66,8 @@ pub enum LoggerBackend { }, Stdout, Stderr, + #[serde(skip)] + Writer(SharedWriter), } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -121,6 +157,7 @@ impl ServiceCore for Logger { } LoggerBackend::Stdout => tracing_appender::non_blocking(std::io::stdout()), LoggerBackend::Stderr => tracing_appender::non_blocking(std::io::stderr()), + LoggerBackend::Writer(writer) => tracing_appender::non_blocking(writer), }; let layer = tracing_subscriber::fmt::Layer::new()