Profiling a .NET Core 3.0 Console App running in Docker for Windows with dotTrace
07 Dec 2019Recently, I was asked to profile a .NET Console App running in Docker for Windows. I’m a big fan of the JetBrains tools for .NET: ReSharper, dotPeek, dotTrace - they are all part of my toolbelt. Since I’ve never profiled a Docker container with dotTrace, this post shall illustrate how to do this.
First of all, we need some code to profile. The complete code can be downloaded from this GitHub repo. But basically, it is nothing more than this:
As we can see, every second 100 random numbers will be generated and printed to the console.
Furthermore, a Dockerfile
is needed and it looks like this:
We’re pulling the base image mcr.microsoft.com/windows/servercore:1903
, adding the compiled application and setting it as the ENTRYPOINT
.
Before building the Docker image, the application has to be built using the dotnet
global tool:
Afterwards, we can build the Docker image:
Before running and profiling the container, please make sure that you have dotTrace installed and if not happened yet, make your self comfortable with the how-to Starting Remote Profiling Session. In summary, it says the following:
- Unzip
RemoteAgent.zip
to the environment to profile (in our case the Docker container). - Start dotTrace and connect to the Remote Agent URL. By default, the Remote Agent uses port 9100.
- Attach to the application.
So lets do this step by step. At first, we will start the Docker container and map the container port 9100 to its local pendant:
To copy the unzipped Remote Agent, the following command has to be executed:
This copies all the content from the host’s folder RemoteAgent
to the container’s folder RemoteAgent
. In case this commands fails saying that you cannot copy content while a container is running: this seems to be a Windows/Hyper V limitation. We can work around this by stopping the container, copying the content and finally starting it again:
Now the Remote Agent is there, but is has to be started:
Finally, we can connect to our application using dotTrace. As Remote Agent URL, we use net.tcp://localhost:9100/RemoteAgent
. This accesses the local port 9100 of my machine which is mapped to port 9100 of the Docker container where the Remote Agent is up and running. Now we can attach dotTrace to TestWithDocker.exe
and collect snapshots as usual.
As you can see in the following screenshot, everything works as usual when profiling an application and we find our method DoSomeWork()
: