Serilog logging with .Net Core — Are we configuring it correctly?
Like many other libraries for .NET, Serilog provides diagnostic logging to files, the console, and elsewhere. It is easy to set up, has a clean API, and is portable between recent .NET platforms.
It is very easy to set up but the question is, Are we doing it correctly?
To start with Serilog with .net core, we need to do two important tasks:
- Configure the settings for Serilog through the config file.
"Serilog": {
"Using": [
"Serilog.Sinks.Console"
],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Host": "Error",
"Microsoft": "Error",
"System": "Error",
"Microsoft.AspNetCore": "Error"
}
},
"WriteTo": [
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "Console",
"Args": {
"formatter": "Serilog.Formatting.Compact.RenderedCompactJsonFormatter, Serilog.Formatting.Compact"
}
}
]
}
}
]
}
In the above setting, we configure three important steps,
a: Define the sink
- sinks are for writing log events to storage in various formats. Here is the complete list of sinks provided by Serilog:
https://github.com/serilog/serilog/wiki/Provided-Sinks
b: Configure the minimum log level which we override to Error for Host, System, and framework errors.
c: Define the WriteTo format for the log events. You can define your custom format of the data being logged here. i.e.
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss} {SourceContext} [{Level}] {Message}{NewLine}{Exception}",
"theme": "Serilog.Sinks.SystemConsole.Themes.SystemConsoleTheme::Grayscale, Serilog.Sinks.Console"
}
}
]
2. Initialize serilog as loggingProvider in Program.cs
var logger = new LoggerConfiguration().ReadFrom.Configuration(builder.Configuration).CreateLogger();
builder.Host.UseSerilog(logger, dispose: true);
Wait, are we doing it correctly. Of course Not! Above code has a security issue and it has led in the past to the following vulnerabilities:
CVE-2018–0285
CVE-2000–1127
CVE-2017–15113
CVE-2015–5742
So how do we correct it then? well, this is how you can correctly initialize the serilog as logging provider through the Action method parameter, instead of creating a new instance of LoggerConfiguration. Here is the code:
builder.Host.UseSerilog((hostingContext, loggerConfiguration) =>
{
loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration);
});
In this case, .Net Core infrastructure will take care of loggerConfiguration through dependency resolver internally based on your config setting which is secured.
Finally Here is the complete code to properly initialize serilog as logging provider by reading config from appsettings.{your_environment}.json files.
using Serilog;var builder = WebApplication.CreateBuilder(args);// read configuration information from appsettings.enviorment.json builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
config.AddEnvironmentVariables();
});builder.Host.UseSerilog((hostingContext, loggerConfiguration) =>
{
loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration);
});
Hope you enjoyed the content, follow me for more like this, and please don’t forget to clap for it. Happy programming.