Logging & Errors

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

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.

request-log

EF Core log

Here is ef core telling you exactly what SQL command it executed.

request-log

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

request-log

Exception log

Exceptions look like this.

request-log

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."
}