Search code examples
c#asp.net-coreloggingserilog

invoke an action if asynchronous logging is failed in asp.net core


I have a requirement where I would like to write logs to a file if database logging failed. The idea here is to again insert those records back to the database from the file by running some batch.

I am using a middleware approach to log request/response/exceptions to the database.

public async Task InvokeAsync(HttpContext context)
{       
    //execute request and get response
    try{
        _logger.LogDebug("{database logging template}", log.Request, log.Response, log.Exception);
    }
    catch(Exception ex){
        //Log to file ---> _logger.LogDebug();
    }   
}

My serilog configuration looks like this

.WriteTo.MSSqlServer(
    connectionString: config.GetConnectionString("DB"),
    sinkOptions: new SinkOptions { TableName = "LogTable", AutoCreateSqlTable = true },
    columnOptions: columnOptions));

I am not sure without blocking the HTTP request, how to check if _logger.LogDebug is successfully executed and if not, proceed in the catch to write the logs in a file.

I can use .AuditTo in serilog but that will make the logging synchronous and hence will block the HTTP response.

Any suggestions?


Solution

  • Serilog doesn't currently have a feature that lets you catch errors when an asynchronous log write fails, so .AuditTo would be the only reliable option out-of-the-box, with the disadvantage that calls become synchronous as you mentioned.

    To do what you want and still keep the writes asynchronous, you'd have to create your own version of Serilog.Sinks.MSSqlServer and handle the errors there or expose them to your calling code.

    One other thing you can do, is to enable the SelfLog and try to write the error messages to a more reliable sink, just so that you can get an alert that the calls are failing. It won't give you the original message that failed to be written, but at least you can get notified when exceptions occur.