Carl Rippon

Building SPAs

Carl Rippon
BlogBooks / CoursesAbout
This site uses cookies. Click here to find out more

Controlling our ASP.NET Core Serilog Log

January 22, 2018
dotnet

In a previous post we built up a Serilog log full of useful information. In this post we’re going to see if we can control exactly what is logged, without a software deployment. By default, we want our logs to be fairly light and have the ability to increase the amount of logging when we are diagnosing a problem.

So, we have an ASP.NET Core Web API in production, hosted in IIS. We also have the middleware running from this post that gives us additional properties in our log like “RequestPath” and “UserName”. Here’s our

"Serilog": {
	"MinimumLevel": {
		"Default": "Information",
		"Override": {
			"Microsoft": "Information"
		}
	},
	"WriteTo": [
		{
			"Name": "MSSqlServer",
			"Args": {
				"connectionString": "our connection string",
				"tableName": "Log"
			}
		}
	],
	"Enrich": [ "FromLogContext" ]
}

If we GET /api/contacts/f7d10f53-4c11-44f4-8dce-d0e0e22cb6ab we get:

Default log

If we increase the level to “Error”, we no longer get the “Information” entries. We will only get exceptions logged in our log. We don’t need to restart the app pool in IIS - the change kicks in as soon as we save appSettings.json. Nice!

"Serilog": {
	"MinimumLevel": {
		"Default": "Error",
		"Override": {
			"Microsoft": "Error"
		}
	},
	...
}

If we decrease the level to “Debug”, we get a lot more log entries.

"Serilog": {
	"MinimumLevel": {
		"Default": "Debug",
		"Override": {
			"Microsoft": "Debug"
		}
	},
	...
}

Debug Log

So, switching to the “Debug” level is going to be valuable when we are diagnosing a problem. However, that’s a lot of log entries from all over our web API - can we be more specific on what we want to log? That’s where filter expressions come in …

In order to use filter expressions, we need to reference the following nuget:

Serilog.Filters.Expressions

Having changed the MinimumLevel to “Debug”, let’s try to add a filter so that we only get “Debug” entries on GET api/contacts/{contactId} whilst still getting errors logged. Let’s change appSettings.json to:

"Serilog": {
	"MinimumLevel": {
      "Default": "Debug",
      "Override": {
        "Microsoft": "Debug"
      }
    },
    "Filter": [
      {
        "Name": "ByIncludingOnly",
        "Args": {
          "expression": "RequestPath like '%/api/contacts/%' or @Level = 'Error'"
        }
      }
    ]
	...
}

Unfortunately for the filter to kick in, we do need to restart the app pool in IIS. After doing this, we do get all the log entries for that particular path:

Filtered Log

The filter expression uses a powerful SQL like syntax. The filter expression docs give the full details.

Another example of using a filter expression to control our logs is if a particular user is having a problem. The following appSettings.json will give all the log entries for “Carl” as well as any other errors.

"Serilog": {
	"MinimumLevel": {
      "Default": "Debug",
      "Override": {
        "Microsoft": "Debug"
      }
    },
    "Filter": [
      {
        "Name": "ByIncludingOnly",
        "Args": {
          "expression": "UserName = 'Carl' or @Level = 'Error'"
        }
      }
    ]
	...
}

Cool stuff!


Interested in learning more about ASP.NET Core and React? My book is available now!
ASP.NET Core 3 and React