use std::ffi::CStr;
use tracing::{info, Level};
use tracing_subscriber::{
layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Layer,
};
#[derive(thiserror::Error, Debug)]
pub(crate) enum LoggingError {
#[error("Failed to setup basic tracing: {source:?}")]
SetupFailure { source: Box<dyn std::error::Error> },
#[error(transparent)]
IOError(#[from] std::io::Error),
#[error(transparent)]
TryInitError(#[from] tracing_subscriber::util::TryInitError),
#[error("Failed to setup syslog logging")]
SyslogError,
}
pub(crate) fn init(verbose: bool, container: bool) -> Result<(), LoggingError> {
let tracing_level = if verbose { Level::TRACE } else { Level::INFO };
if container {
init_container_logging(tracing_level)
} else {
match std::process::id() {
1 => init_pid1_logging(tracing_level),
_ => init_daemon_logging(tracing_level),
}
}
}
fn init_container_logging(tracing_level: Level) -> Result<(), LoggingError> {
info!("initializing container logging");
let stdout_layer = Layer::with_filter(
tracing_subscriber::fmt::layer().compact(),
EnvFilter::new(format!("auraed={tracing_level}")),
);
tracing_subscriber::registry()
.with(stdout_layer)
.try_init()
.map_err(|e| e.into())
}
fn init_daemon_logging(tracing_level: Level) -> Result<(), LoggingError> {
info!("initializing syslog logging");
let syslog_identity =
CStr::from_bytes_with_nul(b"auraed\0").expect("valid CStr");
let syslog_facility = Default::default();
let syslog_options = syslog_tracing::Options::LOG_PID;
let Some(syslog) = syslog_tracing::Syslog::new(
syslog_identity,
syslog_options,
syslog_facility,
) else {
return Err(LoggingError::SyslogError);
};
let syslog_layer = tracing_subscriber::fmt::layer().with_writer(syslog);
let stdout_layer = Layer::with_filter(
tracing_subscriber::fmt::layer().compact(),
EnvFilter::new(format!("auraed={tracing_level}")),
);
tracing_subscriber::registry()
.with(syslog_layer)
.with(stdout_layer)
.try_init()
.map_err(|e| e.into())
}
#[allow(unused)]
fn init_stdout_logging(tracing_level: Level) -> Result<(), LoggingError> {
info!("initializing stdout logging");
tracing_subscriber::fmt()
.compact()
.with_env_filter(format!("auraed={tracing_level}"))
.finish()
.try_init()
.map_err(|e| e.into())
}
fn init_pid1_logging(tracing_level: Level) -> Result<(), LoggingError> {
info!("initializing pid1 logging");
tracing_subscriber::fmt()
.compact()
.with_env_filter(format!("auraed={tracing_level}"))
.try_init()
.map_err(|e| LoggingError::SetupFailure { source: e })
}