Add option to provide custom writer to the logger backend (#518)

* Add option to provide custom writer to the logger backend

* fmt
This commit is contained in:
Giacomo Pasini 2023-11-07 15:24:02 +01:00 committed by GitHub
parent c14998bb9a
commit 3028cdb5d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 37 additions and 0 deletions

View File

@ -1,7 +1,10 @@
// std // std
use futures::StreamExt; use futures::StreamExt;
use std::fmt::{Debug, Formatter};
use std::io::Write;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::{Arc, Mutex};
// crates // crates
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tracing::{error, Level}; use tracing::{error, Level};
@ -21,6 +24,37 @@ pub struct Logger {
worker_guard: Option<WorkerGuard>, worker_guard: Option<WorkerGuard>,
} }
/// 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<Mutex<Box<dyn Write + Send + Sync>>>,
}
impl Write for SharedWriter {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.inner.lock().unwrap().write(buf)
}
fn flush(&mut self) -> std::io::Result<()> {
self.inner.lock().unwrap().flush()
}
}
impl SharedWriter {
pub fn new<W: Write + Send + Sync + 'static>(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)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub enum LoggerBackend { pub enum LoggerBackend {
Gelf { Gelf {
@ -32,6 +66,8 @@ pub enum LoggerBackend {
}, },
Stdout, Stdout,
Stderr, Stderr,
#[serde(skip)]
Writer(SharedWriter),
} }
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
@ -121,6 +157,7 @@ impl ServiceCore for Logger {
} }
LoggerBackend::Stdout => tracing_appender::non_blocking(std::io::stdout()), LoggerBackend::Stdout => tracing_appender::non_blocking(std::io::stdout()),
LoggerBackend::Stderr => tracing_appender::non_blocking(std::io::stderr()), LoggerBackend::Stderr => tracing_appender::non_blocking(std::io::stderr()),
LoggerBackend::Writer(writer) => tracing_appender::non_blocking(writer),
}; };
let layer = tracing_subscriber::fmt::Layer::new() let layer = tracing_subscriber::fmt::Layer::new()