Search code examples
asp.net-core-webapiserilog

C# .net-core Web API Serilog: log files to different folders based on property (i.e. controller name)


Our client wants log files stored in separate folders based on the controller. For example, all logs that hit the Shipping controller would be stored in C:\logs\shipping\ while those that hit the orders controller would be in c:\logs\orders and so on. Below is my ConfigureLoggingServices method. I'm using Serilog and writing to a file and to Seq. I'm using middleware to capture the client user and session ID (stored in the request header) and pushing these values to the log entry with LogContext.PushProperty(). I somehow need to inject the name of the controller into the path of the log file. Is this possible? Thanks

private void ConfigureLoggingServices()
{
    var appName = Configuration.GetValue<string>("Logging:AppName", string.Empty);
    var SeqURL = Configuration.GetValue<string>("Logging:SeqURL", string.Empty);
    var pool = Environment.UserName;

    //string logFile = "C:\\Logs\\" + {Controller} + "\\lis_api.log";
    string logFile = "C:\\Logs\\lis_api.log";
    const string customTemplate = "[{LIS_User} {Timestamp:HH:mm:ss.fff} {Level:u3} {SessionID}] {RequestMethod} {RequestPath} {Message:lj}{NewLine}{Exception}";

    var name = Assembly.GetExecutingAssembly().GetName();

    Log.Logger = new LoggerConfiguration()
        .MinimumLevel.Debug()
        .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
        .MinimumLevel.Override("System", LogEventLevel.Warning)
        .Enrich.FromLogContext()
        .Enrich.WithMachineName()
        .Enrich.WithProperty("Application", appName)
        .Enrich.WithProperty("Version", $"{name.Version}")
        .Enrich.WithProperty("AppPool", pool)
        .Destructure.ByTransforming<User>(x => new { x.ID, x.Name, x.Controller })

       // File Sink - Async
       .WriteTo.Async(a => a.
           File(string.Format(string.Format(logFile)),
           rollingInterval: RollingInterval.Day,
           outputTemplate: customTemplate,
           fileSizeLimitBytes: 40000000,
           shared: true,
           retainedFileCountLimit: 50,
           rollOnFileSizeLimit: true))                  

        .WriteTo.Seq(SeqURL)

        .CreateLogger();

    LoggerFactory = CreateLoggerFactory();
}

Solution

  • .WriteTo.Map(
        "Controller",
        "(None)",
        (ctrl, wt) => wt.File($"C:\\Logs\\{ctrl}\\lis_api.log"))