// file: crates/ksp-app-config-desk/src/bootstrap.rs // version: 2 //! Config and Logging bootstrap for the desktop application. pub(crate) struct LoggingStartup { pub(crate) guard: ksp_logging_lib::LoggingGuard, pub(crate) active_profile_id: std::option::Option, pub(crate) selection_source: String, pub(crate) fallback_active: bool, pub(crate) startup_diagnostic: std::option::Option, } pub(crate) fn config_management(arguments: &[std::ffi::OsString]) -> ksp_core_lib::Result { let bootstrap = ksp_config_lib::ConfigBootstrapOptions::from_args(arguments); let bootstrap = match bootstrap { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let registry = ksp_config_lib::ConfigFileRegistry::from_args(arguments); let registry = match registry { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let engine = ksp_config_lib::ConfigDocumentEngine::new(bootstrap, registry); return std::result::Result::Ok(ksp_config_lib::ConfigManagement::new(engine)); } pub(crate) fn initialize_logging( management: &ksp_config_lib::ConfigManagement, runtime_identity: &ksp_logging_lib::LoggingRuntimeIdentity, ) -> ksp_core_lib::Result { let environment = ksp_config_lib::ConfigEnvironment::load(); let environment = match environment { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return initialize_fallback_logging(error, runtime_identity), }; let resolved = management.engine().load_resolved_logging_config(std::option::Option::None, &environment); let resolved = match resolved { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return initialize_fallback_logging(error, runtime_identity), }; let active_profile_id = resolved.profile_id().to_owned(); let settings = resolved.into_settings(); let guard = ksp_logging_lib::initialize_with_identity(&settings, runtime_identity); return match guard { std::result::Result::Ok(guard) => { ksp_logging_lib::info!( target: crate::TRACING_TARGET, domain = crate::TRACING_DOMAIN_BOOTSTRAP, active_profile = active_profile_id.as_str(), "initialized Config Desk logging from managed configuration" ); std::result::Result::Ok(LoggingStartup { guard, active_profile_id: std::option::Option::Some(active_profile_id), selection_source: "default_profile".to_owned(), fallback_active: false, startup_diagnostic: std::option::Option::None, }) }, std::result::Result::Err(error) => initialize_fallback_logging(error, runtime_identity), }; } fn initialize_fallback_logging( initial_error: ksp_core_lib::Error, runtime_identity: &ksp_logging_lib::LoggingRuntimeIdentity, ) -> ksp_core_lib::Result { let diagnostic = crate::CommandErrorDto::from_error(&initial_error); let settings = fallback_logging_settings(); let guard = ksp_logging_lib::initialize_with_identity(&settings, runtime_identity); let guard = match guard { std::result::Result::Ok(value) => value, std::result::Result::Err(fallback_error) => { return std::result::Result::Err( ksp_core_lib::Error::new(crate::ERROR_CODE_LOGGING_BOOTSTRAP_FAILED, "Cannot initialize Config Desk fallback Logging runtime") .with_context("initial_error_domain", initial_error.code().domain()) .with_context("initial_error_code", initial_error.code().code()) .with_source(fallback_error), ); }, }; ksp_logging_lib::warn!( target: crate::TRACING_TARGET, domain = crate::TRACING_DOMAIN_BOOTSTRAP, error_domain = diagnostic.domain.as_str(), error_code = diagnostic.code.as_str(), "managed Logging configuration is unavailable; using transient in-memory fallback" ); return std::result::Result::Ok(LoggingStartup { guard, active_profile_id: std::option::Option::None, selection_source: "fallback".to_owned(), fallback_active: true, startup_diagnostic: std::option::Option::Some(diagnostic), }); } pub(crate) fn fallback_logging_settings() -> ksp_logging_lib::LoggingSettings { return ksp_logging_lib::LoggingSettings::new( ksp_logging_lib::LogFilterLevel::Info, ksp_logging_lib::SpanEvents::Off, std::option::Option::Some(ksp_logging_lib::ConsoleSettings::stderr()), std::vec::Vec::new(), ); } #[cfg(test)] #[path = "../unit_tests/bootstrap.rs"] mod tests;