119 lines
5.3 KiB
Rust
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;
|