Blog Post

IIS Support Blog
3 MIN READ

Capturing dotnet trace for app service

Meghali's avatar
Meghali
Icon for Microsoft rankMicrosoft
May 19, 2022

Recently I was involved in troubleshooting a bot case where a system.net call from the bot was failing. We wanted to grab dotnet-traces as that gives us best information from system.net perspective. One way would be to run the bot project locally and then run dotnet-trace for the dotnet process there. But if the issue only happens in the Azure deployed bot, things become a little complicated. 

 

These steps below helped to capture dotnet-trace from Azure app service directly:

 

 

 

  • Run dotnet tool install --global dotnet-trace to install the dotnet trace CLI.

 

 

C:\home>dotnet tool install --global dotnet-trace

Failed to add 'C:\local\UserProfile\.dotnet\tools' to the PATH environment variable. Add this directory to your PATH to use tools installed with 'dotnet tool install'.



Welcome to .NET 6.0!

---------------------

SDK Version: 6.0.101



Telemetry

---------

The .NET tools collect usage data in order to help us improve your experience. It is collected by Microsoft and shared with the community. You can opt-out of telemetry by setting the DOTNET_CLI_TELEMETRY_OPTOUT environment variable to '1' or 'true' using your favorite shell.



Read more about .NET CLI Tools telemetry: https://aka.ms/dotnet-cli-telemetry



----------------

Installed an ASP.NET Core HTTPS development certificate.

To trust the certificate run 'dotnet dev-certs https --trust' (Windows and macOS only).

Learn about HTTPS: https://aka.ms/dotnet-https

----------------

Write your first app: https://aka.ms/dotnet-hello-world

Find out what's new: https://aka.ms/dotnet-whats-new

Explore documentation: https://aka.ms/dotnet-docs

Report issues and find source on GitHub: https://github.com/dotnet/core

Use 'dotnet --help' to see available commands or visit: https://aka.ms/dotnet-cli

--------------------------------------------------------------------------------------

Tools directory 'C:\local\UserProfile\.dotnet\tools' is not currently on the PATH environment variable.



You can add the directory to the PATH by running the following command:



setx PATH "%PATH%;C:\local\UserProfile\.dotnet\tools"



You can invoke the tool using the following command: dotnet-trace

Tool 'dotnet-trace' (version '6.0.257301') was successfully installed.

 

 

 

  • Set the environment variable as : set PATH=%PATH%;%USERPROFILE%\.dotnet\tools

 

 

C:\home>set PATH=%PATH%;%USERPROFILE%\.dotnet\tools

 

 

 

  • Now find out the process ID of your dotnet core process by clicking on the “process Explorer” In the Kudu console :

 

  • Once you have the process ID, run the command as below :

 

 

C:\home>dotnet-trace collect --profile cpu-sampling --providers Microsoft-Extensions-Logging:4:5,Microsoft-AspNetCore-Server-Kestrel,Microsoft-System-Net-Http,System-Threading-Tasks-TplEventSource::5 -p 5748 --duration 00:00:00:30



Provider Name                           Keywords            Level               Enabled By

Microsoft-Extensions-Logging            0x0000000000000004  Verbose(5)          --providers

Microsoft-AspNetCore-Server-Kestrel     0xFFFFFFFFFFFFFFFF  Verbose(5)          --providers

Microsoft-System-Net-Http               0xFFFFFFFFFFFFFFFF  Verbose(5)          --providers

System-Threading-Tasks-TplEventSource   0xFFFFFFFFFFFFFFFF  Verbose(5)          --providers

Microsoft-DotNETCore-SampleProfiler     0x0000F00000000000  Informational(4)    --profile

Microsoft-Windows-DotNETRuntime         0x00000014C14FCCBD  Informational(4)    --profile



Process        : C:\Program Files (x86)\dotnet\dotnet.exe

Output File    : C:\home\dotnet.exe_20220211_050635.nettrace

Trace Duration : 00:00:00:30







Stopping the trace. This may take several minutes depending on the application being traced.



Trace completed.

 

 

 

 

 

NOTE : Please do not forget to give the duration parameter ---- Because in Kudu console you will not be able to manually stop (By pressing “Enter” Or “Ctrl + C” --- It is not an actual console after all 😝 )

 

  • Make sure you reproduce the issue within the set duration and once it is done and trace is collected, you can directly download that trace from kudu console :

 

 

 

 

 

  • Once you have the trace, you can open it in Perfview.

 

I have used the above dotnet-trace commands as I was specifically interested in System.Net events, and you can alter the command as per your need.

 

Reference : dotnet-trace diagnostic tool - .NET CLI | Microsoft Docs

 

What if the app is running on Linux app service ?

 

In case of Linux app service, Do the same and go to Kudu console and here you can go to SSH :

 

 

 

 

You can use “top” command to get the process ID of the process running your app.

 

And then normally run the dotnet-trace collect command (In Linux app service, it is already installed, and you can also stop the command using Ctrl + C in Linux SSH 😊)

 

See screenshot below for reference.

 

 

 

 

Now to download this trace, just access the URL appname.scm.azurewebsites.net/vfs/(path-to-file)

 

In this example : https://pglinuxapp.scm.azurewebsites.net/api/vfs/dotnet_20220211_053206.nettrace (It will say path not found…but your browser will download the file)

 

I hope this helps!

Updated May 19, 2022
Version 1.0

4 Comments

  • Another method to download the file for Linux WebApp, I found as an alternate was to add the /newui at the end of the kudu url for example https://myexample.scm.azurewebsites/newui and you can use file manager to navigate to the site directory and download it from there:

     

  • Running a Function App hosted inside an App Service Environment, I am unable to install the dotnet-trace tool:

    C:\home>dotnet tool install --global dotnet-trace
    System.UnauthorizedAccessException: Attempted to perform an unauthorized operation.
       at Microsoft.Win32.RegistryKey.Win32Error(Int32 errorCode, String str)
       at Microsoft.Win32.RegistryKey.SetValueCore(String name, Object value, RegistryValueKind valu
    eKind)
       at Microsoft.Win32.RegistryKey.SetValue(String name, Object value, RegistryValueKind valueKind)
       at Microsoft.DotNet.Cli.Utils.WindowsRegistryEnvironmentPathEditor.Set(String value, SdkEnvironmentVariableTarget sdkEnvironmentVariableTarget)
       at Microsoft.DotNet.ShellShim.WindowsEnvironmentPath.AddPackageExecutablePathToUserPath()
       at Microsoft.DotNet.Configurer.DotnetFirstTimeUseConfigurer.Configure()
       at Microsoft.DotNet.Cli.Program.ConfigureDotNetForFirstTimeUse(IFirstTimeUseNoticeSentinel firstTimeUseNoticeSentinel, IAspNetCertificateSentinel aspNetCertificateSentinel, IFileSentinel toolPathSentinel, Boolean isDotnetBeingInvokedFromNativeInstaller, DotnetFirstRunConfiguration dotnetFirstRunConfiguration, IEnvironmentProvider environmentProvider, Dictionary`2 performanceMeasurements)
       at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, TimeSpan startupTime, ITelemetry telemetryClient)
       at Microsoft.DotNet.Cli.Program.Main(String[] args)