Logging & Errors
Logging and handling errors is a big part of any production application.
Structured logging is done with serilog.
As implemented this code base is VERY chatty.
It automatically logs
- Every request including all request properties + logged in user
- Every sql query executed by ef core with all parameters
- Every exception in a structured way
Libraries & Tools
- Serilog (opens in a new tab)
- Seq (opens in a new tab) (Screenshots are done with this)
- Azure ApplicationInsights (opens in a new tab)
Logging
I find this automated, heavy request logging very useful in the early stages of an application.
Its a great way to know what is actually going on in your production environment and find out how your users are using your application.
Eventually you want to tone this way down though. Or make sure only certain people have access.
Request log
You can see which request, all the request values and which user executed the request.
EF Core log
Here is ef core telling you exactly what SQL command it executed.
As you can tell by me unironically censoring this, this can very easily contain sensitive data.
Thats why its called EnableSensativeDataLogging and Microsoft tells you in the logs
Exception log
Exceptions look like this.
As you can see, it gives you everything. Below the actual exception log you could investigate the request log, with its request values and the user.
Errors
Of course all uncaught exceptions get automatically logged.
But what about the client?
For 4xx responses (client side errors) the api returns the ProblemDetails
class based on the RFC7807 (opens in a new tab) standard.
{
"type": "https://www.rfc-editor.org/rfc/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"instance": "/api/identity/register",
"traceId": "0HN1HBBHVLPTS:00000009",
"errors": [
{
"name": "generalErrors",
"reason": "Passwords must have at least one non alphanumeric character.",
"code": "PasswordRequiresNonAlphanumeric"
}
]
}
For 5xx responses (server side error) the api returns this respose.
{
"status": "Internal Server Error!",
"code": 500,
"reason": "Attempted to divide by zero.",
"note": "See application log for stack trace."
}