I have a .NET 5.0 console application with Serilog nugget. The serilog part of appsettings.json looks like this :
"Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ],
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss.fff} [{Level}] {SourceContext} {Message}{NewLine}{Exception}",
"theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console"
}
},
{
"Name": "File",
"Args": {
"path": "/Logs/SharedTreatment_logs.txt",
"outputTemplate": "{Timestamp:G} {SourceContext} [{Level}] {Message}{NewLine:1}{Exception:1}",
"formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog",
"fileSizeLimitBytes": 1000000,
"rollOnFileSizeLimit": "true",
"shared": "true",
"flushToDiskInterval": 3
}
}
]
It is loaded with this code :
Serilog.Debugging.SelfLog.Enable(Console.Error);
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var logger = loggerConfiguration.ReadFrom.Configuration(configuration).CreateLogger();
Log.Logger = logger?.ForContext<T>() ?? throw new ArgumentNullException(nameof(logger));
Host.CreateDefaultBuilder(args).UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration))
Each class in the solution got a ILogger injection for example ILogger<MyClass> logger
.
The question is how I create a new logger that uses another log configuration section from the appsettings.json to log to another file in such a class?
Update : After a lot of seraching and testing I think I found a way to do this. Im still however not sure it is the right way or the best way?
I have to create 2 sub-loggers, one for the main logging that excludes files and one that only log files like this :
{
"Serilog": {
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
"MinimumLevel": "Debug",
"Enrich": [ "FromLogContext" ],
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss.fff} [{Level}] {SourceContext} {Message}{NewLine}{Exception}",
"theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console"
}
},
{
"Name": "Logger",
"Args": {
"configureLogger": {
"Filter": [
{
"Name": "ByIncludingOnly",
"Args": {
"expression": "@p['LogToFile']"
}
}
],
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "Logs/SharedTreatment_logs_Second.txt",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
}
}
]
}
}
},
{
"Name": "Logger",
"Args": {
"configureLogger": {
"Filter": [
{
"Name": "ByExcluding",
"Args": {
"expression": "@p['LogToFile']"
}
}
],
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "Logs/SharedTreatment_logs.txt",
"outputTemplate": "{Timestamp:G} {SourceContext} [{Level}] {Message}{NewLine:1}{Exception:1}",
"formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog",
"fileSizeLimitBytes": 1000000,
"rollOnFileSizeLimit": "true",
"shared": "true",
"flushToDiskInterval": 3
}
}
]
}
}
}
]
}
}
This is how the C# code looks like :
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Log.Logger = new LoggerConfiguration().DefaultLoggerSetup<Program>();
using (LogContext.PushProperty("LogToFile", true))
{
Log.Information("LogToFileTest");
}
Log.Information("Just log");
Log.CloseAndFlush();
}
Two files is creaed and the filtered logs is where they should be.
To solve this I hade to create a separated log entry in the appsettings.json like this :
{
"Name": "Logger",
"Args": {
"configureLogger": {
"Filter": [
{
"Name": "ByIncludingOnly",
"Args": {
"expression": "@p['LogToFile']"
}
}
],
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "Logs/SharedTreatment_logs_Second.txt",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
}
}
]
}
}
},
I den hade to push the specific loggings to this logger like this :
using (LogContext.PushProperty("LogToFile", true))
{ _logger.LogInformation("Incoming Message MessageGuid : {MessageGuid} , MessageChainGuid : {MessageChainGuid}, SharedTreatment : {SharedTreatment}", incomingMessage.MessageGuid, incomingMessage.MessageChainGuid, incomingMessage.SharedTreatment); }