Vaughan Reid's blog

Measuring .Net Core: 1. Setting up local diagnostics tools

This is the first in a series of posts covering measuring a .Net Core application. If you want to try follow the code then you can have a look at this repo: Blog-Diagnostics.

This is the plan for the series. I will update this with links as it evolves.

  1. Setting up local diagnostics tools
  2. Using dotnet-counters
  3. dotnet-counters with a custom provider
  4. Using dotnet-gcdump to investigate memory leaks
  5. Creating a dump file when a ASP.NET Core application crashes

There are quite a few diagnostic tools that you can install and use for your .net core applications to measure performance and other metrics and I will try go through the ones I know. One nice way to use them is to link them to a project with a local tool-manifest file. You can then check it into source control and anyone using your project can just restore them.

In this project I used the command line in the same folder as the main csproj file and ran the following commands.

dotnet new tool-manifest
dotnet tool install dotnet-counters
dotnet tool install dotnet-dump
dotnet tool install dotnet-gcdump
dotnet tool install dotnet-trace
dotnet tool install dotnet-sos

This creates a json file in a .config folder in the following format.

{
  "version": 1,
  "isRoot": true,
  "tools": {
    "dotnet-counters": {
      "version": "3.1.120604",
      "commands": [
        "dotnet-counters"
      ]
    },
    "dotnet-dump": {
      "version": "3.1.122203",
      "commands": [
        "dotnet-dump"
      ]
    },
    "dotnet-gcdump": {
      "version": "3.1.120604",
      "commands": [
        "dotnet-gcdump"
      ]
    },
    "dotnet-trace": {
      "version": "3.1.120604",
      "commands": [
        "dotnet-trace"
      ]
    },
    "dotnet-sos": {
      "version": "3.1.122203",
      "commands": [
        "dotnet-sos"
      ]
    }
  }
}

Now anyone checking out the project can just run dotnet tool restore and it will all be downloaded and made available.

I would like to run most of these from the docker container since that is most likely where the live code will run. One small problem that I had was that these tools require the SDK installed to be able to run them. Disclaimer: I saw some posts from people who managed to copy the dependencies needed into the runtime image but I never got it to work.

Since this is all just working on my machine I just updated the one that visual studio created to just use the SDK as the base image without playing too much with the multi stage builds.

For the sample project I initially have a Person controller that has a get endpoint that awaits a person result. I will most probably expand this when I go through some of the tools but this is the initial version.


[Route("api/[controller]")]
[ApiController]
public class PersonController : ControllerBase
{
	readonly IPersonService _personService;
	public PersonController(IPersonService personService)
	{
		_personService = personService;
	}

	[HttpGet]
	[Route("{name}")]
	public async Task<IActionResult> Get(string name)
	{
		return Ok(await _personService.GetAsync(name));
	}
}

public class PersonService : IPersonService
{
	public async Task<Person> GetAsync(string name)
	{
	await Task.Delay(TimeSpan.FromSeconds(1));
	return new Person { Name = name, Age = 18 };
	}
}

public interface IPersonService
{
	Task<Person> GetAsync(string name);
}

When I start the application I will sh into the container and run the command.


dotnet tool restore

You should then get a response

Tool 'dotnet-counters' (version '3.1.120604') was restored. Available commands: dotnet-counters
Tool 'dotnet-dump' (version '3.1.122203') was restored. Available commands: dotnet-dump
Tool 'dotnet-gcdump' (version '3.1.120604') was restored. Available commands: dotnet-gcdump
Tool 'dotnet-trace' (version '3.1.120604') was restored. Available commands: dotnet-trace
Tool 'dotnet-sos' (version '3.1.122203') was restored. Available commands: dotnet-sos

And now you can have some fun.