v0.1.3-pre.005
This commit is contained in:
313
deltas/0.1.3/pre.005.md
Normal file
313
deltas/0.1.3/pre.005.md
Normal file
@@ -0,0 +1,313 @@
|
||||
<!-- file: deltas/0.1.3/pre.005.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.1.3-pre.005
|
||||
|
||||
## Base requise
|
||||
|
||||
Livraison précédente validée :
|
||||
|
||||
```text
|
||||
0.1.3-pre.004
|
||||
```
|
||||
|
||||
Version technique de cette base :
|
||||
|
||||
```text
|
||||
workspace.package.version = "0.1.3-pre.4"
|
||||
Cargo.toml header version = 44
|
||||
```
|
||||
|
||||
Validations utilisateur de `pre.004` exécutées le 2026-08-15 :
|
||||
|
||||
```text
|
||||
cargo fmt --all OK
|
||||
cargo check --workspace OK
|
||||
cargo clippy --workspace --all-targets OK
|
||||
cargo test --workspace OK
|
||||
cargo tree -p ksp-logging-lib OK
|
||||
cargo tree -p ksp-logging-lib -d OK — aucune duplication
|
||||
cargo tree -p ksp-logging-lib -e features OK
|
||||
```
|
||||
|
||||
## Objet de pre.005
|
||||
|
||||
Cette tranche active le runtime multi-sink derrière les contrats publics stabilisés en `pre.004`, mais reste bornée aux dimensions de routing directement portées par les métadonnées des events/spans :
|
||||
|
||||
```text
|
||||
level
|
||||
target
|
||||
```
|
||||
|
||||
Le routing par champ structuré `domain` est scindé en `pre.006` plutôt que d'être approximé ou assimilé au target.
|
||||
|
||||
## Multi-sink runtime
|
||||
|
||||
`RuntimeOutputs` possède maintenant :
|
||||
|
||||
```text
|
||||
console: Option<RuntimeOutput>
|
||||
files: Vec<RuntimeFileOutput>
|
||||
```
|
||||
|
||||
Tous les `FileSettings` actifs sont préparés et installés simultanément.
|
||||
|
||||
Chaque fichier conserve :
|
||||
|
||||
```text
|
||||
output_id
|
||||
WorkerGuard
|
||||
ErrorCounter
|
||||
```
|
||||
|
||||
Le lifecycle de hot reload reste celui stabilisé en `0.1.2` :
|
||||
|
||||
1. validation et préparation complète des nouvelles sorties ;
|
||||
2. swap du groupe de layers via le handle reload existant ;
|
||||
3. conservation des compteurs des sorties retirées ;
|
||||
4. destruction des anciens layers ;
|
||||
5. destruction des anciens guards/writers.
|
||||
|
||||
Un échec de préparation avant le swap laisse la configuration active intacte.
|
||||
|
||||
## Routing par output : level + target
|
||||
|
||||
Chaque formatter utilise désormais un `RouteMakeWriter` interne.
|
||||
|
||||
Lors de `make_writer_for(metadata)` :
|
||||
|
||||
- `OutputFilter.level` décide si le niveau est accepté ;
|
||||
- `OutputFilter.targets[]` accepte le wildcard `*` ou un préfixe de target KSP ;
|
||||
- un writer désactivé absorbe la sortie sans écrire dans le sink concerné.
|
||||
|
||||
Le takeover global existant reste distinct :
|
||||
|
||||
```text
|
||||
default_filter + TargetFilter[]
|
||||
↓
|
||||
groupe de sinks
|
||||
↓
|
||||
OutputFilter level/target propre à chaque sink
|
||||
```
|
||||
|
||||
Le routing par output ne transforme pas les layers en `Filtered` reloadables. La composition `Targets.and_then(output_layers)` stabilisée pendant `0.1.2` est conservée.
|
||||
|
||||
## Scission du routing `domain`
|
||||
|
||||
`domain` est un champ structuré déclaré par les callers, par exemple :
|
||||
|
||||
```rust
|
||||
ksp_logging_lib::info!(
|
||||
target: "ksp-config-lib",
|
||||
domain = "config",
|
||||
"configuration event"
|
||||
);
|
||||
```
|
||||
|
||||
Il n'est pas une propriété des métadonnées de target.
|
||||
|
||||
Pour respecter le budget de tranche et éviter une sémantique incorrecte, `pre.005` refuse explicitement un output **actif** dont :
|
||||
|
||||
```text
|
||||
domains != ["*"]
|
||||
```
|
||||
|
||||
Le refus utilise `logging.invalid_settings` avec le contexte :
|
||||
|
||||
```text
|
||||
runtime_contract = metadata-routing-before-domain-routing
|
||||
```
|
||||
|
||||
Les contrats publics de `pre.004` restent inchangés : un output désactivé peut déjà porter son futur filtre domain et `LoggingSettings::validate()` continue de le valider structurellement.
|
||||
|
||||
`pre.006` est insérée pour traiter :
|
||||
|
||||
- domain porté directement par un event ;
|
||||
- domain d'un span ;
|
||||
- héritage vers les events sans champ direct ;
|
||||
- spans imbriqués ;
|
||||
- lifecycle `SpanEvents` ;
|
||||
- interaction avec les quatre formats et plusieurs sinks.
|
||||
|
||||
## Formats runtime
|
||||
|
||||
Les quatre formats publics sont maintenant actifs :
|
||||
|
||||
```text
|
||||
Human
|
||||
Compact
|
||||
Pretty
|
||||
Json
|
||||
```
|
||||
|
||||
Le manifest racine active pour `tracing-subscriber` :
|
||||
|
||||
```toml
|
||||
features = ["fmt", "json", "ansi"]
|
||||
```
|
||||
|
||||
Aucune nouvelle dépendance directe n'est ajoutée au workspace.
|
||||
|
||||
## ANSI
|
||||
|
||||
La console applique désormais réellement `ConsoleSettings::ansi()` pour les formats humains.
|
||||
|
||||
Les fichiers restent construits derrière `StripAnsiWriter` et persistent sans ANSI.
|
||||
|
||||
La combinaison :
|
||||
|
||||
```text
|
||||
console.format = Json
|
||||
console.ansi = true
|
||||
```
|
||||
|
||||
est refusée par `LoggingSettings::validate()` afin de ne pas accepter une option qui serait sans effet.
|
||||
|
||||
## Compteurs par output fichier
|
||||
|
||||
La vue agrégée existante reste disponible :
|
||||
|
||||
```rust
|
||||
LoggingGuard::dropped_lines() -> DroppedLines
|
||||
```
|
||||
|
||||
avec :
|
||||
|
||||
```text
|
||||
console
|
||||
file
|
||||
total
|
||||
```
|
||||
|
||||
`pre.005` ajoute :
|
||||
|
||||
```rust
|
||||
LoggingGuard::dropped_file_lines(output_id: &str) -> Option<usize>
|
||||
```
|
||||
|
||||
Le compteur est cumulatif à travers les reloads pour un même `LoggingGuard` et un même `output_id`, y compris après retrait du sink.
|
||||
|
||||
Un `output_id` qui n'a jamais été actif retourne `None`.
|
||||
|
||||
## Tests
|
||||
|
||||
Les tests unitaires couvrent notamment :
|
||||
|
||||
- préparation de plusieurs fichiers simultanés ;
|
||||
- console ANSI + format Compact ;
|
||||
- fichiers Pretty et Json ;
|
||||
- refus explicite d'un domain spécifique ;
|
||||
- mapping des niveaux de routing ;
|
||||
- writer désactivé ;
|
||||
- rejet JSON + ANSI console ;
|
||||
- conservation des tests de takeover, rotation, saturation et span lifecycle.
|
||||
|
||||
Le test global runtime est étendu pour vérifier en un seul subscriber global :
|
||||
|
||||
- échec transactionnel d'une configuration domain non encore supportée ;
|
||||
- quatre fichiers simultanés ;
|
||||
- formats Human, Compact, Pretty et Json ;
|
||||
- routing indépendant par target et niveau ;
|
||||
- silence des targets externes ;
|
||||
- stripping ANSI fichier ;
|
||||
- counters par `output_id` après retrait des sinks ;
|
||||
- hot reload concurrent existant ;
|
||||
- impossibilité d'une seconde initialisation globale.
|
||||
|
||||
## Plan de release regranularisé
|
||||
|
||||
La scission explicite décale le reste du cycle :
|
||||
|
||||
```text
|
||||
pre.005 Logging : runtime multi-sink + level/target/formats
|
||||
pre.006 Logging : routing structuré domain
|
||||
pre.007 JSON/JSON Schema + std.logging.json
|
||||
pre.008 globals + profils + default_profile
|
||||
pre.009 compositions génériques par file_id
|
||||
pre.010 .env + process env + resolver ${...}
|
||||
pre.011 sensibilité + real/safe/provenance
|
||||
pre.012 adapter Config -> Logging
|
||||
pre.013 management + persistence JSON/.env
|
||||
pre.014 ownership audits + robustesse
|
||||
pre.015 clôture
|
||||
```
|
||||
|
||||
Le schema `std.logging.schema.json` n'est donc pas figé avant validation du routing domain.
|
||||
|
||||
## Version technique
|
||||
|
||||
La prerelease devient :
|
||||
|
||||
```text
|
||||
workspace.package.version = "0.1.3-pre.5"
|
||||
```
|
||||
|
||||
Le manifest racine devient :
|
||||
|
||||
```text
|
||||
# version: 45
|
||||
```
|
||||
|
||||
## Fichier ajouté
|
||||
|
||||
```text
|
||||
deltas/0.1.3/pre.005.md
|
||||
```
|
||||
|
||||
## Fichiers modifiés
|
||||
|
||||
```text
|
||||
Cargo.toml
|
||||
crates/ksp-logging-lib/README.md
|
||||
crates/ksp-logging-lib/TODO.md
|
||||
crates/ksp-logging-lib/USAGE.md
|
||||
crates/ksp-logging-lib/src/lib.rs
|
||||
crates/ksp-logging-lib/src/runtime.rs
|
||||
crates/ksp-logging-lib/src/settings.rs
|
||||
crates/ksp-logging-lib/src/writer.rs
|
||||
crates/ksp-logging-lib/tests/public_api.rs
|
||||
crates/ksp-logging-lib/tests/runtime.rs
|
||||
crates/ksp-logging-lib/unit_tests/runtime.rs
|
||||
crates/ksp-logging-lib/unit_tests/settings.rs
|
||||
crates/ksp-logging-lib/unit_tests/writer.rs
|
||||
docs/plans/000-README.md
|
||||
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
|
||||
docs/plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md
|
||||
```
|
||||
|
||||
## Hors scope confirmé
|
||||
|
||||
Cette tranche n'implémente pas :
|
||||
|
||||
- le routing runtime par champ structuré `domain` ;
|
||||
- JSON Config ou JSON Schema ;
|
||||
- `std.logging.json` ;
|
||||
- profils/composites Config ;
|
||||
- `.env` ou interpolation ;
|
||||
- secrets/redaction Config ;
|
||||
- modification de `ksp-config-lib` ;
|
||||
- rotation par taille/rétention/compression.
|
||||
|
||||
## Validations à exécuter par l'utilisateur
|
||||
|
||||
```bash
|
||||
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
|
||||
```
|
||||
|
||||
Les commandes Cargo ne sont pas déclarées réussies dans ce delta tant qu'elles n'ont pas été exécutées sur l'environnement utilisateur.
|
||||
|
||||
## Suite
|
||||
|
||||
Après validation de cette tranche :
|
||||
|
||||
```text
|
||||
0.1.3-pre.006 — ksp-logging-lib : routing structuré domain
|
||||
```
|
||||
|
||||
Cette tranche devra fermer la dernière dimension du contrat `OutputFilter` avant l'introduction de `std.logging.schema.json`.
|
||||
Reference in New Issue
Block a user