Skip to content

Commit 17fa68c

Browse files
committed
netstandard2.1 only, update to Serilog.Extensions.Hosting 4.0.0 to pull in CreateBootstrapLogger(), one sample (showing two-stage intialization), simplified README
1 parent 2857be8 commit 17fa68c

File tree

120 files changed

+1470
-40572
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

120 files changed

+1470
-40572
lines changed

README.md

+48-35
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ public class Program
2222
public static int Main(string[] args)
2323
{
2424
Log.Logger = new LoggerConfiguration()
25-
.MinimumLevel.Debug()
2625
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
2726
.Enrich.FromLogContext()
2827
.WriteTo.Console()
@@ -81,7 +80,7 @@ That's it! With the level bumped up a little you will see log output resembling:
8180

8281
**Tip:** to see Serilog output in the Visual Studio output window when running under IIS, either select _ASP.NET Core Web Server_ from the _Show output from_ drop-down list, or replace `WriteTo.Console()` in the logger configuration with `WriteTo.Debug()`.
8382

84-
A more complete example, showing `appsettings.json` configuration, can be found in [the sample project here](https://github.com/serilog/serilog-aspnetcore/tree/dev/samples/EarlyInitializationSample).
83+
A more complete example, including `appsettings.json` configuration, can be found in [the sample project here](https://github.com/serilog/serilog-aspnetcore/tree/dev/samples/Sample).
8584

8685
### Request logging
8786

@@ -188,59 +187,73 @@ app.UseSerilogRequestLogging(options =>
188187
});
189188
```
190189

191-
### Inline initialization
190+
### Two-stage initialization
192191

193-
You can alternatively configure Serilog inline, in `BuildWebHost()`, using a delegate as shown below:
192+
The example at the top of this page shows how to configure Serilog immediately when the application starts. This has the benefit of catching and reporting exceptions thrown during set-up of the ASP.NET Core host.
194193

195-
```csharp
196-
.UseSerilog((hostingContext, services, loggerConfiguration) => loggerConfiguration
197-
.ReadFrom.Configuration(hostingContext.Configuration)
198-
.Enrich.FromLogContext()
199-
.WriteTo.Console())
200-
```
194+
The downside of initializing Serilog first is that services from the ASP.NET Core host, including the `appsettings.json` configuration and dependency injection, aren't available yet.
201195

202-
This has the advantage of making a service provider and the `hostingContext`'s `Configuration` object available for [configuration of the logger](https://github.com/serilog/serilog-settings-configuration), but at the expense of losing `Exception`s raised earlier in program startup.
196+
To address this, Serilog supports two-stage initialization. An initial "bootstrap" logger is configured immediately when the program starts, and this is replaced by the fully-configured logger once the host has loaded.
203197

204-
If this method is used, `Log.Logger` is assigned implicitly, and closed when the app is shut down.
198+
To use this technique, first replace the initial `CreateLogger()` call with `CreateBoostrapLogger()`:
205199

206-
A complete example, showing this approach, can be found in [the _InlineIntializationSample_ project](https://github.com/serilog/serilog-aspnetcore/tree/dev/samples/InlineInitializationSample).
200+
```csharp
201+
using Serilog;
207202

208-
### Enabling `Microsoft.Extensions.Logging.ILoggerProvider`s
203+
public class Program
204+
{
205+
public static int Main(string[] args)
206+
{
207+
Log.Logger = new LoggerConfiguration()
208+
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
209+
.Enrich.FromLogContext()
210+
.WriteTo.Console()
211+
.CreateBootstrapLogger(); <-- this line!
212+
```
209213

210-
Serilog sends events to outputs called _sinks_, that implement Serilog's `ILogEventSink` interface, and are added to the logging pipeline using `WriteTo`. _Microsoft.Extensions.Logging_ has a similar concept called _providers_, and these implement `ILoggerProvider`. Providers are what the default logging configuration creates under the hood through methods like `AddConsole()`.
214+
Then, pass a callback to `UseSerilog()` that creates the final logger:
211215

212-
By default, Serilog ignores providers, since there are usually equivalent Serilog sinks available, and these work more efficiently with Serilog's pipeline. If provider support is needed, it can be optionally enabled.
216+
```csharp
217+
public static IHostBuilder CreateHostBuilder(string[] args) =>
218+
Host.CreateDefaultBuilder(args)
219+
.UseSerilog((context, services, configuration) => configuration
220+
.ReadFrom.Configuration(context.Configuration)
221+
.ReadFrom.Services(services)
222+
.Enrich.FromLogContext()
223+
.WriteTo.Console())
224+
.ConfigureWebHostDefaults(webBuilder =>
225+
{
226+
webBuilder.UseStartup<Startup>();
227+
});
228+
```
213229

214-
**Using the recommended configuration:**
230+
It's important to note that the final logger **completely replaces** the bootstrap logger: if you want both to log to the console, for instance, you'll need to specify `WriteTo.Console()` in both places, as the example shows.
215231

216-
In the recommended configuration (in which startup exceptions are caught and logged), first create a `LoggerProviderCollection` in a static field in _Program.cs_:
232+
#### Consuming `appsettings.json` configuration
217233

218-
```csharp
219-
// using Serilog.Extensions.Logging;
220-
static readonly LoggerProviderCollection Providers = new LoggerProviderCollection();
221-
```
234+
**Using two-stage initialization**, insert the `ReadFrom.Configuration(context.Configuration)` call shown in the example above. The JSON configuration syntax is documented in [the _Serilog.Settings.Configuration_ README](https://github.com/serilog/serilog-settings-configuration)/
222235
223-
Next, add `WriteTo.Providers()` to the logger configuration:
236+
#### Injecting services into enrichers and sinks
224237

225-
```csharp
226-
.WriteTo.Providers(Providers)
227-
```
238+
**Using two-stage initialization**, insert the `ReadFrom.Services(services)` call shown in the example above. The `ReadFrom.Services()` call will configure the logging pipeline with any registred implementations of the following services:
228239

229-
Finally, pass the provider collection into `UseSerilog()`:
240+
* `IDestructuringPolicy`
241+
* `ILogEventEnricher`
242+
* `ILogEventFilter`
243+
* `ILogEventSink`
244+
* `LoggingLevelSwitch`
230245

231-
```csharp
232-
.UseSerilog(providers: Providers)
233-
```
246+
#### Enabling `Microsoft.Extensions.Logging.ILoggerProvider`s
234247

235-
Providers registered in _Startup.cs_ with `AddLogging()` will then receive events from Serilog.
248+
Serilog sends events to outputs called _sinks_, that implement Serilog's `ILogEventSink` interface, and are added to the logging pipeline using `WriteTo`. _Microsoft.Extensions.Logging_ has a similar concept called _providers_, and these implement `ILoggerProvider`. Providers are what the default logging configuration creates under the hood through methods like `AddConsole()`.
236249

237-
**Using inline initialization:**
250+
By default, Serilog ignores providers, since there are usually equivalent Serilog sinks available, and these work more efficiently with Serilog's pipeline. If provider support is needed, it can be optionally enabled.
238251

239-
If [inline initialization](#inline-initialization) is used, providers can be enabled by adding `writeToProviders: true` to the `UseSerilog()` method call:
252+
To have Serilog pass events to providers, **using two-stage initialization** as above, pass `writeToProviders: true` in the call to `UseSerilog()`:
240253

241254
```csharp
242255
.UseSerilog(
243-
(hostingContext, loggerConfiguration) => /* snip! */,
256+
(hostingContext, services, loggerConfiguration) => /* snip! */,
244257
writeToProviders: true)
245258
```
246259

@@ -278,7 +291,7 @@ The Azure Diagnostic Log Stream ships events from any files in the `D:\home\LogF
278291

279292
### Pushing properties to the `ILogger<T>`
280293

281-
If you want to add extra properties to all logevents in a specific part of your code, you can add them to the **`ILogger<T>`** in **Microsoft.Extensions.Logging** with the following code. For this code to work, make sure you have added the `.Enrich.FromLogContext()` to the `.UseSerilog(...)` statement, as specified in the samples above.
294+
If you want to add extra properties to all log events in a specific part of your code, you can add them to the **`ILogger<T>`** in **Microsoft.Extensions.Logging** with the following code. For this code to work, make sure you have added the `.Enrich.FromLogContext()` to the `.UseSerilog(...)` statement, as specified in the samples above.
282295

283296
```csharp
284297
// Microsoft.Extensions.Logging ILogger<T>

global.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"sdk": {
33
"allowPrerelease": false,
4-
"version": "3.1.201",
4+
"version": "5.0.102",
55
"rollForward": "latestFeature"
66
}
77
}

samples/EarlyInitializationSample/EarlyInitializationSample.csproj

-11
This file was deleted.

samples/EarlyInitializationSample/Program.cs

-56
This file was deleted.

samples/EarlyInitializationSample/Startup.cs

-45
This file was deleted.

samples/EarlyInitializationSample/Views/Home/Privacy.cshtml

-6
This file was deleted.

samples/EarlyInitializationSample/Views/Shared/Error.cshtml

-25
This file was deleted.

samples/EarlyInitializationSample/Views/Shared/_CookieConsentPartial.cshtml

-25
This file was deleted.

samples/EarlyInitializationSample/Views/Shared/_Layout.cshtml

-77
This file was deleted.

0 commit comments

Comments
 (0)