You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Framework code reaches logging through Serilog's static Log, which pins the
project to one logger implementation and leaks Serilog types outward. Introduce
Microsoft.Extensions.Logging.ILogger as the abstraction in front of it, keeping
Serilog as the provider and the pipeline itself untouched.
AddFalloutLogging registers the abstraction over the pipeline and nothing else,
so any container can call it any number of times. Configuring the pipeline stays
separate because Logging.Configure is not idempotent: it reassigns Serilog's
Log.Logger on every call, and with no build it installs a pipeline with no file
sinks, no host sink and no filter, wiping out whatever a previous caller had set
up. BuildManager.Execute runs Configure explicitly, just before it builds the
provider.
The registration deliberately avoids services.AddLogging, which would install
MEL's own filter pipeline with an Information default -- a second level authority
that would drop trace and debug records before Serilog saw them, displacing
Logging.LevelSwitch.
ILogger<T> and ILogger are transient, not singleton. Logger<T> binds its inner
logger in its constructor, so a singleton would pin every consumer to whichever
pipeline was current at the first resolution -- the same failure Logging.Logger
stays uncached to avoid. ILoggerFactory stays a singleton because it is left
unbound and pins nothing. Transient does not rescue a component that holds a
logger across a pipeline swap, so that remaining constraint is documented at the
registration and on CreateSerilogLoggerFactory.
BuildManager.Execute now owns a per-run composition root and feeds the resolved
factory to a static facade on Logging, so the ~85 Log.* call sites and the static
build engine are unchanged. The provider is declared outside the try so it
survives into Finish(), but built inside it so a configuration failure still
returns the same exit code as before.
The seam is internal: it is framework foundation, not public surface yet. Nothing
in the public API changes and no output changes.
docs/dependencies.md gains rows for Serilog.Extensions.Logging,
Microsoft.Extensions.Logging.Abstractions and
Microsoft.Extensions.DependencyInjection. The DI row notes that Fallout.Build is
consumer-facing, so every consumer now pulls the container transitively.
First of the additive PRs in #428.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|`Microsoft.Extensions.DependencyInjection`| DI container for the per-run composition root that wires the logging seam ([#428](https://github.com/Fallout-build/Fallout/issues/428)) |`Fallout.Build`. Note the footprint: `Fallout.Build` is consumer-facing, so every consumer now pulls the container transitively. Deliberate, not accidental. It currently serves one internal composition root, and the plugin foundation ([milestone #6](https://github.com/Fallout-build/Fallout/milestone/6)) is what will use it more widely. |
|`Microsoft.SourceLink.GitHub`| Source-link symbols into published nupkgs so debuggers can step into Fallout | All packable libs |
20
21
|`Nerdbank.GitVersioning`| Build-time semver derived from git history | All packable libs |
@@ -27,6 +28,8 @@ Central package versions are pinned in `Directory.Packages.props`; this page lin
27
28
|---|---|
28
29
|`Serilog` + `Sinks.Console` + `Sinks.File`| The logging framework. All `Log.Information/Warning/Error` calls route through this. |
29
30
|`Serilog.Formatting.Compact` (+ `.Reader`) | Structured JSON log format for machine-readable logs |
31
+
|`Serilog.Extensions.Logging`| Serilog provider for `Microsoft.Extensions.Logging`. Backs the `ILogger` seam in `Fallout.Build`, so framework code logs against the abstraction while Serilog stays the provider. |
32
+
|`Microsoft.Extensions.Logging.Abstractions`| The `ILogger` / `ILoggerFactory` abstraction itself. Abstractions only, no implementation and no filter pipeline. |
0 commit comments