To enable the Application Insights Profiler on your container, you will need to:
- Add the reference to the NuGet package.
- Register services to enable profiler.
In this article, you'll learn the various ways you can:
-
Install the NuGet package in the project.
-
Register the service to enable profiler.
Notice: this post is NOT about security best practice. you will need to take your security measure according to your orchestrator/environment. For example, use secrets in Kubernetes for sensitive configurations.
- An Application Insights resource. Make note of the connection string.
- .NET 6 SDK for creating projects and local build.
- Docker Desktop to build docker images.
Either use a provided project or build your own. Here's how:
Use an existing project
-
Fork / clone and use the following sample project:
git clone https://github.com/microsoft/ApplicationInsights-Profiler-AspNetCore.git
-
You will find the example project under
examples\EnableServiceProfilerForContainerAppNet6
.
Build your own
If you want to build your own project, here are the steps:
-
Start a bare bone webapi project created by templates:
dotnet new webapi
-
Add reference to NuGet packages:
dotnet add package Microsoft.ApplicationInsights.Profiler.AspNetCore
Tips: Find out the latest NuGet package by visiting nuget.org.
-
Enable Profiler by registering it into the Service Collection in Program.cs:
builder.Services.AddApplicationInsightsTelemetry(); // Register Application Insights builder.Services.AddServiceProfiler(); // Register Profiler
-
Add application insights configurations (appsettings.json) as a sibling to
Logging
to connect to the Application Insights resource created:{ "ApplicationInsights": { "InstrumentationKey": "Your instrumentation key" } }
-
Add a delay in WeatherForecastController to simulate a bottleneck. And call it whenever WeatherForecast endpoint is hit.
[HttpGet(Name = "GetWeatherForecast")] public IEnumerable<WeatherForecast> Get() { SimulateDelay(); ... // Other existing code. } private void SimulateDelay() { // Delay for 500ms to 2s to simulate a bottleneck. Thread.Sleep((new Random()).Next(500, 2000)); }
-
Build the project to make sure it works.
dotnet build
Move on to dockerize the application once build succeeded.
-
Review the dockerfile.
-
Build the image with it:
docker build -t profilerapp .
-
Run the container
docker run -d -p 8080:80 --name testapp profilerapp
Note: The Profiler will run for 2 minutes. That is the best chance for testing and it is important to hit the endpoint to generate some traffic for profiling during this period. If you missed the window, kill the container and run it again.
-
To hit the endpoint, visit http://localhost:8080/weatherforecast in your browser or use curl:
curl http://localhost:8080/weatherforecast
-
Optionally, inspect the local log to see if a session of profiling finished by:
docker logs testapp
There are some key events to pay attention to like:
Starting application insights profiler with instrumentation key: your-instrumentation key # Double check the instrumentation key Service Profiler session started. # Profiler started. Finished calling trace uploader. Exit code: 0 # Uploader is called with exit code 0. Service Profiler session finished. # A profiling session is completed.
Notes: If there is no uploader related events, chances are, there's no traffic during the session. Kill the container and run it again.
-
Wait for 2 to 5 minutes for the Profiler show up in your Application Insights resource in the Portal.
-
Clean up the local container
docker rm -f testapp
To better correlate the container with the host of your application when deploying directly to Azure App Service, a telemetry initializer can be introduced. This will help address the issue where the value for cloud_RoleInstance is simply the container id, which may not be easily identifiable with the host. Follow these steps:
-
Create the telemetry initializer, see RoleInstanceTelemetryInitializer for an example:
public class RoleInstanceTelemetryInitializer : ITelemetryInitializer { public void Initialize(ITelemetry telemetry) { string? computerName = Environment.GetEnvironmentVariable("COMPUTERNAME"); if (string.IsNullOrEmpty(computerName)) { return; } telemetry.Context.Cloud.RoleInstance = computerName; } }
Tips:
-
"COMPUTERNAME" was used as an example, you could pick any useful environment variables from Kudu:
-
With telemetry initializer, any property on the telemetry could be customized. See here for more details.
-
Do not use async code or heavy logic in telemetry initializers.
-
-
Register it at the startup of your application, see Program.cs for an example:
// Register RoleInstanceTelemetryInitializer as an ITelemetryInitializer builder.Services.AddSingleton<ITelemetryInitializer, RoleInstanceTelemetryInitializer>();
And here's how it looks like:
- Add customize configurations - There are lot of customization supported like profiling duration, local cache folder, upload mode, etc.
- Sets logging level for Profiler - logging is useful and important for troubleshooting.