Skip to content

Commit cd8662f

Browse files
authored
Merge pull request #370 from nblumhardt/readme-updates
README and sample updates to match recent .NET hosting models
2 parents c862bfc + 92bc15a commit cd8662f

File tree

4 files changed

+87
-132
lines changed

4 files changed

+87
-132
lines changed

README.md

+24-39
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ Serilog logging for ASP.NET Core. This package routes ASP.NET Core log messages
44

55
With _Serilog.AspNetCore_ installed and configured, you can write log messages directly through Serilog or any `ILogger` interface injected by ASP.NET. All loggers will use the same underlying implementation, levels, and destinations.
66

7-
**.NET Framework** and .NET Core 2.x are supported by version 3.4.0 of this package. Recent versions of _Serilog.AspNetCore_ require .NET Core 3.x, .NET 5, or later.
7+
**Versioning:** This package tracks the versioning and target framework support of its
8+
[_Microsoft.Extensions.Hosting_](https://nuget.org/packages/Microsoft.Extensions.Hosting) dependency. Most users should choose the version of _Serilog.AspNetCore_ that matches
9+
their application's target framework. I.e. if you're targeting .NET 7.x, choose a 7.x version of _Serilog.AspNetCore_. If
10+
you're targeting .NET 8.x, choose an 8.x _Serilog.AspNetCore_ version, and so on.
811

912
### Instructions
1013

@@ -28,11 +31,9 @@ try
2831
Log.Information("Starting web application");
2932

3033
var builder = WebApplication.CreateBuilder(args);
31-
32-
builder.Host.UseSerilog(); // <-- Add this line
34+
builder.Services.AddSerilog(); // <-- Add this line
3335
3436
var app = builder.Build();
35-
3637
app.MapGet("/", () => "Hello World!");
3738

3839
app.Run();
@@ -47,23 +48,21 @@ finally
4748
}
4849
```
4950

50-
The `builder.Host.UseSerilog()` call will redirect all log events through your Serilog pipeline.
51+
The `builder.Services.AddSerilog()` call will redirect all log events through your Serilog pipeline.
5152

5253
**Finally**, clean up by removing the remaining configuration for the default logger, including the `"Logging"` section from _appsettings.*.json_ files (this can be replaced with [Serilog configuration](https://github.com/serilog/serilog-settings-configuration) as shown in [the _Sample_ project](https://github.com/serilog/serilog-aspnetcore/blob/dev/samples/Sample/Program.cs), if required).
5354

5455
That's it! With the level bumped up a little you will see log output resembling:
5556

5657
```
57-
[22:14:44.646 DBG] RouteCollection.RouteAsync
58-
Routes:
59-
Microsoft.AspNet.Mvc.Routing.AttributeRoute
60-
{controller=Home}/{action=Index}/{id?}
61-
Handled? True
62-
[22:14:44.647 DBG] RouterMiddleware.Invoke
63-
Handled? True
64-
[22:14:45.706 DBG] /lib/jquery/jquery.js not modified
65-
[22:14:45.706 DBG] /css/site.css not modified
66-
[22:14:45.741 DBG] Handled. Status code: 304 File: /css/site.css
58+
[12:01:43 INF] Starting web application
59+
[12:01:44 INF] Now listening on: http://localhost:5000
60+
[12:01:44 INF] Application started. Press Ctrl+C to shut down.
61+
[12:01:44 INF] Hosting environment: Development
62+
[12:01:44 INF] Content root path: serilog-aspnetcore/samples/Sample
63+
[12:01:47 WRN] Failed to determine the https port for redirect.
64+
[12:01:47 INF] Hello, world!
65+
[12:01:47 INF] HTTP GET / responded 200 in 95.0581 ms
6766
```
6867

6968
**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()`.
@@ -97,12 +96,16 @@ Or [as JSON](https://github.com/serilog/serilog-formatting-compact):
9796
}
9897
```
9998

100-
To enable the middleware, first change the minimum level for `Microsoft.AspNetCore` to `Warning` in your logger configuration or _appsettings.json_ file:
99+
To enable the middleware, first change the minimum level for the noisy ASP.NET Core log sources to `Warning` in your logger configuration or _appsettings.json_ file:
101100

102101
```csharp
103-
.MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
102+
.MinimumLevel.Override("Microsoft.AspNetCore.Hosting", LogEventLevel.Warning)
103+
.MinimumLevel.Override("Microsoft.AspNetCore.Mvc", LogEventLevel.Warning)
104+
.MinimumLevel.Override("Microsoft.AspNetCore.Routing", LogEventLevel.Warning)
104105
```
105106

107+
> **Tip:** add `{SourceContext}` to your console logger's output template to see the names of loggers; this can help track down the source of a noisy log event to suppress.
108+
106109
Then, in your application's _Program.cs_, add the middleware with `UseSerilogRequestLogging()`:
107110

108111
```csharp
@@ -187,11 +190,11 @@ Log.Logger = new LoggerConfiguration()
187190
.CreateBootstrapLogger(); // <-- Change this line!
188191
```
189192

190-
Then, pass a callback to `UseSerilog()` that creates the final logger:
193+
Then, pass a callback to `AddSerilog()` that creates the final logger:
191194

192195
```csharp
193-
builder.Host.UseSerilog((context, services, configuration) => configuration
194-
.ReadFrom.Configuration(context.Configuration)
196+
builder.Services.AddSerilog((services, lc) => lc
197+
.ReadFrom.Configuration(builder.Configuration)
195198
.ReadFrom.Services(services)
196199
.Enrich.FromLogContext()
197200
.WriteTo.Console());
@@ -201,7 +204,7 @@ It's important to note that the final logger **completely replaces** the bootstr
201204

202205
#### Consuming `appsettings.json` configuration
203206

204-
**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).
207+
**Using two-stage initialization**, insert the `ReadFrom.Configuration(builder.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).
205208

206209
#### Injecting services into enrichers and sinks
207210

@@ -213,20 +216,6 @@ It's important to note that the final logger **completely replaces** the bootstr
213216
* `ILogEventSink`
214217
* `LoggingLevelSwitch`
215218

216-
#### Enabling `Microsoft.Extensions.Logging.ILoggerProvider`s
217-
218-
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()`.
219-
220-
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.
221-
222-
To have Serilog pass events to providers, **using two-stage initialization** as above, pass `writeToProviders: true` in the call to `UseSerilog()`:
223-
224-
```csharp
225-
builder.Host.UseSerilog(
226-
(hostingContext, services, loggerConfiguration) => /* snip! */,
227-
writeToProviders: true)
228-
```
229-
230219
### JSON output
231220

232221
The `Console()`, `Debug()`, and `File()` sinks all support JSON-formatted output natively, via the included _Serilog.Formatting.Compact_ package.
@@ -286,7 +275,3 @@ using (LogContext.PushProperty("OperationType", "update"))
286275
// UserId and OperationType are set for all logging events in these brackets
287276
}
288277
```
289-
290-
### Versioning
291-
292-
This package tracks the versioning and target framework support of its (indirect) [_Microsoft.Extensions.Hosting_](https://nuget.org/packages/Microsoft.Extensions.Hosting) dependency.

samples/Sample/Program.cs

+60-38
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,69 @@
11
using Serilog;
2+
using Serilog.Events;
23
using Serilog.Templates;
4+
using Serilog.Templates.Themes;
35

4-
namespace Sample;
6+
// The initial "bootstrap" logger is able to log errors during start-up. It's completely replaced by the
7+
// logger configured in `UseSerilog()` below, once configuration and dependency-injection have both been
8+
// set up successfully.
9+
Log.Logger = new LoggerConfiguration()
10+
.WriteTo.Console()
11+
.CreateBootstrapLogger();
512

6-
public static class Program
13+
Log.Information("Starting up!");
14+
15+
try
716
{
8-
public static int Main(string[] args)
17+
var builder = WebApplication.CreateBuilder(args);
18+
19+
builder.Services.AddSerilog((services, lc) => lc
20+
.ReadFrom.Configuration(builder.Configuration)
21+
.ReadFrom.Services(services)
22+
.Enrich.FromLogContext()
23+
.WriteTo.Console(new ExpressionTemplate(
24+
// Include trace and span ids when present.
25+
"[{@t:HH:mm:ss} {@l:u3}{#if @tr is not null} ({substring(@tr,0,4)}:{substring(@sp,0,4)}){#end}] {@m}\n{@x}",
26+
theme: TemplateTheme.Code)));
27+
28+
builder.Services.AddControllersWithViews();
29+
30+
await using var app = builder.Build();
31+
32+
// Configure the HTTP request pipeline.
33+
if (!app.Environment.IsDevelopment())
934
{
10-
// The initial "bootstrap" logger is able to log errors during start-up. It's completely replaced by the
11-
// logger configured in `UseSerilog()` below, once configuration and dependency-injection have both been
12-
// set up successfully.
13-
Log.Logger = new LoggerConfiguration()
14-
.WriteTo.Console()
15-
.CreateBootstrapLogger();
16-
17-
Log.Information("Starting up!");
18-
19-
try
20-
{
21-
CreateHostBuilder(args).Build().Run();
22-
23-
Log.Information("Stopped cleanly");
24-
return 0;
25-
}
26-
catch (Exception ex)
27-
{
28-
Log.Fatal(ex, "An unhandled exception occurred during bootstrapping");
29-
return 1;
30-
}
31-
finally
32-
{
33-
Log.CloseAndFlush();
34-
}
35+
app.UseExceptionHandler("/Home/Error");
36+
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
37+
app.UseHsts();
3538
}
39+
40+
// Write streamlined request completion events, instead of the more verbose ones from the framework.
41+
// To use the default framework request logging instead, remove this line and set the "Microsoft"
42+
// level in appsettings.json to "Information".
43+
app.UseSerilogRequestLogging();
44+
45+
app.UseHttpsRedirection();
46+
app.UseStaticFiles();
47+
48+
app.UseRouting();
49+
50+
app.UseAuthorization();
51+
52+
app.MapControllerRoute(
53+
name: "default",
54+
pattern: "{controller=Home}/{action=Index}/{id?}");
3655

37-
public static IHostBuilder CreateHostBuilder(string[] args) =>
38-
Host.CreateDefaultBuilder(args)
39-
.UseSerilog((context, services, configuration) => configuration
40-
.ReadFrom.Configuration(context.Configuration)
41-
.ReadFrom.Services(services)
42-
.Enrich.FromLogContext()
43-
.WriteTo.Console(new ExpressionTemplate(
44-
// Include trace and span ids when present.
45-
"[{@t:HH:mm:ss} {@l:u3}{#if @tr is not null} ({substring(@tr,0,4)}:{substring(@sp,0,4)}){#end}] {@m}\n{@x}")))
46-
.ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>());
56+
await app.RunAsync();
57+
58+
Log.Information("Stopped cleanly");
59+
return 0;
60+
}
61+
catch (Exception ex)
62+
{
63+
Log.Fatal(ex, "An unhandled exception occurred during bootstrapping");
64+
return 1;
65+
}
66+
finally
67+
{
68+
Log.CloseAndFlush();
4769
}

samples/Sample/Startup.cs

-53
This file was deleted.

samples/Sample/appsettings.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
"MinimumLevel": {
44
"Default": "Information",
55
"Override": {
6-
"Microsoft": "Warning",
7-
"Microsoft.Hosting.Lifetime": "Information"
6+
"Microsoft.AspNetCore.Mvc": "Warning",
7+
"Microsoft.AspNetCore.Routing": "Warning",
8+
"Microsoft.AspNetCore.Hosting": "Warning"
89
}
910
},
1011
"WriteTo": [

0 commit comments

Comments
 (0)