Skip to content

6.1.0 Release #310

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Nov 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<TreatWarningsAsErrors>True</TreatWarningsAsErrors>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>../../assets/Serilog.snk</AssemblyOriginatorKeyFile>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>
146 changes: 55 additions & 91 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,53 +18,38 @@ dotnet add package Serilog.AspNetCore

```csharp
using Serilog;
using Serilog.Events;

public class Program
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();

try
{
public static int Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.Enrich.FromLogContext()
.WriteTo.Console()
.CreateLogger();
Log.Information("Starting web application");

try
{
Log.Information("Starting web host");
CreateHostBuilder(args).Build().Run();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
return 1;
}
finally
{
Log.CloseAndFlush();
}
}
```
var builder = WebApplication.CreateBuilder(args);

builder.Host.UseSerilog(); // <-- Add this line

var app = builder.Build();

**Then**, add `UseSerilog()` to the Generic Host in `CreateHostBuilder()`.
app.MapGet("/", () => "Hello World!");

```csharp
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog() // <-- Add this line
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
app.Run();
}
catch (Exception ex)
{
Log.Fatal(ex, "Application terminated unexpectedly");
}
finally
{
Log.CloseAndFlush();
}
```

**Finally**, clean up by removing the remaining configuration for the default logger:
The `builder.Host.UseSerilog()` call will redirect all log events through your Serilog pipeline.

* Remove 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)
* Remove `UseApplicationInsights()` (this can be replaced with the [Serilog AI sink](https://github.com/serilog/serilog-sinks-applicationinsights), if required)
**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).

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

Expand Down Expand Up @@ -118,23 +103,14 @@ To enable the middleware, first change the minimum level for `Microsoft.AspNetCo
.MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
```

Then, in your application's _Startup.cs_, add the middleware with `UseSerilogRequestLogging()`:
Then, in your application's _Program.cs_, add the middleware with `UseSerilogRequestLogging()`:

```csharp
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}

app.UseSerilogRequestLogging(); // <-- Add this line

// Other app configuration
var app = builder.Build();

app.UseSerilogRequestLogging(); // <-- Add this line

// Other app configuration
```

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.)
Expand Down Expand Up @@ -204,31 +180,21 @@ To use this technique, first replace the initial `CreateLogger()` call with `Cre
using Serilog;
using Serilog.Events;

public class Program
{
public static int Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.Enrich.FromLogContext()
.WriteTo.Console()
.CreateBootstrapLogger(); // <-- Change this line!
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.Enrich.FromLogContext()
.WriteTo.Console()
.CreateBootstrapLogger(); // <-- Change this line!
```

Then, pass a callback to `UseSerilog()` that creates the final logger:

```csharp
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog((context, services, configuration) => configuration
.ReadFrom.Configuration(context.Configuration)
.ReadFrom.Services(services)
.Enrich.FromLogContext()
.WriteTo.Console())
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
builder.Host.UseSerilog((context, services, configuration) => configuration
.ReadFrom.Configuration(context.Configuration)
.ReadFrom.Services(services)
.Enrich.FromLogContext()
.WriteTo.Console());
```

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.
Expand Down Expand Up @@ -256,7 +222,7 @@ By default, Serilog ignores providers, since there are usually equivalent Serilo
To have Serilog pass events to providers, **using two-stage initialization** as above, pass `writeToProviders: true` in the call to `UseSerilog()`:

```csharp
.UseSerilog(
builder.Host.UseSerilog(
(hostingContext, services, loggerConfiguration) => /* snip! */,
writeToProviders: true)
```
Expand All @@ -276,23 +242,21 @@ To write newline-delimited JSON, pass a `CompactJsonFormatter` or `RenderedCompa
The Azure Diagnostic Log Stream ships events from any files in the `D:\home\LogFiles\` folder. To enable this for your app, add a file sink to your `LoggerConfiguration`, taking care to set the `shared` and `flushToDiskInterval` parameters:

```csharp
public static int Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.Enrich.FromLogContext()
.WriteTo.Console()
// Add this line:
.WriteTo.File(
System.IO.Path.Combine(Environment.GetEnvironmentVariable("HOME"), "LogFiles", "Application", "diagnostics.txt"),
rollingInterval: RollingInterval.Day,
fileSizeLimitBytes: 10 * 1024 * 1024,
retainedFileCountLimit: 2,
rollOnFileSizeLimit: true,
shared: true,
flushToDiskInterval: TimeSpan.FromSeconds(1))
.CreateLogger();
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.Enrich.FromLogContext()
.WriteTo.Console()
// Add this line:
.WriteTo.File(
System.IO.Path.Combine(Environment.GetEnvironmentVariable("HOME"), "LogFiles", "Application", "diagnostics.txt"),
rollingInterval: RollingInterval.Day,
fileSizeLimitBytes: 10 * 1024 * 1024,
retainedFileCountLimit: 2,
rollOnFileSizeLimit: true,
shared: true,
flushToDiskInterval: TimeSpan.FromSeconds(1))
.CreateLogger();
```

### Pushing properties to the `ILogger<T>`
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ deploy:
- provider: NuGet
skip_symbols: true
api_key:
secure: U7I8Skf+EcC7PiqvLWpSzPqNhCg03cqDOi4OtAkb+ZelMlQj1YoKDX8r1pdQzy7H
secure: JZt0dILdf7cKm+rCtxfAHFGefHJHUUtt8Imm+J3+LtqTeVKODNZ7nyLjrP+QGBk5
on:
branch: /^(main|dev)$/
- provider: GitHub
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"sdk": {
"allowPrerelease": false,
"version": "5.0.201",
"version": "6.0.401",
"rollForward": "latestFeature"
}
}
73 changes: 33 additions & 40 deletions samples/Sample/Controllers/HomeController.cs
Original file line number Diff line number Diff line change
@@ -1,47 +1,40 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Sample.Models;
using Serilog;

namespace Sample.Controllers
namespace Sample.Controllers;

public class HomeController : Controller
{
public class HomeController : Controller
static int _callCount;

readonly ILogger<HomeController> _logger;
readonly IDiagnosticContext _diagnosticContext;

public HomeController(ILogger<HomeController> logger, IDiagnosticContext diagnosticContext)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_diagnosticContext = diagnosticContext ?? throw new ArgumentNullException(nameof(diagnosticContext));
}

public IActionResult Index()
{
_logger.LogInformation("Hello, world!");

_diagnosticContext.Set("IndexCallCount", Interlocked.Increment(ref _callCount));

return View();
}

public IActionResult Privacy()
{
throw new InvalidOperationException("Something went wrong.");
}

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
static int _callCount;

readonly ILogger<HomeController> _logger;
readonly IDiagnosticContext _diagnosticContext;

public HomeController(ILogger<HomeController> logger, IDiagnosticContext diagnosticContext)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_diagnosticContext = diagnosticContext ?? throw new ArgumentNullException(nameof(diagnosticContext));
}

public IActionResult Index()
{
_logger.LogInformation("Hello, world!");

_diagnosticContext.Set("IndexCallCount", Interlocked.Increment(ref _callCount));

return View();
}

public IActionResult Privacy()
{
throw new InvalidOperationException("Something went wrong.");
}

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel {RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier});
}
return View(new ErrorViewModel {RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier});
}
}
}
11 changes: 4 additions & 7 deletions samples/Sample/Models/ErrorViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
using System;
namespace Sample.Models;

namespace Sample.Models
public class ErrorViewModel
{
public class ErrorViewModel
{
public string RequestId { get; set; }
public string? RequestId { get; set; }

public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
Loading