Question
Filtering Serilog logs to different sinks depending on Property
I am attempting to integrate Serilog into my ASP.NET Core API project to log specific types of entries to different sinks based on their propertry. My goal is to configure the logger so that when the Serilog Context includes a specific property, the logs are written to a file; otherwise, they should be directed to SEQ . But this not working for me. Please find below my Code
Appsettings.json
{
"Serilog": {
"Using": [ "Serilog.Exceptions" ],
"LevelSwitches": { "$controlSwitch": "Error" },
"MinimumLevel": { "ControlledBy": "$controlSwitch" },
"Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId", "WithExceptionDetails" ],
"WriteTo": [
{
"Name": "File",
"Args": {
"pathFormat": "C:\\Logs\\MLAPILog-{Date}.log",
"rollingInterval": "Day",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
},
"Filter": [
{
"Name": "ByIncluding",
"Args": {
"Expression": "Matching.WithProperty('LogType', 'File')"
}
}
]
},
{
"Name": "Seq",
"Args": {
"serverUrl": "sequrl",
"apiKey": "api key",
"controlLevelSwitch": "$controlSwitch"
},
"Filter": [
{
"Name": "ByExcluding",
"Args": {
"Expression": "Matching.WithProperty('LogType', 'File')"
}
}
]
}
],
"Properties": {
"MLEnvironment": "Local",
"Client": "Unknown"
}
},
BaseController
//below method is specifically to write logs to file.
internal void LogAuthInfo(string requestUrl, string authToken, string formattedAuth)
{
var hostName = Dns.GetHostName();
var ipAddress = Dns.GetHostAddresses(hostName);
using (LogContext.PushProperty("LogType", "File"))
{
_logger
.ForContext("CallingApplication", this.CallingApplication)
.ForContext("CustomerCode", this.CustomerCode)
.ForContext("LocationId", this.LocationId.ToString())
.ForContext("LocationDescription", this.LocationDescription)
.ForContext("Version", Assembly.GetExecutingAssembly().GetName().Version)
.ForContext("ServerIP", string.Join(",", ipAddress.Select(x => x.ToString())))
.ForContext("RequestUrl", requestUrl)
.ForContext("AuthToken", authToken)
.ForContext("FormattedAuthToken", formattedAuth)
.Error("AuthToken Info");
}
}
}
Below one is used to log details in seq. Since both logs needs to save different info, I have given different methods
protected internal void LogInfo(string message, [CallerMemberName] string memberName = null, bool detailedTracking = false)
{
var hostName = Dns.GetHostName();
var ipAddress = Dns.GetHostAddresses(hostName);
_logger
.ForContext("CallingApplication", this.CallingApplication)
.ForContext("CustomerCode", this.CustomerCode)
.ForContext("LocationId", this.LocationId.ToString())
.ForContext("LocationDescription", this.LocationDescription)
.ForContext("Version", Assembly.GetExecutingAssembly().GetName().Version)
.ForContext("ServerIP", string.Join(",", ipAddress.Select(x => x.ToString())))
.ForContext("DetailedTracking", detailedTracking.ToString())
.Information(message);
}
Then I am calling this code in the BasicAuthorizeAttribute class
public class BasicAuthorizeAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext actionContext)var configuration = actionContext.HttpContext.RequestServices.GetRequiredService<Microsoft.Extensions.Configuration.IConfiguration>();
var logDebugAccess = configuration.GetValue<string>("AppSettings:LogAuthToken:DebugAccessCodeEnabled");
string customerCodes = configuration.GetValue<string>("AppSettings:LogAuthToken:CustomerCodes");
BaseController controller = (BaseController)actionContext.Controller;
if (logDebugAccess != null && logDebugAccess == "true" && !string.IsNullOrEmpty(customerCodes)) //These are configurations to control the logging
{
var customerCodeList = customerCodes.Split(',').Select(code => code.ToUpper().Trim());
if (customerCodeList.Contains(siteCode.ToUpper()))
{
controller.LogAuthInfo(url, encryptetransactioncode, formattedAuth);
}
}
}
}
In Serilog Logger Extension class, I have the below logic given
public static class SerilogLoggerExtension
{
public static void Initialize(ILoggerFactory loggerFactory, IConfiguration configuration)
{
var mlEnvironment = configuration.GetValue<string>("MLEnvironment");
var productName = "MicrologicAPI";
// Read Seq server URL and API key from appsettings.json
var seqServerUrl = configuration.GetValue<string>("Serilog:WriteTo:1:Args:serverUrl");
var seqApiKey = configuration.GetValue<string>("Serilog:WriteTo:1:Args:apiKey");
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.Enrich.FromLogContext()
.Enrich.WithEnvironmentUserName()
.Enrich.WithExceptionDetails()
.CreateLogger();
loggerFactory.WithFilter(new FilterLoggerSettings
{
{"Trace",LogLevel.Trace },
{"Default", LogLevel.Trace},
{"Microsoft", LogLevel.Warning},
{"System", LogLevel.Warning}
})
.AddSerilog();
}
}
I am using Serilog Version - 2.10.1. Can anyone please help to identify the issue with my code?