Files
khadhroony-solana-project/crates/ksp-app-config-desk/src/logging_runtime.rs
2026-08-20 09:24:10 +02:00

119 lines
5.3 KiB
Rust

// file: crates/ksp-app-config-desk/src/logging_runtime.rs
// version: 3
//! Runtime Logging metadata, launch identity and explicit profile application for Config Desk.
use ts_rs::TS; // rust-rules: derive-import
/// Metadata for one currently active persistent Logging file output.
#[derive(Clone, Debug, serde::Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export, export_to = "../frontend/ts/bindings/ksp_app_config_desk/logging_runtime/LoggingRuntimeFileDto.ts")]
pub(crate) struct LoggingRuntimeFileDto {
/// Stable configured output identifier.
pub(crate) output_id: String,
/// Resolved runtime directory.
pub(crate) directory: String,
/// Effective per-launch filename prefix passed to the rolling appender.
pub(crate) file_name_prefix: String,
/// Effective file rotation cadence.
pub(crate) rotation: String,
}
/// Safe observable state of the currently active KSP Logging runtime.
#[derive(Clone, Debug, serde::Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export, export_to = "../frontend/ts/bindings/ksp_app_config_desk/logging_runtime/LoggingRuntimeStatusDto.ts")]
pub(crate) struct LoggingRuntimeStatusDto {
/// Active profile identifier, or `None` while fallback Logging is active.
pub(crate) active_profile: std::option::Option<String>,
/// Source that selected the active runtime profile.
pub(crate) selection_source: String,
/// Monotonic runtime generation.
pub(crate) generation: u32,
/// Whether transient fallback Logging is active.
pub(crate) fallback_active: bool,
/// Stable application identifier embedded in launch-specific file names.
pub(crate) application_id: String,
/// Stable launch timestamp token reused by all hot reloads in this process.
pub(crate) launch_timestamp: String,
/// Whether the currently active console sink is enabled.
pub(crate) console_enabled: bool,
/// Cumulative console lines dropped by non-blocking outputs.
pub(crate) dropped_console_lines: u64,
/// Cumulative file lines dropped by non-blocking outputs.
pub(crate) dropped_file_lines: u64,
/// Cumulative lines dropped across all outputs.
pub(crate) dropped_total_lines: u64,
/// Active persistent file outputs and their launch-specific prefixes.
pub(crate) files: std::vec::Vec<LoggingRuntimeFileDto>,
}
/// Creates the stable runtime identity for this Config Desk process launch.
pub(crate) fn launch_identity() -> ksp_core_lib::Result<ksp_logging_lib::LoggingRuntimeIdentity> {
let timestamp = format!("{}-p{}", chrono::Utc::now().format("%Y%m%d-%H%M%S%.3fZ"), std::process::id());
return ksp_logging_lib::LoggingRuntimeIdentity::new(crate::TRACING_TARGET, timestamp);
}
/// Returns safe metadata for the currently active Logging runtime.
pub(crate) fn status(state: &crate::AppState) -> ksp_core_lib::Result<LoggingRuntimeStatusDto> {
return state.logging_runtime_status();
}
/// Applies one persisted Logging profile explicitly without changing `default_profile` or the source document.
pub(crate) fn apply_profile(state: &crate::AppState, profile_id: &str) -> ksp_core_lib::Result<LoggingRuntimeStatusDto> {
let environment = ksp_config_lib::ConfigEnvironment::load();
let environment = match environment {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let resolved = state.config_management().engine().load_resolved_logging_config(std::option::Option::Some(profile_id), &environment);
let resolved = match resolved {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let active_profile = resolved.profile_id().to_owned();
let settings = resolved.into_settings();
let generation = state.reinitialize_logging_runtime(active_profile.as_str(), "explicit", &settings);
if let std::result::Result::Err(error) = generation {
return std::result::Result::Err(error);
}
ksp_logging_lib::debug!(
target: crate::TRACING_TARGET,
domain = crate::TRACING_DOMAIN_LOGGING_RUNTIME,
active_profile = active_profile.as_str(),
selection_source = "explicit",
"persisted Logging profile applied explicitly to runtime"
);
return state.logging_runtime_status();
}
pub(crate) fn project_file(metadata: &ksp_logging_lib::RuntimeFileMetadata) -> LoggingRuntimeFileDto {
return LoggingRuntimeFileDto {
output_id: metadata.output_id().to_owned(),
directory: metadata.directory().display().to_string(),
file_name_prefix: metadata.file_name_prefix().to_owned(),
rotation: rotation_label(metadata.rotation()).to_owned(),
};
}
const fn rotation_label(rotation: ksp_logging_lib::FileRotation) -> &'static str {
return match rotation {
ksp_logging_lib::FileRotation::Never => "never",
ksp_logging_lib::FileRotation::Hourly => "hourly",
ksp_logging_lib::FileRotation::Daily => "daily",
};
}
pub(crate) fn count_to_u64(value: usize) -> u64 {
let converted = u64::try_from(value);
return match converted {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => u64::MAX,
};
}
#[cfg(test)]
#[path = "../unit_tests/logging_runtime.rs"]
mod tests;