Files
khadhroony-solana-project/deltas/0.1.2/pre.004.md
2026-08-14 18:43:54 +02:00

8.1 KiB

Delta 0.1.2-pre.004

Base requise

Livraison précédente validée :

0.1.2-pre.003-fix.001

La base de développement validée porte :

workspace.package.version = "0.1.2-pre.3.fix.1"
Cargo.toml header version = 30

Les validations remontées avant l'ouverture de cette tranche sont propres :

cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test --workspace

Objectif

Compléter le runtime Logging avec les sorties réellement retenues pour 0.1.2 :

  • ajouter tracing-appender ;
  • rendre console et fichier non bloquants pour le caller ;
  • posséder les WorkerGuard jusqu'au reload/shutdown approprié ;
  • exposer les dropped-line counters ;
  • activer le fichier Never/Hourly/Daily avec construction fallible ;
  • supprimer les séquences ANSI avant persistence ;
  • conserver le takeover et le hot reload transactionnel établis par pre.003-fix.001.

Version Cargo

workspace.package.version passe de :

0.1.2-pre.3.fix.1

à :

0.1.2-pre.4

L'identifiant de livraison est :

0.1.2-pre.004

Le header du Cargo.toml racine passe de version 30 à 31.

Dépendance tracing-appender

L'audit du 2026-08-14 confirme tracing-appender 0.2.5, publié le 2026-04-17, dans la génération ^0.2.

La dépendance est centralisée sous [workspace.dependencies] :

tracing-appender = { version = "^0.2", default-features = false }

ksp-logging-lib la consomme avec :

tracing-appender.workspace = true

Aucune feature optionnelle n'est activée. Le backend expose NonBlockingBuilder, WorkerGuard, ErrorCounter et RollingFileAppender sans feature supplémentaire.

Console non bloquante

La console n'utilise plus directement stdout/stderr dans le formatter.

Chaque sink console construit :

Stdout | Stderr
    -> NonBlockingBuilder(lossy = true)
    -> fmt layer
    + WorkerGuard
    + ErrorCounter

Le mode lossy est explicite : lorsque la queue est saturée, un log peut être abandonné au lieu de bloquer le thread appelant.

Le thread worker console est nommé :

ksp-logging-console

Fichier et rotation

FileSettings est maintenant réellement consommé par le runtime.

Le mapping est :

FileRotation::Never  -> Rotation::NEVER
FileRotation::Hourly -> Rotation::HOURLY
FileRotation::Daily  -> Rotation::DAILY

Le runtime utilise uniquement :

RollingFileAppender::builder()
    .rotation(...)
    .filename_prefix(...)
    .build(directory)

La forme builder retourne un Result; aucune API de construction qui panique n'est utilisée par KSP.

Un échec retourne :

logging.file_output_initialization_failed

avec le directory, le file-name prefix et l'erreur InitError externe conservés dans le contrat Core.

Stripping ANSI

Le fichier est composé comme suit :

fmt layer
    -> NonBlocking queue
        -> StripAnsiWriter
            -> RollingFileAppender

Le stripping est donc effectué par le thread logging et non par le caller.

StripAnsiWriter conserve un état entre les appels Write afin de retirer correctement une séquence terminal coupée entre plusieurs buffers. La première surface couvre :

  • CSI (ESC [ ... final byte) ;
  • OSC terminé par BEL ou ST ;
  • autres chaînes terminal ESC de type DCS/SOS/PM/APC terminées par ST.

Ce mécanisme est générique et n'introduit aucune dépendance Tauri.

Formatter humain

Console et fichier partagent le formatter humain KSP avec :

  • timestamp standard tracing-subscriber ;
  • niveau ;
  • target ;
  • champs/message ;
  • source file ;
  • line number ;
  • ANSI du formatter désactivé ;
  • lifecycle de spans selon SpanEvents.

La ponctuation exacte du formatter reste hors contrat public.

Ownership et reload

LoggingGuard possède désormais les outputs actifs :

LoggingGuard
├── reload handle
├── current LoggingSettings
├── active console WorkerGuard/ErrorCounter
├── active file WorkerGuard/ErrorCounter
└── cumulative retired dropped-line counters

reinitialize() :

  1. valide les nouveaux settings ;
  2. construit entièrement le nouveau file appender et tous les nouveaux non-blocking writers/guards ;
  3. construit les nouveaux layers ;
  4. remplace le Vec reloadable ;
  5. mémorise les dropped lines des anciens sinks ;
  6. remplace les outputs actifs ;
  7. détruit les anciens WorkerGuard, provoquant leur flush borné par le backend.

Une erreur avant le swap détruit uniquement les nouveaux outputs préparés et laisse l'ancienne configuration active.

Dropped lines

Nouvelle surface publique :

DroppedLines
LoggingGuard::dropped_lines() -> DroppedLines

DroppedLines expose :

console()
file()
total()

Les valeurs sont cumulées pour toute la durée de vie du LoggingGuard, y compris après plusieurs hot reloads. Les ErrorCounter de tracing-appender ne sont pas exposés directement aux consumers.

Tests

Unitaires

  • mapping Never/Hourly/Daily ;
  • runtime sans sink ;
  • console préparée avec filter séparé, non-blocking output et guard ;
  • addition saturante des dropped-line counters ;
  • stripping CSI ;
  • stripping d'une CSI coupée entre deux writes ;
  • stripping OSC terminé par BEL/ST.

Intégration runtime global

Le test global vérifie désormais :

  1. initialisation silencieuse sans sink ;
  2. hot reload console non bloquante ;
  3. takeover KSP et silence sqlx ;
  4. erreur de création d'un file appender sur un chemin invalide ;
  5. conservation des settings précédents après cet échec ;
  6. hot reload vers un fichier Never ;
  7. émission d'un message contenant des codes ANSI ;
  8. retrait du sink fichier par reload, donc drop/flush de son guard ;
  9. présence du message KSP dans le fichier ;
  10. absence des codes ANSI persistés ;
  11. absence du message externe sqlx ;
  12. présence du target et de la source ;
  13. lecture de la statistique cumulée ;
  14. refus d'un second initialize().

La saturation déterministe avec une queue artificiellement petite est reportée à pre.005, où un writer de test injecté pourra être utilisé sans rendre la capacité de queue publique dans LoggingSettings.

Fichiers ajoutés

  • crates/ksp-logging-lib/src/writer.rs
  • crates/ksp-logging-lib/unit_tests/writer.rs
  • deltas/0.1.2/pre.004.md

Fichiers modifiés

  • Cargo.toml
  • crates/ksp-logging-lib/Cargo.toml
  • crates/ksp-logging-lib/src/error.rs
  • crates/ksp-logging-lib/src/lib.rs
  • crates/ksp-logging-lib/src/runtime.rs
  • crates/ksp-logging-lib/unit_tests/runtime.rs
  • crates/ksp-logging-lib/tests/runtime.rs
  • crates/ksp-logging-lib/tests/public_api.rs
  • docs/plans/004-V0_1_2_LOGGING_FOUNDATION_PLAN.md

Validations exécutées pendant la préparation

  • revérification documentaire officielle de tracing-appender 0.2.5 ;
  • vérification de la sémantique lossy de NonBlockingBuilder ;
  • vérification de WorkerGuard et ErrorCounter::dropped_lines() ;
  • vérification du builder fallible de RollingFileAppender ;
  • contrôle TOML des manifests ;
  • contrôle des headers file: / version: ;
  • contrôle de la centralisation de tracing-appender sous [workspace.dependencies] ;
  • contrôle que le code production ajouté n'utilise ni unwrap, ni expect, ni panic, ni opérateur ?, ni unsafe ;
  • contrôle que les usages directs de tracing-appender restent dans ksp-logging-lib.

Validations à exécuter dans le workspace

cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test --workspace
cargo tree -p ksp-logging-lib
cargo tree -p ksp-logging-lib -d
cargo tree -p ksp-logging-lib -e features

Aucune validation Cargo non exécutable dans l'environnement de préparation n'est déclarée réussie.

Suite

Après validation de pre.004, passer à 0.1.2-pre.005 :

  • concurrence/reloads répétés ;
  • saturation déterministe et dropped lines ;
  • audits de façade et usages directs de la stack tracing ;
  • audits Cargo/features/doublons ;
  • mesure grossière de l'overhead du reload/runtime ;
  • compléments de tests et documentation de crate avant la tranche finale.