v0.2.5-pre.010.fix.001

This commit is contained in:
2026-08-20 11:17:12 +02:00
parent 5bf9651038
commit c0b131bf6f
97 changed files with 2277 additions and 655 deletions

View File

@@ -1,13 +1,15 @@
// file: crates/ksp-logging-lib/src/domain.rs
// version: 2
// version: 3
std::thread_local! {
static CURRENT_DOMAIN: std::cell::RefCell<std::option::Option<std::string::String>> = const { std::cell::RefCell::new(std::option::Option::None) };
}
/// Crate-internal `DomainContextLayer` state shared across the owning crate.
pub(crate) struct DomainContextLayer;
impl DomainContextLayer {
/// Creates a new `DomainContextLayer` value.
pub(crate) const fn new() -> Self {
return Self;
}
@@ -99,6 +101,7 @@ impl tracing::field::Visit for DomainVisitor {
}
}
/// Executes the crate-internal current domain matches operation for the owning module.
pub(crate) fn current_domain_matches(selectors: &[std::string::String]) -> bool {
if let [selector] = selectors
&& selector == "*"

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-logging-lib/src/identity.rs
// version: 1
// version: 2
//! Stable runtime identity used to separate persistent file outputs between application launches.
@@ -41,6 +41,7 @@ impl LoggingRuntimeIdentity {
return self.launch_timestamp.as_str();
}
/// Executes the crate-internal file name prefix operation for `LoggingRuntimeIdentity`.
pub(crate) fn file_name_prefix(&self, configured_prefix: &str) -> std::string::String {
return format!("{}.{}.{}", self.application_id, self.launch_timestamp, configured_prefix);
}

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-logging-lib/src/lib.rs
// version: 9
// version: 10
#![warn(missing_docs)]
#![deny(unreachable_pub)]
@@ -70,10 +70,17 @@ pub use self::span::Span;
/// Instruments an asynchronous future with a KSP span.
pub use self::span::instrument;
/// Crate-internal `DomainContextLayer` state shared across the owning crate.
pub(crate) use self::domain::DomainContextLayer;
/// Executes the crate-internal current domain matches operation for the owning module.
pub(crate) use self::domain::current_domain_matches;
/// Crate-internal `RouteMakeWriter` state shared across the owning crate.
pub(crate) use self::writer::RouteMakeWriter;
/// Crate-internal `RoutedWriter` variants used by the owning crate.
pub(crate) use self::writer::RoutedWriter;
/// Crate-internal `StripAnsiWriter` state shared across the owning crate.
pub(crate) use self::writer::StripAnsiWriter;
/// Hidden tracing crate bridge used exclusively by exported KSP logging macros.
#[doc(hidden)]
/// Internal macro bridge. KSP consumers must not use this reexport directly.
pub extern crate tracing as __private_tracing;
pub extern crate tracing;

View File

@@ -1,11 +1,11 @@
// file: crates/ksp-logging-lib/src/macros.rs
// version: 1
// version: 2
/// Emits a KSP error event with an explicit owning target.
#[macro_export]
macro_rules! error {
(target: $target:expr, $($argument:tt)+) => {{
$crate::__private_tracing::error!(target: $target, $($argument)+);
$crate::tracing::error!(target: $target, $($argument)+);
}};
}
@@ -13,7 +13,7 @@ macro_rules! error {
#[macro_export]
macro_rules! warn {
(target: $target:expr, $($argument:tt)+) => {{
$crate::__private_tracing::warn!(target: $target, $($argument)+);
$crate::tracing::warn!(target: $target, $($argument)+);
}};
}
@@ -21,7 +21,7 @@ macro_rules! warn {
#[macro_export]
macro_rules! info {
(target: $target:expr, $($argument:tt)+) => {{
$crate::__private_tracing::info!(target: $target, $($argument)+);
$crate::tracing::info!(target: $target, $($argument)+);
}};
}
@@ -29,7 +29,7 @@ macro_rules! info {
#[macro_export]
macro_rules! debug {
(target: $target:expr, $($argument:tt)+) => {{
$crate::__private_tracing::debug!(target: $target, $($argument)+);
$crate::tracing::debug!(target: $target, $($argument)+);
}};
}
@@ -37,7 +37,7 @@ macro_rules! debug {
#[macro_export]
macro_rules! trace {
(target: $target:expr, $($argument:tt)+) => {{
$crate::__private_tracing::trace!(target: $target, $($argument)+);
$crate::tracing::trace!(target: $target, $($argument)+);
}};
}
@@ -45,10 +45,10 @@ macro_rules! trace {
#[macro_export]
macro_rules! error_span {
(target: $target:expr, $name:expr) => {{
$crate::Span::__from_tracing($crate::__private_tracing::error_span!(target: $target, $name))
$crate::Span::__from_tracing($crate::tracing::error_span!(target: $target, $name))
}};
(target: $target:expr, $name:expr, $($field:tt)+) => {{
$crate::Span::__from_tracing($crate::__private_tracing::error_span!(target: $target, $name, $($field)+))
$crate::Span::__from_tracing($crate::tracing::error_span!(target: $target, $name, $($field)+))
}};
}
@@ -56,10 +56,10 @@ macro_rules! error_span {
#[macro_export]
macro_rules! warn_span {
(target: $target:expr, $name:expr) => {{
$crate::Span::__from_tracing($crate::__private_tracing::warn_span!(target: $target, $name))
$crate::Span::__from_tracing($crate::tracing::warn_span!(target: $target, $name))
}};
(target: $target:expr, $name:expr, $($field:tt)+) => {{
$crate::Span::__from_tracing($crate::__private_tracing::warn_span!(target: $target, $name, $($field)+))
$crate::Span::__from_tracing($crate::tracing::warn_span!(target: $target, $name, $($field)+))
}};
}
@@ -67,10 +67,10 @@ macro_rules! warn_span {
#[macro_export]
macro_rules! info_span {
(target: $target:expr, $name:expr) => {{
$crate::Span::__from_tracing($crate::__private_tracing::info_span!(target: $target, $name))
$crate::Span::__from_tracing($crate::tracing::info_span!(target: $target, $name))
}};
(target: $target:expr, $name:expr, $($field:tt)+) => {{
$crate::Span::__from_tracing($crate::__private_tracing::info_span!(target: $target, $name, $($field)+))
$crate::Span::__from_tracing($crate::tracing::info_span!(target: $target, $name, $($field)+))
}};
}
@@ -78,10 +78,10 @@ macro_rules! info_span {
#[macro_export]
macro_rules! debug_span {
(target: $target:expr, $name:expr) => {{
$crate::Span::__from_tracing($crate::__private_tracing::debug_span!(target: $target, $name))
$crate::Span::__from_tracing($crate::tracing::debug_span!(target: $target, $name))
}};
(target: $target:expr, $name:expr, $($field:tt)+) => {{
$crate::Span::__from_tracing($crate::__private_tracing::debug_span!(target: $target, $name, $($field)+))
$crate::Span::__from_tracing($crate::tracing::debug_span!(target: $target, $name, $($field)+))
}};
}
@@ -89,9 +89,9 @@ macro_rules! debug_span {
#[macro_export]
macro_rules! trace_span {
(target: $target:expr, $name:expr) => {{
$crate::Span::__from_tracing($crate::__private_tracing::trace_span!(target: $target, $name))
$crate::Span::__from_tracing($crate::tracing::trace_span!(target: $target, $name))
}};
(target: $target:expr, $name:expr, $($field:tt)+) => {{
$crate::Span::__from_tracing($crate::__private_tracing::trace_span!(target: $target, $name, $($field)+))
$crate::Span::__from_tracing($crate::tracing::trace_span!(target: $target, $name, $($field)+))
}};
}

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-logging-lib/src/runtime.rs
// version: 14
// version: 15
use tracing_subscriber::Layer; // rust-rules: trait-import
use tracing_subscriber::layer::SubscriberExt; // rust-rules: trait-import
@@ -315,7 +315,7 @@ fn prepare_runtime_with_identity(
if output_layers.is_empty() {
return std::result::Result::Ok(PreparedRuntime { layers: RuntimeLayers::new(), outputs });
}
output_layers.insert(0, crate::domain::DomainContextLayer::new().boxed());
output_layers.insert(0, crate::DomainContextLayer::new().boxed());
let takeover_layer = build_target_filter(settings).and_then(output_layers).boxed();
return std::result::Result::Ok(PreparedRuntime { layers: vec![takeover_layer], outputs });
}
@@ -413,7 +413,7 @@ fn build_format_layer(
let span_events = map_span_events(span_events);
return match format {
crate::LogFormat::Human => tracing_subscriber::fmt::layer()
.with_writer(crate::writer::RouteMakeWriter::new(writer, filter.clone()))
.with_writer(crate::RouteMakeWriter::new(writer, filter.clone()))
.with_ansi(ansi)
.with_ansi_sanitization(ansi_sanitization)
.with_target(true)
@@ -423,7 +423,7 @@ fn build_format_layer(
.boxed(),
crate::LogFormat::Compact => tracing_subscriber::fmt::layer()
.compact()
.with_writer(crate::writer::RouteMakeWriter::new(writer, filter.clone()))
.with_writer(crate::RouteMakeWriter::new(writer, filter.clone()))
.with_ansi(ansi)
.with_ansi_sanitization(ansi_sanitization)
.with_target(true)
@@ -433,7 +433,7 @@ fn build_format_layer(
.boxed(),
crate::LogFormat::Pretty => tracing_subscriber::fmt::layer()
.pretty()
.with_writer(crate::writer::RouteMakeWriter::new(writer, filter.clone()))
.with_writer(crate::RouteMakeWriter::new(writer, filter.clone()))
.with_ansi(ansi)
.with_ansi_sanitization(ansi_sanitization)
.with_target(true)
@@ -443,7 +443,7 @@ fn build_format_layer(
.boxed(),
crate::LogFormat::Json => tracing_subscriber::fmt::layer()
.json()
.with_writer(crate::writer::RouteMakeWriter::new(writer, filter.clone()))
.with_writer(crate::RouteMakeWriter::new(writer, filter.clone()))
.with_ansi(false)
.with_target(true)
.with_file(true)
@@ -473,7 +473,6 @@ const fn map_filter_level(level: crate::LogFilterLevel) -> tracing_subscriber::f
crate::LogFilterLevel::Trace => tracing_subscriber::filter::LevelFilter::TRACE,
};
}
const fn map_file_rotation(rotation: crate::FileRotation) -> tracing_appender::rolling::Rotation {
return match rotation {
crate::FileRotation::Never => tracing_appender::rolling::Rotation::NEVER,

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-logging-lib/src/writer.rs
// version: 4
// version: 5
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum StripAnsiState {
@@ -12,12 +12,14 @@ enum StripAnsiState {
StringEscape,
}
/// Crate-internal `StripAnsiWriter` state shared across the owning crate.
pub(crate) struct StripAnsiWriter<W> {
inner: W,
state: StripAnsiState,
}
impl<W> StripAnsiWriter<W> {
/// Creates a new `StripAnsiWriter` value.
pub(crate) const fn new(inner: W) -> Self {
return Self { inner, state: StripAnsiState::Text };
}
@@ -100,6 +102,7 @@ impl<W> StripAnsiWriter<W> {
}
}
/// Crate-internal `RouteMakeWriter` state shared across the owning crate.
#[derive(Clone)]
pub(crate) struct RouteMakeWriter<W> {
inner: W,
@@ -107,11 +110,13 @@ pub(crate) struct RouteMakeWriter<W> {
}
impl<W> RouteMakeWriter<W> {
/// Creates a new `RouteMakeWriter` value.
pub(crate) fn new(inner: W, filter: crate::OutputFilter) -> Self {
return Self { inner, filter };
}
}
/// Crate-internal `RoutedWriter` variants used by the owning crate.
pub(crate) enum RoutedWriter<W> {
Enabled(W),
Disabled,

View File

@@ -1,12 +1,12 @@
// file: crates/ksp-logging-lib/tests/overhead.rs
// version: 1
// version: 2
//! Diagnostic gross-overhead probe for the reload layer used by KSP Logging.
use tracing_subscriber::layer::SubscriberExt; // rust-rules: trait-import
const TEST_TARGET: &str = "ksp-logging-lib";
const ITERATIONS: u64 = 200_000;
const TEST_TARGET: &str = "ksp-logging-lib";
fn emit_probe_events() {
for sequence in 0..ITERATIONS {

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-logging-lib/tests/ownership.rs
// version: 2
// version: 3
//! Integration audit ensuring KSP crates do not bypass the logging facade.
@@ -157,6 +157,11 @@ fn workspace_crates_do_not_bypass_ksp_logging_facade() {
std::result::Result::Err(_) => continue,
};
assert!(!source_uses_direct_path(source.as_str(), "tracing::"), "{} bypasses ksp-logging-lib via tracing", rust_file.display());
assert!(
!source_uses_direct_path(source.as_str(), "ksp_logging_lib::tracing::"),
"{} bypasses ksp-logging-lib via its hidden tracing bridge",
rust_file.display(),
);
assert!(
!source_uses_direct_path(source.as_str(), "tracing_subscriber::"),
"{} bypasses ksp-logging-lib via tracing-subscriber",

View File

@@ -1,12 +1,12 @@
// file: crates/ksp-logging-lib/tests/runtime.rs
// version: 9
// version: 10
//! Integration tests for global initialization, takeover filtering, non-blocking outputs and hot reload.
const EXTERNAL_TARGET: &str = "sqlx";
const JSON_KSP_TARGET: &str = "ksp-logging-json-test";
const LOGGING_TARGET: &str = "ksp-logging-lib";
const OTHER_KSP_TARGET: &str = "ksp-store-lib";
const JSON_KSP_TARGET: &str = "ksp-logging-json-test";
const EXTERNAL_TARGET: &str = "sqlx";
fn logging_trace_enabled() -> bool {
return tracing::enabled!(target: LOGGING_TARGET, tracing::Level::TRACE);