Femur.Logging.Bootstrap
0.0.31
dotnet add package Femur.Logging.Bootstrap --version 0.0.31
NuGet\Install-Package Femur.Logging.Bootstrap -Version 0.0.31
<PackageReference Include="Femur.Logging.Bootstrap" Version="0.0.31" />
<PackageVersion Include="Femur.Logging.Bootstrap" Version="0.0.31" />
<PackageReference Include="Femur.Logging.Bootstrap" />
paket add Femur.Logging.Bootstrap --version 0.0.31
#r "nuget: Femur.Logging.Bootstrap, 0.0.31"
#:package Femur.Logging.Bootstrap@0.0.31
#addin nuget:?package=Femur.Logging.Bootstrap&version=0.0.31
#tool nuget:?package=Femur.Logging.Bootstrap&version=0.0.31
Femur.Logging.Bootstrap
A lightweight .NET library that enables logging during application startup, before the host is fully initialized.
The Problem
In .NET applications using the Generic Host (Host.CreateApplicationBuilder), logging typically isn't available until after the host is built. This creates a blind spot during critical startup phases:
var builder = Host.CreateApplicationBuilder(args);
// No logging available here!
builder.Services.AddHostedService<MyService>();
// Or here...
var host = builder.Build();
// Logging only works after this point
await host.RunAsync();
Femur.Logging.Bootstrap solves this by providing a standalone logger that works immediately and seamlessly transitions to your application's main logging infrastructure.
Features
- Early logging: Log during host configuration and startup validation
- Seamless integration: Bootstrap logger transitions cleanly into the main application host
- Zero duplication: Logging providers are shared between bootstrap and host - logs go to the same destination
- Proper disposal: Ensures logger providers are flushed on application shutdown
- OpenTelemetry support: Works with OpenTelemetry logging, tracing, and metrics
- Simple API: Minimal code changes to add bootstrap logging to existing applications
Installation
dotnet add package Femur.Logging.Bootstrap
Quick Start
using Femur.Logging.Bootstrap;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
// Create a bootstrap logger before anything else
using var logger = BootstrapLogger.Create<Program>(builder =>
{
builder.ClearProviders();
builder.AddConsole();
});
// Now you can log during startup!
logger.LogInformation("Starting application with bootstrapped logging.");
var builder = Host.CreateApplicationBuilder(args);
logger.LogInformation("Configuring services.");
// Transfer the bootstrap logger to the host
builder.Services.AddBootstrappedLogging(logger);
var host = builder.Build();
logger.LogInformation("Starting application.");
await host.RunAsync();
logger.LogInformation("Application stopped.");
How It Works
- Create:
BootstrapLogger.Create<T>()creates a standalone logger with your configured providers - Use: The logger works immediately - use it anywhere before host initialization
- Transfer:
AddBootstrappedLogging()transfers the logging infrastructure to your main host - Share: Both loggers write to the same providers - no duplication
The bootstrap logger's service provider is kept alive and shared with the main host, ensuring:
- Log messages from both stages appear in the same output
- OpenTelemetry traces and metrics are correlated correctly
- Logger providers are properly flushed on shutdown
Use Cases
Startup Validation
using var logger = BootstrapLogger.Create<Program>(builder =>
{
builder.AddConsole();
});
logger.LogInformation("Validating environment...");
if (!Directory.Exists("/required/path"))
{
logger.LogCritical("Required directory not found!");
return 2; // Exit with error code
}
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddBootstrappedLogging(logger);
// ... continue with host setup
Configuration Debugging
using var logger = BootstrapLogger.Create<Program>(builder =>
{
builder.AddConsole();
builder.SetMinimumLevel(LogLevel.Debug);
});
logger.LogDebug("Loading configuration from {Path}", configPath);
var builder = Host.CreateApplicationBuilder(args);
logger.LogDebug("Configuration sections: {Sections}",
string.Join(", ", builder.Configuration.AsEnumerable().Select(c => c.Key)));
builder.Services.AddBootstrappedLogging(logger);
// ... continue
OpenTelemetry Integration
using var logger = BootstrapLogger.Create<Program>(
builder =>
{
builder.AddOpenTelemetry(options =>
{
options.SetResourceBuilder(ResourceBuilder.CreateDefault()
.AddService("MyService"));
options.AddConsoleExporter();
});
},
services =>
{
// Register additional services needed by OpenTelemetry
services.AddSingleton(new ActivitySource("MyService"));
});
logger.LogInformation("Application starting with OpenTelemetry");
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddBootstrappedLogging(logger);
// Add tracing and metrics
builder.Services.AddOpenTelemetry()
.WithTracing(tracing => tracing
.AddSource("MyService")
.AddConsoleExporter())
.WithMetrics(metrics => metrics
.AddRuntimeInstrumentation()
.AddConsoleExporter());
var host = builder.Build();
await host.RunAsync();
Examples
This package includes two complete examples in the repository:
- BasicExample: Simple console application with bootstrap logging and a hosted service
- AdvancedExample: Production-ready patterns with OpenTelemetry, distributed tracing, error handling, and validation
API Reference
BootstrapLogger.Create<T>
Creates a new bootstrap logger with an explicit type parameter.
BootstrapLogger Create<T>(
Action<ILoggingBuilder> configure,
Action<IServiceCollection>? configureServices = null)
Parameters:
configure: Configure logging providers (Console, OpenTelemetry, etc.)configureServices: Optional callback to register additional services (e.g., ActivitySource for OpenTelemetry)
Returns: A BootstrapLogger that implements ILogger, IDisposable, and IAsyncDisposable
AddBootstrappedLogging
Extension method to transfer bootstrap logging to the host.
IServiceCollection AddBootstrappedLogging(
this IServiceCollection services,
BootstrapLogger logger)
Parameters:
services: The host's service collectionlogger: The bootstrap logger to transfer
Returns: The service collection for chaining
Integration with Femur.Hosting
If you're using the Femur.Hosting framework, bootstrap logging is built-in. The framework automatically creates a bootstrap logger with type discovery, uses it during startup, and seamlessly transfers it to your application's host:
using Femur.Hosting;
// The framework handles bootstrap logging automatically
var result = await ApplicationBuilder.Create(args)
.UseDefaultConsoleLogging() // Bootstrap logger is created here
.SkipConfiguration()
.ConfigureServices(services =>
{
services.AddHostedService<MyWorkerService>();
})
.SkipConfigureErrorHandlers()
.RunAsync();
return result;
The Femur.Hosting framework provides comprehensive error handling, graceful shutdown, and detailed logging throughout the application lifecycle, all built on top of this bootstrap logging infrastructure. Type discovery for logger categories is handled internally by the hosting framework.
Requirements
- .NET 8.0 or later (also supports .NET Standard 2.0)
- Microsoft.Extensions.Logging 8.0+
- Microsoft.Extensions.DependencyInjection 8.0+
- Femur.DependencyInjection (automatically included)
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Femur.DependencyInjection (>= 0.0.31)
- Microsoft.Extensions.DependencyInjection (>= 3.1.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 3.1.0)
- Microsoft.Extensions.Logging (>= 3.1.0)
- Microsoft.Extensions.Logging.Abstractions (>= 3.1.0)
- System.Memory (>= 4.6.3)
-
net10.0
- Femur.DependencyInjection (>= 0.0.31)
- Microsoft.Extensions.DependencyInjection (>= 10.0.2)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.2)
- Microsoft.Extensions.Logging (>= 10.0.2)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.2)
-
net8.0
- Femur.DependencyInjection (>= 0.0.31)
- Microsoft.Extensions.DependencyInjection (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Logging (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
-
net9.0
- Femur.DependencyInjection (>= 0.0.31)
- Microsoft.Extensions.DependencyInjection (>= 9.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Logging (>= 9.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Femur.Logging.Bootstrap:
| Package | Downloads |
|---|---|
|
Femur.Hosting
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.