I can't find a consistent way to log exceptions in my .NET Core microservice. Informational messages logging guidelines are simple (Microsoft.Extension.Logging is used):
_logger.LogInformation($"Reading file {path}..."); // bad
_logger.LogInformation("Reading file {Path}...", path); // good
The benefit of the second variant is structured information: by using a clever log event router (like Serilog with RenderedCompactJsonFormatter) the path is written as separate property of the log event.
Things are going worse with errors logging. The requirements are obvious:
- Errors are implemented as exceptions.
- An error is logged in the catch block where it is handled.
- Each error is logged in a structured form.
So, I'd expect the error reporting to look like
throw new MyException("Failed to read file {Path}", path);
and error logging - like
catch(MyException e)
{
_logger.LogError(e, "Processing error");
}
LogError method here logs the complete error description, but it is not structured: the path is not added as a property. I tried to make MyException hold the message template and the arguments, but there are 2 problems with this approach:
- How to render the exception message based on a template with named arguments?
- An argument may be disposed when an exception is processed in a catch block.
Please tell me how you deal with this.
