Author : MD TAREQ HASSAN
Installing packages
Install-Package Serilog.AspNetCore
Serilog.AspNetCore
already has references to the following packages:
Install-Package Serilog.Settings.Configuration
Install-Package Serilog.Sinks.Console
Install-Package Serilog.Sinks.File
Install-Package Serilog.Formatting.Compact
Extra packages (if you want/need):
Install-Package Serilog.Sinks.Async
Install-Package Serilog.Enrichers.Environment
Install-Package Serilog.Enrichers.Process
Install-Package Serilog.Enrichers.Thread
appsettings json
appsettings.Development.json
appsettings.Production.json
{
"Serilog": {
"MinimumLevel": {
"Default": "Warning"
},
"Enrich": [
"FromLogContext"
],
"Properties": {
"Application": "HovermindApp"
},
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} <s:{SourceContext}>{NewLine}{Exception}",
"theme": "Serilog.Sinks.SystemConsole.Themes.SystemConsoleTheme::Literate, Serilog.Sinks.Console"
}
},
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "File",
"Args": {
"formatter": "Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact",
"path": "D:/home/LogFiles/Application/HovermindApp.ndjson",
"shared": "true",
"fileSizeLimitBytes": "1000000",
"rollOnFileSizeLimit": true,
"flushToDiskInterval": "1"
}
}
]
}
}
]
}
}
Logger initialization in Program class
- all settings are in
appsettings.json
& can be overriden by fluent api (some settings are not possible byappsettings.json
, those seeting are set by fluent api) - try/catch used to log application start-up exceptions
- Plugging into ASP.NET Core with
UseSerilog()
- Important: Serilog in ASP.NET Core 3 plugs into the generic host and not webBuilder
- https://github.com/serilog/serilog-aspnetcore
Program.cs
public class Program
{
public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
.AddEnvironmentVariables()
.Build();
public static int Main(string[] args)
{
Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(Configuration).CreateLogger();
try
{
Log.Information("Getting the motors running...");
CreateHostBuilder(args).Build().Run();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
return 1;
}
finally
{
Log.CloseAndFlush();
}
}
public static IHostBuilder CreateHostBuilder(string[] args){
// Serilog in ASP.NET Core 3 plugs into the generic host and not webBuilder
return Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder => {
webBuilder.UseStartup<Startup>();
})
.UseSerilog(); // <- Plug Serilog into the pipeline;
}
}
Another way:
public class Program
{
public static int Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args){
// Serilog in ASP.NET Core 3 plugs into the generic host and not webBuilder
return Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder => {
webBuilder.UseStartup<Startup>();
})
.UseSerilog((context, config) =>
{
config.ReadFrom.Configuration(context.Configuration);
})
}
}
Logging section in appsettings json
- Since Serilog is plugged into ASP.Net core, all logging will be done by Serilog
- Even if logging is done by
ILogger<T>
of ASP.Net core (by DI), logging will be done by Serilog - Logging section in
appsettings.json
will not be used by Serilog, so remove Logging section from allappsettings.json
(default, Development, Production etc.)
Logging in Controller
Using Dependency Injection
HomeController.cs
using Serilog;
public class HomeController : Controller
{
private ILogger<HomeController> _logger;
private static IFooService _fs;
public HomeController(ILogger<HomeController> logger, IFooService fs, ...)
{
_logger = logger;
_fs = fs;
// ... ... ...
}
public IActionResult Index()
{
var foo = new Foo { Id = 2, FooName = "FooTwo" };
_logger.Information("Object: {@FooMan}", foo); // @ : destructuring operator
return View();
}
}
Using static Log
HomeController.cs
using Serilog;
public class HomeController : Controller
{
private static IFooService _fs;
public HomeController(IFooService fs)
{
_fs = fs;
}
public IActionResult Index()
{
var foo = new Foo { Id = 2, FooName = "FooTwo" };
Log.Information("Object: {@FooMan}", foo); // @ : destructuring operator
return View();
}
}
seq sink
seq in docker: Running seq in docker
seq sink package installation
Install-Package Serilog.Sinks.Seq
configuration for seq in appsettings.json
{
"Serilog": {
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"Enrich": [
"FromLogContext"
],
"Properties": {
"Application": "HoverApp"
},
"WriteTo": [
// ... ... ...
{
"Name": "Seq",
"Args": {
"serverUrl": "http://localhost:5341",
"compact": true
}
}
]
}
}
Request logging
Serilog.AspNetCore
includes middleware for smarter HTTP request logging ( The default request logging implemented by ASP.NET Core is noisy, with multiple events emitted per request)UseSerilogRequestLogging()
=> plugs request logging middleware- It’s important that the UseSerilogRequestLogging() call appears before handlers such as MVC
- to exclude noisy handlers from logging, such as
UseStaticFiles()
, by placingUseSerilogRequestLogging()
after them - https://github.com/serilog/serilog-aspnetcore#request-logging
To enable the middleware, first change the minimum level for Microsoft.AspNetCore
to Warning
{
"Serilog": {
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Microsoft.AspNetCore": "Warning"
}
},
// ... ... ...
}
In Startup.cs
, add the middleware with UseSerilogRequestLogging()
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
// ... ... ...
}
options callback on UseSerilogRequestLogging()
(modify message template, events, properties etc.)
// ... ... ...
app.UseSerilogRequestLogging(options =>
{
// Customize the message template
options.MessageTemplate = "Handled {RequestPath}";
// Emit debug-level events instead of the defaults
options.GetLevel = (httpContext, elapsed, ex) => LogEventLevel.Debug;
// Attach additional properties to the request completion event
options.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
{
diagnosticContext.Set("RequestHost", httpContext.Request.Host.Value);
diagnosticContext.Set("RequestScheme", httpContext.Request.Scheme);
};
});
// ... ... ...
Response logging
- https://exceptionnotfound.net/using-middleware-to-log-requests-and-responses-in-asp-net-core/
- https://github.com/exceptionnotfound/AspNetCoreRequestResponseMiddlewareDemo/blob/master/RequestResponseLoggingDemo.Web/Middleware/RequestResponseLoggingMiddleware.cs
Logging to Azure Blob Storage
/aspnet-core/logging#logging-to-azure-blob-storage-using-serilog