Skip to content

Commit 40672d3

Browse files
authored
Merge pull request #96 from serilog/readme-deps
README and dependency updates
2 parents a64500c + fff0984 commit 40672d3

File tree

5 files changed

+94
-21
lines changed

5 files changed

+94
-21
lines changed

README.md

Lines changed: 79 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
# Serilog.AspNetCore [![Build status](https://ci.appveyor.com/api/projects/status/4rscdto23ik6vm2r?svg=true)](https://ci.appveyor.com/project/serilog/serilog-aspnetcore) [![NuGet Version](http://img.shields.io/nuget/v/Serilog.AspNetCore.svg?style=flat)](https://www.nuget.org/packages/Serilog.AspNetCore/)
22

3+
Serilog logging for ASP.NET Core. This package routes ASP.NET Core log messages through Serilog, so you can get information about ASP.NET's internal operations written to the same Serilog sinks as your application events.
34

4-
Serilog logging for ASP.NET Core. This package routes ASP.NET Core log messages through Serilog, so you can get information about ASP.NET's internal operations logged to the same Serilog sinks as your application events.
5+
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.
56

67
### Instructions
78

89
**First**, install the _Serilog.AspNetCore_ [NuGet package](https://www.nuget.org/packages/Serilog.AspNetCore) into your app. You will need a way to view the log messages - _Serilog.Sinks.Console_ writes these to the console; there are [many more sinks available](https://www.nuget.org/packages?q=Tags%3A%22serilog%22) on NuGet.
910

10-
```powershell
11-
Install-Package Serilog.AspNetCore -DependencyVersion Highest
12-
Install-Package Serilog.Sinks.Console
11+
```shell
12+
dotnet add package Serilog.AspNetCore
13+
dotnet add package Serilog.Sinks.Console
1314
```
1415

1516
**Next**, in your application's _Program.cs_ file, configure Serilog first. A `try`/`catch` block will ensure any configuration issues are appropriately logged:
@@ -82,11 +83,82 @@ Tip: to see Serilog output in the Visual Studio output window when running under
8283

8384
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).
8485

85-
### Using the package
86+
### Request logging
8687

87-
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.
88+
The package includes middleware for smarter HTTP request logging. The default request logging implemented by ASP.NET Core is noisy, with multiple events emitted per request. The included middleware condenses these into a single event that carries method, path, status code, and timing information.
89+
90+
As text, this has a format like:
91+
92+
```
93+
[16:05:54 INF] HTTP GET / responded 200 in 227.3253 ms
94+
```
95+
96+
Or [as JSON](https://github.com/serilog/serilog-formatting-compact):
97+
98+
```json
99+
{
100+
"@t":"2019-06-26T06:05:54.6881162Z",
101+
"@mt":"HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms",
102+
"@r":["224.5185"],
103+
"RequestMethod":"GET",
104+
"RequestPath":"/",
105+
"StatusCode":200,
106+
"Elapsed":224.5185,
107+
"RequestId":"0HLNPVG1HI42T:00000001",
108+
"CorrelationId":null,
109+
"ConnectionId":"0HLNPVG1HI42T"
110+
}
111+
```
112+
113+
To enable the middleware, first change the minimum level for `Microsoft` to `Warning` in your logger configuration or _appsettings.json_ file:
114+
115+
```csharp
116+
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
117+
```
118+
119+
Then, in your application's _Startup.cs_, add the middleware with `UseSerilogRequestLogging()`:
120+
121+
```csharp
122+
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
123+
{
124+
if (env.IsDevelopment())
125+
{
126+
app.UseDeveloperExceptionPage();
127+
}
128+
else
129+
{
130+
app.UseExceptionHandler("/Home/Error");
131+
}
132+
133+
app.UseSerilogRequestLogging(); // <-- Add this line
134+
135+
// Other app configuration
136+
```
137+
138+
It's important that the `UseSerilogRequestLogging()` call appears _before_ handlers such as MVC. The middleware will not time or log components that appear before it in the pipeline. (This can be utilized to exclude noisy handlers from logging, such as `UseStaticFiles()`, by placing `UseSerilogRequestLogging()` after them.)
139+
140+
During request processing, additional properties can be attached to the completion event using `IDiagnosticContext.Set()`:
141+
142+
```csharp
143+
public class HomeController : Controller
144+
{
145+
readonly IDiagnosticContext _diagnosticContext;
146+
147+
public HomeController(IDiagnosticContext diagnosticContext)
148+
{
149+
_diagnosticContext = diagnosticContext ?? throw new ArgumentNullException(nameof(diagnosticContext));
150+
}
151+
152+
public IActionResult Index()
153+
{
154+
// The request completion event will carry this property
155+
_diagnosticContext.Set("CatalogLoadTime", 1423);
156+
157+
return View();
158+
}
159+
```
88160

89-
**Tip:** change the minimum level for `Microsoft` to `Warning` and plug in this [custom logging middleware](https://github.com/datalust/serilog-middleware-example/blob/master/src/Datalust.SerilogMiddlewareExample/Diagnostics/SerilogMiddleware.cs) to clean up request logging output and record more context around errors and exceptions.
161+
This pattern has the advantage of reducing the number of log events that need to be constructed, transmitted, and stored per HTTP request. Having many properties on the same event can also make correlation of request details and other data easier.
90162

91163
### Inline initialization
92164

samples/EarlyInitializationSample/Controllers/HomeController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public IActionResult Index()
2525
{
2626
_logger.LogInformation("Hello, world!");
2727

28-
_diagnosticContext.Add("IndexCallCount", Interlocked.Increment(ref _callCount));
28+
_diagnosticContext.Set("IndexCallCount", Interlocked.Increment(ref _callCount));
2929

3030
return View();
3131
}

samples/InlineInitializationSample/Controllers/HomeController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public IActionResult Index()
2525
{
2626
_logger.LogInformation("Hello, world!");
2727

28-
_diagnosticContext.Add("IndexCallCount", Interlocked.Increment(ref _callCount));
28+
_diagnosticContext.Set("IndexCallCount", Interlocked.Increment(ref _callCount));
2929

3030
return View();
3131
}

src/Serilog.AspNetCore/AspNetCore/RequestCompletionMiddleware.cs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
// limitations under the License.
1414

1515
using System;
16-
using System.Collections.Generic;
1716
using System.Diagnostics;
1817
using System.Linq;
1918
using System.Threading.Tasks;
@@ -30,7 +29,8 @@ class RequestLoggingMiddleware
3029
readonly RequestDelegate _next;
3130
readonly DiagnosticContext _diagnosticContext;
3231
readonly MessageTemplate _messageTemplate;
33-
readonly int _messageTemplatePlaceholderCount;
32+
33+
static readonly LogEventProperty[] NoProperties = new LogEventProperty[0];
3434

3535
public RequestLoggingMiddleware(RequestDelegate next, DiagnosticContext diagnosticContext, RequestLoggingOptions options)
3636
{
@@ -39,7 +39,6 @@ public RequestLoggingMiddleware(RequestDelegate next, DiagnosticContext diagnost
3939
_diagnosticContext = diagnosticContext ?? throw new ArgumentNullException(nameof(diagnosticContext));
4040

4141
_messageTemplate = new MessageTemplateParser().Parse(options.MessageTemplate);
42-
_messageTemplatePlaceholderCount = _messageTemplate.Tokens.OfType<PropertyToken>().Count();
4342
}
4443

4544
// ReSharper disable once UnusedMember.Global
@@ -75,16 +74,18 @@ bool LogCompletion(HttpContext httpContext, DiagnosticContextCollector collector
7574

7675
if (!Log.IsEnabled(level)) return false;
7776

78-
if (!collector.TryComplete(out var properties))
79-
properties = new List<LogEventProperty>();
77+
if (!collector.TryComplete(out var collectedProperties))
78+
collectedProperties = NoProperties;
8079

81-
properties.Capacity = properties.Count + _messageTemplatePlaceholderCount;
80+
// Last-in (correctly) wins...
81+
var properties = collectedProperties.Concat(new[]
82+
{
83+
new LogEventProperty("RequestMethod", new ScalarValue(httpContext.Request.Method)),
84+
new LogEventProperty("RequestPath", new ScalarValue(GetPath(httpContext))),
85+
new LogEventProperty("StatusCode", new ScalarValue(statusCode)),
86+
new LogEventProperty("Elapsed", new ScalarValue(elapsedMs))
87+
});
8288

83-
// Last-in (rightly) wins...
84-
properties.Add(new LogEventProperty("RequestMethod", new ScalarValue(httpContext.Request.Method)));
85-
properties.Add(new LogEventProperty("RequestPath", new ScalarValue(GetPath(httpContext))));
86-
properties.Add(new LogEventProperty("StatusCode", new ScalarValue(statusCode)));
87-
properties.Add(new LogEventProperty("Elapsed", new ScalarValue(elapsedMs)));
8889
var evt = new LogEvent(DateTimeOffset.Now, level, ex, _messageTemplate, properties);
8990
Log.Write(evt);
9091

src/Serilog.AspNetCore/Serilog.AspNetCore.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
<ItemGroup>
2626
<PackageReference Include="Serilog" Version="2.8.0" />
27-
<PackageReference Include="Serilog.Extensions.Hosting" Version="3.0.0-*" />
27+
<PackageReference Include="Serilog.Extensions.Hosting" Version="3.0.0-dev-00019" />
2828
<PackageReference Include="Serilog.Extensions.Logging" Version="3.0.0-*" />
2929
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.0.0" />
3030
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.0.0" />

0 commit comments

Comments
 (0)