# Utilisation de ksp-logging-lib ## Target d'une crate consommatrice Chaque crate KSP comportementale fournit explicitement son target, égal au nom Cargo de la crate : ```rust const LOGGING_TARGET: &str = "ksp-store-lib"; ksp_logging_lib::trace!( target: LOGGING_TARGET, domain = "store", component = "postgres", operation = "load_transactions", "executing store operation" ); ``` Les champs `domain`, `component`, `operation` et autres champs structurés sont ajoutés par le caller lorsqu'ils sont utiles ; ils ne remplacent pas le target propriétaire. ## Initialisation `initialize` installe le subscriber global KSP une seule fois et retourne le `LoggingGuard` qui doit rester vivant pendant la durée du runtime : ```rust let settings = ksp_logging_lib::LoggingSettings::new( ksp_logging_lib::LogFilterLevel::Info, ksp_logging_lib::SpanEvents::NewAndClose, std::option::Option::Some(ksp_logging_lib::ConsoleSettings::stderr()), std::option::Option::Some(ksp_logging_lib::FileSettings::new( "logs", "worker.log", ksp_logging_lib::FileRotation::Daily, )), ); let initialize_result = ksp_logging_lib::initialize(&settings); let mut logging_guard = match initialize_result { std::result::Result::Ok(guard) => guard, std::result::Result::Err(error) => return std::result::Result::Err(error), }; ``` Une configuration sans console ni fichier est valide et installe une infrastructure initialement silencieuse qui pourra être activée plus tard par hot reload. ## Hot reload Une nouvelle configuration peut être appliquée sans redémarrer le processus ou le worker : ```rust let debug_settings = ksp_logging_lib::LoggingSettings::new( ksp_logging_lib::LogFilterLevel::Info, ksp_logging_lib::SpanEvents::NewAndClose, std::option::Option::Some(ksp_logging_lib::ConsoleSettings::stderr()), std::option::Option::None, ) .with_target_filter(ksp_logging_lib::TargetFilter::new( "ksp-store-lib", ksp_logging_lib::LogFilterLevel::Debug, )); let reload_result = ksp_logging_lib::reinitialize(&mut logging_guard, &debug_settings); if let std::result::Result::Err(error) = reload_result { return std::result::Result::Err(error); } ``` La nouvelle configuration est préparée avant la bascule. Si sa validation ou la création d'un nouveau sink échoue, l'ancienne configuration reste active. ## Spans synchrones ```rust let span = ksp_logging_lib::trace_span!( target: LOGGING_TARGET, "materialize_transaction", domain = "store" ); let output = span.in_scope(|| { return materialize_transaction(); }); ``` Avec `SpanEvents::NewAndClose`, le formatter produit les événements de création/fermeture et les temps `busy` / `idle` à la fermeture. ## Spans async Une `Future` doit être instrumentée avec `ksp_logging_lib::instrument` ; un guard d'entrée de span ne doit pas être conservé à travers `.await` : ```rust let span = ksp_logging_lib::trace_span!( target: LOGGING_TARGET, "fetch_account", domain = "transport" ); let output = ksp_logging_lib::instrument(span, fetch_account()).await; ``` La future instrumentée entre/sort du span pendant ses polls et lors de son `Drop`, conformément au contrat de la primitive `tracing` sous-jacente. ## Lignes abandonnées Les sorties utilisent des queues lossy afin de ne pas appliquer de backpressure au hot path. Les pertes restent observables : ```rust let dropped = logging_guard.dropped_lines(); ksp_logging_lib::warn!( target: LOGGING_TARGET, console = dropped.console(), file = dropped.file(), total = dropped.total(), "logging queues dropped lines" ); ``` ## Instrumentation async et executor `instrument(span, future)` accepte une `Future` standard et ne dépend d'aucun executor particulier : ```rust let span = ksp_logging_lib::trace_span!(target: LOGGING_TARGET, "load_transactions"); let result = ksp_logging_lib::instrument(span, async_operation()).await; ``` La crate ne requiert pas Tokio en production. Tokio n'est présent qu'en `dev-dependency` pour valider la surface sur un executor réel, y compris après plusieurs suspensions et sur un runtime multi-thread. Un consumer peut donc utiliser l'executor adapté à son propre contexte sans que Logging lui en impose un.