# Utilisation de ks-logging ## Initialisation ```rust let config = ks_logging::LoggingConfig { default_level: "info".to_string(), targets: vec![ks_logging::LogTargetConfig { name: "console".to_string(), enabled: true, sink: "console".to_string(), level: "info".to_string(), path: String::new(), rotation: "none".to_string(), format: "compact".to_string(), ansi: true, targets: vec!["kb-*".to_string()], }], target_filters: Vec::new(), }; let guard = match ks_logging::init_logging(&config) { Ok(value) => value, Err(error) => return Err(error), }; ``` `init_logging` doit être appelée une seule fois par processus. Le `LoggingGuard` retourné doit rester vivant jusqu’à l’arrêt afin de ne pas interrompre les writers non bloquants. ## Inspection des routes ```rust assert_eq!(guard.route_count(), 1); assert_eq!(guard.guard_count(), 1); assert_eq!(guard.route_names(), &["console".to_string()]); ``` ## Route fichier JSON ```rust let file_route = ks_logging::LogTargetConfig { name: "operations-json".to_string(), enabled: true, sink: "file".to_string(), level: "debug".to_string(), path: "logs/operations.jsonl".to_string(), rotation: "daily".to_string(), format: "json".to_string(), ansi: false, targets: vec![ "ks-pipeline*".to_string(), "ks-onchain-transport*".to_string(), ], }; let config = ks_logging::LoggingConfig { default_level: "info".to_string(), targets: vec![file_route], target_filters: Vec::new(), }; let guard = match ks_logging::init_logging(&config) { Ok(value) => value, Err(error) => return Err(error), }; ``` Pour une route `file`, `path` doit désigner le fichier cible et `rotation` doit être une valeur supportée (`none`, `never`, `daily` ou `hourly`). Les formats supportés sont `human`, `compact`, `pretty` et `json`. ## Filtres de targets ```rust let config = ks_logging::LoggingConfig { default_level: "warn".to_string(), targets: vec![ks_logging::LogTargetConfig { name: "console".to_string(), enabled: true, sink: "console".to_string(), level: "info".to_string(), path: String::new(), rotation: "none".to_string(), format: "compact".to_string(), ansi: true, targets: vec!["kb-*".to_string()], }], target_filters: vec![ ks_logging::LogTargetFilterConfig { target: "ks-pipeline".to_string(), level: "debug".to_string(), }, ks_logging::LogTargetFilterConfig { target: "ks-store".to_string(), level: "info".to_string(), }, ], }; ``` Les routes acceptent des targets exactes et des préfixes wildcard. Les `target_filters` ajoutent des niveaux spécifiques aux routes wildcard. Une route d’erreur conserve la sémantique stricte prévue par l’implémentation. ## Émission d’événements après initialisation ```rust tracing::info!( target: ks_logging::tracing_target(), action = "startup", "logging runtime initialized" ); tracing::debug!( target: "ks-pipeline.demo", scenario = "token_2022", "scenario preparation started" ); ``` Les targets doivent suivre la nomenclature canonique du workspace pour que les routes et filtres restent prévisibles. ## Inspection des routes actives ```rust for route_name in guard.route_names() { println!("active logging route: {route_name}"); } assert_eq!(guard.route_count(), guard.route_names().len()); ``` ## Erreurs Les erreurs utilisent `ks_core::Error`. Les cas principaux sont : - aucune route activée ; - sink, format, rotation ou niveau inconnu ; - chemin fichier invalide ; - échec d’initialisation du subscriber global. ## Tests instructifs - `enabled_routes_keep_all_configured_outputs` vérifie l’installation multi-routes ; - `route_writer_filter_preserves_target_and_level_semantics` vérifie l’admission finale ; - `more_than_64_routes_compose_without_filtered_layer_ids` couvre un volume élevé de routes ; - `every_tracing_crate_exposes_canonical_targets` vérifie la cohérence des targets du workspace. ## Limites - initialisation globale unique par processus ; - configuration fournie par l’appelant ;