Skip to content

Commit

Permalink
revive backend of access logs when it fails
Browse files Browse the repository at this point in the history
startup fails when access logs backend is not responding

Co-Authored-By: Eloi DEMOLIS <[email protected]>
  • Loading branch information
Keksoj and Wonshtrum committed Apr 23, 2024
1 parent 5dfb309 commit edb9b94
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 21 deletions.
61 changes: 40 additions & 21 deletions command/src/logging/logs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use std::{

use mio::net::UnixDatagram;
use prost::{encoding::encoded_len_varint, Message};
use rand::{distributions::Alphanumeric, thread_rng, Rng};

use crate::{
config::Config,
Expand Down Expand Up @@ -59,9 +58,12 @@ pub struct InnerLogger {
version: u8,
directives: Vec<LogDirective>,
backend: LoggerBackend,
log_target: String,
pub colored: bool,
/// target of the access logs
access_backend: Option<LoggerBackend>,
/// used to revive the backend for access logs
access_logs_target: Option<String>,
/// how to format the access logs
access_format: AccessLogFormat,
access_colored: bool,
Expand Down Expand Up @@ -99,8 +101,10 @@ impl Default for Logger {
level: LogLevelFilter::Error,
}],
backend: LoggerBackend::Stdout(stdout()),
log_target: "stdout".to_string(),
colored: false,
access_backend: None,
access_logs_target: None,
access_format: AccessLogFormat::Ascii,
access_colored: false,
buffer: LoggerBuffer(Vec::with_capacity(4096)),
Expand All @@ -120,12 +124,20 @@ impl Logger {
pub fn init(
tag: String,
spec: &str,
backend: LoggerBackend,
log_target: &str,
colored: bool,
access_backend: Option<LoggerBackend>,
access_logs_target: Option<&str>,
access_format: Option<AccessLogFormat>,
access_colored: Option<bool>,
) {
println!("setting log target to {log_target}");
let backend = target_or_default(log_target);

println!("setting target of access logs to {access_logs_target:?}");
let access_backend = access_logs_target.map(|target| {
target_to_backend(target).expect("could not setup logger for access logs")
});

let (directives, _errors) = parse_logging_spec(spec);
LOGGER.with(|logger| {
let mut logger = logger.borrow_mut();
Expand All @@ -142,7 +154,9 @@ impl Logger {
_ => false,
};
logger.backend = backend;
logger.log_target = log_target.to_owned();
logger.access_backend = access_backend;
logger.access_logs_target = access_logs_target.map(ToOwned::to_owned);
logger.access_format = access_format.unwrap_or(AccessLogFormat::Ascii);
logger.tag = tag;
logger.pid = unsafe { libc::getpid() };
Expand Down Expand Up @@ -293,6 +307,11 @@ impl InnerLogger {

if let Err(e) = io_result {
println!("Could not write access log to {}: {e:?}", backend.as_ref());
println!(
"trying to revive the backend of access logs to {:?}, or defaulting to {}",
self.access_logs_target, self.log_target
);
backend.revive(self.access_logs_target.as_ref().unwrap_or(&self.log_target));
}
}

Expand Down Expand Up @@ -337,6 +356,17 @@ pub enum LoggerBackend {
File(crate::writer::MultiLineWriter<File>),
}

impl LoggerBackend {
fn revive(&mut self, log_target: &str) {
match target_to_backend(log_target) {
Ok(backend) => *self = backend,
Err(err) => {
println!("could not revive logger backend: {err}");
}
}
}
}

#[repr(usize)]
#[derive(Clone, Copy, Eq, Debug)]
pub enum LogLevel {
Expand Down Expand Up @@ -614,18 +644,14 @@ pub fn setup_logging(
log_level: &str,
tag: &str,
) {
let backend = target_or_default(log_target);

let access_backend = access_logs_target.map(target_or_default);

let log_level = env::var("RUST_LOG").unwrap_or(log_level.to_string());

Logger::init(
tag.to_string(),
&log_level,
backend,
log_target,
log_colored,
access_backend,
access_logs_target,
access_logs_format,
access_logs_colored,
);
Expand Down Expand Up @@ -668,18 +694,11 @@ pub fn target_to_backend(target: &str) -> Result<LoggerBackend, LogError> {
}

if let Some(addr) = target.strip_prefix("unix://") {
let path = Path::new(addr);
let mut dir = env::temp_dir();
let s: String = thread_rng()
.sample_iter(&Alphanumeric)
.take(12)
.map(|c| c as char)
.collect();
dir.push(s);
let socket = UnixDatagram::bind(dir).unwrap();
let socket = UnixDatagram::unbound().map_err(LogError::CreateUnixSocket)?;

socket
.connect(path)
.map_err(|e| LogError::InvalidLogTarget(target.to_owned(), e.to_string()))?;
.connect(addr)
.map_err(|e| LogError::ConnectToUnixSocket(target.to_owned(), e))?;

return Ok(LoggerBackend::Unix(socket));
}
Expand Down Expand Up @@ -1012,7 +1031,7 @@ macro_rules! setup_test_logger {
$crate::logging::Logger::init(
module_path!().to_string(),
"error",
$crate::logging::LoggerBackend::Stdout(::std::io::stdout()),
"stdout",
false,
None,
None,
Expand Down
4 changes: 4 additions & 0 deletions command/src/logging/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ pub enum LogError {
InvalidLogTarget(String, String),
#[error("could not connect to TCP socket {0}: {1}")]
TcpConnect(String, std::io::Error),
#[error("could not create unbound UNIX datagram: {0}")]
CreateUnixSocket(std::io::Error),
#[error("could not connect to UNIX datagram {0}: {1}")]
ConnectToUnixSocket(String, std::io::Error),
}

0 comments on commit edb9b94

Please sign in to comment.