#[cfg(target_family = "unix")]
use crate::create_syslog_layer;
use crate::errors::RexLoggerError;
use crate::memory_logger::config::{DEFAULT_LOG_ENTRIES_LIMIT, DEFAULT_MESSAGE_LENGTH_LIMIT};
use crate::memory_logger::handler::{SCRIPT_HANDLE, ScriptLogHandle};
use crate::tracing_logger::config::LoggingOption;
#[cfg(target_family = "unix")]
use crate::tracing_logger::config::SYSLOG_IDENTITY;
use crate::tracing_logger::level::log_level;
use crate::{
RUNNER_TARGET, RUNNER_TARGET_FOR_SCRIPT_LOGS, create_console_layer, create_script_log_layer,
default_fmt_layer,
};
use anyhow::Result;
use std::error::Error;
#[cfg(target_family = "unix")]
use std::ffi::CString;
#[cfg(target_family = "unix")]
use syslog_tracing::{Facility, Options, Syslog};
use tracing_subscriber::filter::FilterExt;
use tracing_subscriber::fmt::time::UtcTime;
use tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::{Layer, filter, fmt};
macro_rules! init_registry {
($($layer:expr),*) => {
let _ = tracing_subscriber::registry()
$(.with($layer))*
.try_init()
.map_err(|e| RexLoggerError::InitializationError {
reason: "Failed to initialize logger".to_string(),
source: Some(Box::new(e)),
})?;
};
}
pub fn init_logger(log_config: &LoggingOption) -> Result<(), Box<dyn Error>> {
if !log_config.console && !log_config.syslog && !log_config.script_log {
return Ok(());
}
let log_level = log_level();
let console_layer = create_console_layer!(log_config.console, log_level);
let script_layer = create_script_log_layer!(
log_config.script_log,
log_config
.max_script_log_message_length
.unwrap_or(DEFAULT_MESSAGE_LENGTH_LIMIT)
);
if let Some(ref handle) = script_layer {
SCRIPT_HANDLE.set(handle.clone()).ok();
}
#[cfg(target_family = "unix")]
{
let syslog_layer = create_syslog_layer!(log_config.syslog, log_level);
init_registry!(console_layer, syslog_layer, script_layer);
}
#[cfg(not(target_family = "unix"))]
{
init_registry!(console_layer, script_layer);
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::init_logger;
use crate::tracing_logger::config::LoggingOptionBuilder;
use sealed_test::prelude::*;
use std::env::set_var;
#[test]
fn test_logging_option_builder_defaults() {
let config = LoggingOptionBuilder::default().build().unwrap();
assert!(
!config.console,
"Console logging should be disabled by default"
);
assert!(!config.syslog, "Syslog should be disabled by default");
let result = init_logger(&config);
assert!(
result.is_ok(),
"init_logger should succeed even with all logging disabled"
);
}
#[test]
fn test_init_logger_console_only() {
let config = LoggingOptionBuilder::default()
.console(true)
.syslog(false)
.build()
.unwrap();
let result = init_logger(&config);
assert!(
result.is_ok(),
"init_logger should succeed with only console subscriber enabled"
);
}
#[sealed_test]
fn test_init_logger_integration() {
unsafe {
set_var("LOG_LEVEL", "INFO");
}
let config = LoggingOptionBuilder::default()
.console(false) .syslog(false) .build()
.unwrap();
let result = init_logger(&config);
assert!(
result.is_ok(),
"Refactored init_logger should work correctly"
);
}
}