diff --git a/README.md b/README.md index 8f07351..20229e3 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,19 @@ # Application Insights Profiler for Asp.Net core on Linux App Services ## Announcement -~~.NET Core 3.0 is supported now! Check out the new version: [1.1.7-beta1](https://www.nuget.org/packages/Microsoft.ApplicationInsights.Profiler.AspNetCore/1.1.7-beta1).~~ -The issue in 1.1.7-beta1 for .NET Core 3.0 has been fixed. Please update to [1.1.7-beta2](https://www.nuget.org/packages/Microsoft.ApplicationInsights.Profiler.AspNetCore/1.1.7-beta2). + +* Profiler 2.0.0-beta1 is [available now](https://www.nuget.org/packages/Microsoft.ApplicationInsights.Profiler.AspNetCore/2.0.0-beta1). Read [What's new](./docs/WhatIsNew2_0.md) and [Migrate to Application Insights Profiler 2.0](./docs/MigrateTo2_0.md). Follow the example of [quick start](./examples/QuickStart3_0/Readme.md) if you are building a new app service. ## Description -This is the project home page for App Services Linux profiler. Our NuGet package can be found [here](https://www.nuget.org/packages/Microsoft.ApplicationInsights.Profiler.AspNetCore/). -**Notice:** It is highly recommended to use `Application Insights Profiler` with [CLR 2.1](https://dot.net) (shipped with Dotnet Core SDK 2.1.300) and above since there are fixes for fundamental reliability issues. +This is the project home page for `Microsoft Application Insights Profiler for ASP.NET Core`. The NuGet package can be found [here](https://www.nuget.org/packages/Microsoft.ApplicationInsights.Profiler.AspNetCore/). -![Profiler Traces](https://raw.githubusercontent.com/Microsoft/ApplicationInsights-Profiler-AspNetCore/master/media/profiler-traces.png) +![Profiler Traces](./media/profiler-traces.png) ## Get Started +_The following steps based are based on ASP.NET Core 2.2 project. Refer to [Quick Start](./examples/QuickStart3_0/Readme.md) for more specific steps for ASP.NET Core 3.0 projects._ + * Create a WebApi project ```shell @@ -22,6 +23,8 @@ This is the project home page for App Services Linux profiler. Our NuGet package To make it real, make use the following code to add some delay in the controllers to simulate the bottleneck: ```CSharp +using System.Threading; +... private void SimulateDelay() { // Delay for 500ms to 2s to simulate a bottleneck. @@ -51,15 +54,16 @@ public ActionResult Get(int id) Reference [ValuesController.cs](./examples/EnableServiceProfilerInVSCLR2_2_Win/EnableSPInVSWin/Controllers/ValuesController.cs) for full code. -* Add the NuGet package +* Add the NuGet packages ```shell - dotnet add package Microsoft.ApplicationInsights.Profiler.AspNetCore -v 1.1.7-* + dotnet add package Microsoft.ApplicationInsights.AspNetCore + dotnet add package Microsoft.ApplicationInsights.Profiler.AspNetCore -v 2.0.0-* ``` _Note: Find the latest package from the [NuGet.org here](https://www.nuget.org/packages/Microsoft.ApplicationInsights.Profiler.AspNetCore/)._ -* [Create an Application Insights in Azure Portal](https://docs.microsoft.com/en-us/azure/application-insights/app-insights-dotnetcore-quick-start?toc=/azure/azure-monitor/toc.json#log-in-to-the-azure-portal), set Application Insights instrumentation key in `appsettings.json`: +* [Create an Application Insights in Azure Portal](https://docs.microsoft.com/en-us/azure/application-insights/app-insights-dotnetcore-quick-start?toc=/azure/azure-monitor/toc.json#log-in-to-the-azure-portal), set Application Insights instrumentation key in `appsettings.Development.json`: ```json { @@ -76,7 +80,7 @@ Reference [ValuesController.cs](./examples/EnableServiceProfilerInVSCLR2_2_Win/E { services.AddApplicationInsightsTelemetry(); // Enable Application Insights telemetry services.AddServiceProfiler(); // Add this line of code to Enable Profiler - services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); + ... } ``` @@ -125,21 +129,23 @@ You have been start to run the the WebApi with Profiler on. * [Profiler Sessions](./ProfilerSessions.md) - describes when the profiler starts, stops and what is traced. * [Configurations for the Profiler](./Configurations.md) - describes how to customize various settings of the profiler. * [Trace Analysis](./https://docs.microsoft.com/en-us/azure/application-insights/app-insights-profiler-overview?toc=/azure/azure-monitor/toc.json#view-profiler-data) - introduce the trace analysis. +* [Diagnosing a WebAPI experiencing intermittent high CPU using the Application Insights Profiler](https://github.com/Azure/azure-diagnostics-tools/blob/master/Profiler/TriggerProfiler.md). +* [The call tree filter](https://github.com/Azure/azure-diagnostics-tools/blob/master/Profiler/CallTreeFilter.md). ## Supported Versions -| Application Insights Profiler | Windows | Linux | -|-------------------------------|------------------------------------------------------------------------------------------------|-------------------------------------------| -| [1.1.7-beta2](https://www.nuget.org/packages/Microsoft.ApplicationInsights.Profiler.AspNetCore/1.1.7-beta2) | Experimental support for .NET Core App 2.2, 3.0 | Supported for .NET Core App 2.1, 2.2, 3.0 | -| 1.1.7-beta1 | Experimental support for .NET Core App 2.2. | Supported for .NET Core App 2.1, 2.2 | -| 1.1.6-beta1 | Experimental support for .NET Core App 2.2. | Supported for .NET Core App 2.1, 2.2 | -| 1.1.5-beta2 | Experimental support for .NET Core App 2.2. | Supported for .NET Core App 2.1, 2.2 | -| 1.1.4-beta1 | Experimental support for .NET Core App 2.2. Trace tree in the trace explorer looks very noisy. | Supported for .NET Core App 2.1, 2.2 | -| 1.1.3-beta2 | Not supported. | Supported for .NET Core App 2.1, 2.2 | -| 1.1.3-beta1 | Not supported. | Supported for .NET Core App 2.1, 2.2 | -| 1.1.2-beta1 | Not supported. | Deprecated. | -| 1.0.0-beta1 | Not supported. | Deprecated. | - +| Application Insights Profiler | Windows | Linux | +|-------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|-------------------------------------------| +| [2.0.0-beta1](https://www.nuget.org/packages/Microsoft.ApplicationInsights.Profiler.AspNetCore/2.0.0-beta1) | Experimental support for .NET Core App 2.2, 3.0 | Supported for .NET Core App 2.2, 3.0 | +| [1.1.7-beta2](https://www.nuget.org/packages/Microsoft.ApplicationInsights.Profiler.AspNetCore/1.1.7-beta2) | Experimental support for .NET Core App 2.2, 3.0 | Supported for .NET Core App 2.1, 2.2, 3.0 | +| 1.1.7-beta1 | Experimental support for .NET Core App 2.2. | Supported for .NET Core App 2.1, 2.2 | +| 1.1.6-beta1 | Experimental support for .NET Core App 2.2. | Supported for .NET Core App 2.1, 2.2 | +| 1.1.5-beta2 | Experimental support for .NET Core App 2.2. | Supported for .NET Core App 2.1, 2.2 | +| 1.1.4-beta1 | Experimental support for .NET Core App 2.2. Trace tree in the trace explorer looks very noisy. | Supported for .NET Core App 2.1, 2.2 | +| 1.1.3-beta2 | Not supported. | Supported for .NET Core App 2.1, 2.2 | +| 1.1.3-beta1 | Not supported. | Supported for .NET Core App 2.1, 2.2 | +| 1.1.2-beta1 | Not supported. | Deprecated. | +| 1.0.0-beta1 | Not supported. | Deprecated. | ## Examples diff --git a/docs/MigrateTo2_0.md b/docs/MigrateTo2_0.md new file mode 100644 index 0000000..dd4e822 --- /dev/null +++ b/docs/MigrateTo2_0.md @@ -0,0 +1,27 @@ +# Migrating from Application Insights Profiler 1.x to 2.0 + +There are break changes between 1.x and 2.0 for Application Insights Profiler but the migration should be very easy. + +## Update the NuGet packages + +* To use .NET Core CLI: + +```shell +dotnet add package Microsoft.ApplicationInsights.Profiler.AspNetCore --version 2.0.0-* +``` + +* To use package manager: + +```shell +Install-Package Microsoft.ApplicationInsights.Profiler.AspNetCore -Version 1.1.7-* +``` + +## Update the configurations + +There are changes in the configurations. Refer to [What's new](./WhatIsNew2_0#New_customization_options) for details. The minimum step is to remove the obsoleted parameter named 'Interval' form the following location: + +1. appsettings.[Environment].json +1. appsettings.json +1. Update the method of `AddServiceProfiler` to remove the option of **Interval** if it is used. + +And that's it. diff --git a/docs/WhatIsNew2_0.md b/docs/WhatIsNew2_0.md new file mode 100644 index 0000000..81d1e6e --- /dev/null +++ b/docs/WhatIsNew2_0.md @@ -0,0 +1,56 @@ +# What is New in Application Insights Profiler 2.0.0 + +## Profiler Now + +The profiler is talking with the service profiler azure backend and will accept `Profile Now` requests from the portal. + +You can use the `Profile Now` button in the portal and review the traces from the Azure Portal. + +## New scheduling system + +**Random scheduling policy** is used to replace the old fixed time scheduling system. + +In previous versions (1.x), the scheduling system takes 3 parameters: initial delay, duration and interval. The Profiler will be started with an initial delay, run for duration and then pause for interval. + +It is replaced by a random scheduling system/policy. A new parameter of `RandomProfilingOverhead` has been introduced. The random scheduling policy will calculate the profiling count based on the request overhead. For example, to calculate for the next 24 hours: + +```shell +dn / 60 = 24 * r +``` + +In the formula above, `r` is the overhead rate, `d` is the duration, n is the number of profiling. Take duration of **2 minutes**, rate of **5%**, in the next **24 hours** as an example: + +```shell +n = 24 * 0.05 * 60 / 2 = 36 +``` + +Profiler will happen 36 times. + +Notices, depends on the traffic and sampling and other factors, the real trace you get may be less than 36. + +Also, if you watch carefully, you will see other scheduling policies like **OneTimeSchedulingPolicy**, which runs every time after the initial delay per app session. Profile Now is implemented by **OnDemandSchedulingPolicy**. + +## CPU / Memory trigger support for Apps running on Windows + +When Application Insights Profiler for ASP.NET Core NuGet package is included in an ASP.NET Core Application on **Windows**, **CPU triggers** and **Memory triggers** are supported. + +The threshold for the triggers are 80% by default. The trigger policy will look back for 30 second, get the average resource usage and compare it with the threshold. When the value goes beyond the threshold, profiling will be triggered. + +Notes: Although sharing the backend, this is different than the traditional Profiling [here](https://docs.microsoft.com/en-us/azure/azure-monitor/app/profiler-overview). + +## Better container support for .NET Core 3.0 Application + +* Uploaders for .NET Core Runtime 2.0 and .NET Core Runtime 3.0 are sim-shipped in the NuGet package. No more hacks needed to run the same profiler in both .NET Core 2.0 based containers as well as .NET Core 3.0 runtime based containers. + +* In the scenario where you want to pull down the uploader in your dockerfile directly, we are now uploading the exact same uploader binaries on GitHub. Check them out in [Releases](https://github.com/microsoft/ApplicationInsights-Profiler-AspNetCore/releases). + +## New customization options + +* There are changes of options to control the profiling: + +| Option | v2 | v1 | Remark | +|-------------------------|---------|----------|---------------------------------------------------------------| +| RandomProfilingOverhead | 0.05 | N/A | Random profiling overhead percentage in float. The default value of 0.05 means 5%. | +| CPUTriggerThreshold | 0.80 | N/A | Windows only. Threshold for CPU profiling trigger. | +| MemoryTriggerThreshold | 0.80 | N/A | Windows only. Threshold for memory profiling trigger. | +| Interval | Removed | 00:58:00 | Intervals between profiling. Replaced by random policy. | diff --git a/examples/QuickStart3_0/.dockerignore b/examples/QuickStart3_0/.dockerignore new file mode 100644 index 0000000..cd42ee3 --- /dev/null +++ b/examples/QuickStart3_0/.dockerignore @@ -0,0 +1,2 @@ +bin/ +obj/ diff --git a/examples/QuickStart3_0/.gitignore b/examples/QuickStart3_0/.gitignore new file mode 100644 index 0000000..998bde6 --- /dev/null +++ b/examples/QuickStart3_0/.gitignore @@ -0,0 +1,5 @@ +bin/ +obj/ +global.json +nuget.config +pkgs/ \ No newline at end of file diff --git a/examples/QuickStart3_0/.vscode/launch.json b/examples/QuickStart3_0/.vscode/launch.json new file mode 100644 index 0000000..a6dc55d --- /dev/null +++ b/examples/QuickStart3_0/.vscode/launch.json @@ -0,0 +1,36 @@ +{ + // Use IntelliSense to find out which attributes exist for C# debugging + // Use hover for the description of the existing attributes + // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md + "version": "0.2.0", + "configurations": [ + { + "name": ".NET Core Launch (web)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + // If you have changed target frameworks, make sure to update the program path. + "program": "${workspaceFolder}/bin/Debug/netcoreapp3.0/QuickStart3_0.dll", + "args": [], + "cwd": "${workspaceFolder}", + "stopAtEntry": false, + // Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser + "serverReadyAction": { + "action": "openExternally", + "pattern": "^\\s*Now listening on:\\s+(https?://\\S+)" + }, + "env": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "sourceFileMap": { + "/Views": "${workspaceFolder}/Views" + } + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach", + "processId": "${command:pickProcess}" + } + ] +} \ No newline at end of file diff --git a/examples/QuickStart3_0/.vscode/tasks.json b/examples/QuickStart3_0/.vscode/tasks.json new file mode 100644 index 0000000..500b667 --- /dev/null +++ b/examples/QuickStart3_0/.vscode/tasks.json @@ -0,0 +1,18 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Build QuickStart for .NET Core 3.0", + "command": "dotnet", + "type": "process", + "group": "build", + "args": [ + "build", + "${workspaceFolder}/QuickStart3_0.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/examples/QuickStart3_0/Controllers/WeatherForecastController.cs b/examples/QuickStart3_0/Controllers/WeatherForecastController.cs new file mode 100644 index 0000000..0da2dbf --- /dev/null +++ b/examples/QuickStart3_0/Controllers/WeatherForecastController.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; + +namespace QuickStart3_0.Controllers +{ + [ApiController] + [Route("[controller]")] + public class WeatherForecastController : ControllerBase + { + private static readonly string[] Summaries = new[] + { + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + }; + + private readonly ILogger _logger; + + public WeatherForecastController(ILogger logger) + { + _logger = logger; + } + + [HttpGet] + public IEnumerable Get() + { + SimulateDelay(); + var rng = new Random(); + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateTime.Now.AddDays(index), + TemperatureC = rng.Next(-20, 55), + Summary = Summaries[rng.Next(Summaries.Length)] + }) + .ToArray(); + } + + private void SimulateDelay() + { + // Delay for 500ms to 2s to simulate a bottleneck. + Thread.Sleep((new Random()).Next(500, 2000)); + } + } +} diff --git a/examples/QuickStart3_0/Program.cs b/examples/QuickStart3_0/Program.cs new file mode 100644 index 0000000..11a312d --- /dev/null +++ b/examples/QuickStart3_0/Program.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace QuickStart3_0 +{ + public class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); + } +} diff --git a/examples/QuickStart3_0/QuickStart3_0.csproj b/examples/QuickStart3_0/QuickStart3_0.csproj new file mode 100644 index 0000000..52979f1 --- /dev/null +++ b/examples/QuickStart3_0/QuickStart3_0.csproj @@ -0,0 +1,15 @@ + + + + netcoreapp3.0 + + + + + + + + + + + diff --git a/examples/QuickStart3_0/Readme.md b/examples/QuickStart3_0/Readme.md new file mode 100644 index 0000000..f17a6b5 --- /dev/null +++ b/examples/QuickStart3_0/Readme.md @@ -0,0 +1,147 @@ +# Quick Start to build an ASP.NET Core 3.0 WebAPI with Profiler (Part I) + +In this example, we will walk through the steps to build an ASP.NET Core 3.0 WebAPI with Application Insights Profiler enabled and run on Windows. The same steps work for .NET Core 2.2 application too. + +Then, in the second part, we will containerized it to a Linux container. + +## Prerequisites + +1. [.NET Core **SDK** 3.0.100](https://dotnet.microsoft.com/download). +1. [An instrumentation key](https://docs.microsoft.com/en-us/azure/azure-monitor/app/create-new-resource) associated with a valid application insights resource in Azure. + +## Get started + +### Create an application + +```shell +dotnet new webapi +``` + +### Add package reference + +The latest Application Insights (2.8+) is required to run on .NET Core 3.0. And the profiler NuGet package, of course. + +```shell +dotnet add package Microsoft.ApplicationInsights.AspNetCore +dotnet add package Microsoft.ApplicationInsights.Profiler.AspNetCore -v 2.0.0-* +``` + +### Update the code in `Startup.cs` to enable application insights and the profiler + +```csharp + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + ... + services.AddControllers(); + // Adding the following lines to enable application insights and profiler. + services.AddApplicationInsightsTelemetry(); + services.AddServiceProfiler(); + } +``` + +### Optionally, add a bottleneck + +To make it fun, make use the following code to add some delay in the controllers to simulate the bottleneck: + +```csharp +using System.Threading; +... +private void SimulateDelay() +{ + // Delay for 500ms to 2s to simulate a bottleneck. + Thread.Sleep((new Random()).Next(500, 2000)); +} +``` + +And then, call it from the controller: + +```csharp +[HttpGet] +public IEnumerable Get() +{ + SimulateDelay(); + var rng = new Random(); + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + ... +} +``` + +### Setup the instrumentation key for debugging + +In [appsettings.Development.json](./appsettings.Development.json), add the following configuration: + +```json +{ + ... + "ApplicationInsights": { + "InstrumentationKey": "replace-with-your-instrumentation-key" + } + ... +} +``` + +Optionally, change the logging levels that the log will become more relevant. Refer [appsettings.Development.json](./appsettings.Development.json) for a full example. + +### Generate traffic for profiling + +At the beginning of the application, **OneTimeSchedulingPolicy** will immediately kick in, profiling for 2 minutes. Let's hit the endpoint in a browser during the profiling session: + +```shell +https://localhost:5001/weatherforecast +``` + +It is suggested to hit the endpoint 10 more times since not all the samples are going to be valid. After 2 minutes, you will see logs like this: + +```log +D:\Repos\fork-ai-profiler\examples\QuickStart3_0> dotnet run +info: ServiceProfiler.EventPipe.Client.ServiceProfilerProvider[0] + Service Profiler session started. +info: Microsoft.Hosting.Lifetime[0] + Now listening on: https://localhost:5001 +info: Microsoft.Hosting.Lifetime[0] + Now listening on: http://localhost:5000 +info: Microsoft.Hosting.Lifetime[0] + Application started. Press Ctrl+C to shut down. +info: Microsoft.Hosting.Lifetime[0] + Hosting environment: Development +info: Microsoft.Hosting.Lifetime[0] + Content root path: D:\Repos\fork-ai-profiler\examples\QuickStart3_0 +warn: ServiceProfiler.EventPipe.Client.TraceValidators.ActivityListValidator[0] + All activities are not found in the trace. First one: Stop/#19500/1/101/. +warn: ServiceProfiler.EventPipe.Client.ServiceProfilerProvider[0] + Matched sample count does not equal to gathered sample count. Expected: 93, Actual: 71 +info: ServiceProfiler.EventPipe.Client.ServiceProfilerProvider[0] + Trace validation result: True +info: ServiceProfiler.EventPipe.Upload.TraceUploader[0] + Service Profiler trace uploaded. +info: ServiceProfiler.EventPipe.Client.TraceUploader.TraceUploaderProxy[0] + Finished calling trace uploader. Exit code: 0 +info: ServiceProfiler.EventPipe.Client.ServiceProfilerProvider[0] + Service Profiler session finished. Samples: 93 +``` + +### Open the trace form Azure Portal + +Get a coffee and wait for a couple of minutes - the backend needs some time, usually a 2 minutes, to ingest the data. + +Then, open the application insights resource in Azure Portal, go to the **performance** blade, and use the button of `Configure Profiler`. There, you are going to see all profiling sessions: + +![Profiler Trace Sessions](../../media/OneTimeProfilerTrace.png) + +_Tip: Click on the trace to open the trace analyzer._ + +### Try Profile Now + +Keep the application running, click `Profile Now` on the page, you will see from the log that another trace session has been started: + +```log +info: ServiceProfiler.EventPipe.Client.ServiceProfilerProvider[0] + Service Profiler session started. +``` + +Now, hit the endpoint in the browsers to generate some traffic again. + +And when the session finished, it will show up in the trace session list: + +![Profile Trace Sessions with Profile Now](../../media/OnDemandProfilerTrace.png) diff --git a/examples/QuickStart3_0/Readme2.md b/examples/QuickStart3_0/Readme2.md new file mode 100644 index 0000000..ea4ede2 --- /dev/null +++ b/examples/QuickStart3_0/Readme2.md @@ -0,0 +1,57 @@ +# Quick Start to build an ASP.NET Core 3.0 WebAPI with Profiler (Part II) + +In [the last post](./Readme.md), we walked through how to build an application with Application Insights Profiler on locally. In this post, we are going to containerize the app and get it run inside a container. + +## Prerequisites + +1. Finish [part I](./Readme.md) to have a working application with Profiler on. +1. [Docker Desktop on Windows](https://docs.docker.com/docker-for-windows/install/). + +## Get started + +### Create a Dockerfile for the application + +Since we already have a working project, just follow the [dockerfile example](https://docs.docker.com/engine/examples/dotnetcore/) from the docker documentation with the following tweaks: + +1. For ASP.NET Core 3.0, update the base images. + + Find the base images for ASP.NET Core [on the dockerhub](https://hub.docker.com/_/microsoft-dotnet-core). + + Specifically, we need [an SDK image](https://hub.docker.com/_/microsoft-dotnet-core-sdk/) and [a ASP.NET Core runtime image](https://hub.docker.com/_/microsoft-dotnet-core-aspnet/) and update the image names in the dockerfile. + + At the moment, actually the changes required are change the tags to `3.0` from `2.2` for both `build-env` and for the runtime image. + +1. Set the environment variable to provide instrumentation for release build of the application: + + ```dockerfile + ENV APPINSIGHTS_INSTRUMENTATIONKEY YOUR_APPLICATION_INSIGHTS_KE + ``` + +1. Update the entry point toward the end of the file to pick up the proper assembly. + +A full example could be found [here](./dockerfile). + +### Build and start the container + +Here's some shorthands for building and running the container: + +```shell +docker build -t quickstart30:0.0.1 . +docker run -p 8080:80 --name aiprofiler-quickstart quickstart30:0.0.1 +``` + +Let's generate traffic for the following endpoint this time: + +```shell +http://localhost:8080/weatherforecast +``` + +And as we did before, we will wait for 2 minutes to let the data ingest after the profiling session. + +You will be able to get the same result as it is running locally. + +### Delete the container after the testing + +```shell +docker container rm aiprofiler-quickstart -f +``` diff --git a/examples/QuickStart3_0/Startup.cs b/examples/QuickStart3_0/Startup.cs new file mode 100644 index 0000000..780a316 --- /dev/null +++ b/examples/QuickStart3_0/Startup.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.HttpsPolicy; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace QuickStart3_0 +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddControllers(); + services.AddApplicationInsightsTelemetry(); + services.AddServiceProfiler(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseHttpsRedirection(); + + app.UseRouting(); + + app.UseAuthorization(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + } + } +} diff --git a/examples/QuickStart3_0/WeatherForecast.cs b/examples/QuickStart3_0/WeatherForecast.cs new file mode 100644 index 0000000..21ffa27 --- /dev/null +++ b/examples/QuickStart3_0/WeatherForecast.cs @@ -0,0 +1,15 @@ +using System; + +namespace QuickStart3_0 +{ + public class WeatherForecast + { + public DateTime Date { get; set; } + + public int TemperatureC { get; set; } + + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + + public string Summary { get; set; } + } +} diff --git a/examples/QuickStart3_0/appsettings.Development.json b/examples/QuickStart3_0/appsettings.Development.json new file mode 100644 index 0000000..cb5e36a --- /dev/null +++ b/examples/QuickStart3_0/appsettings.Development.json @@ -0,0 +1,11 @@ +{ + "ApplicationInsights": { + "InstrumentationKey": "your-instrumentation-key" + }, + "Logging": { + "LogLevel": { + "Default": "Warning", + "ServiceProfiler": "Information" + } + } +} \ No newline at end of file diff --git a/examples/QuickStart3_0/appsettings.json b/examples/QuickStart3_0/appsettings.json new file mode 100644 index 0000000..d9d9a9b --- /dev/null +++ b/examples/QuickStart3_0/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} diff --git a/examples/QuickStart3_0/dockerfile b/examples/QuickStart3_0/dockerfile new file mode 100644 index 0000000..b091d0a --- /dev/null +++ b/examples/QuickStart3_0/dockerfile @@ -0,0 +1,17 @@ +FROM mcr.microsoft.com/dotnet/core/sdk:3.0 AS build-env +WORKDIR /app + +# Copy csproj and restore as distinct layers +COPY *.csproj ./ +RUN dotnet restore + +# Copy everything else and build +COPY . ./ +RUN dotnet publish -c Release -o out + +# Build runtime image +FROM mcr.microsoft.com/dotnet/core/aspnet:3.0 +ENV APPINSIGHTS_INSTRUMENTATIONKEY ***your-instrumentation-key*** +WORKDIR /app +COPY --from=build-env /app/out . +ENTRYPOINT ["dotnet", "QuickStart3_0.dll"] \ No newline at end of file diff --git a/media/OnDemandProfilerTrace.png b/media/OnDemandProfilerTrace.png new file mode 100644 index 0000000..0ba76f6 Binary files /dev/null and b/media/OnDemandProfilerTrace.png differ diff --git a/media/OneTimeProfilerTrace.png b/media/OneTimeProfilerTrace.png new file mode 100644 index 0000000..952a29d Binary files /dev/null and b/media/OneTimeProfilerTrace.png differ diff --git a/media/profiler-traces.png b/media/profiler-traces.png index e9e0b3e..0304c89 100644 Binary files a/media/profiler-traces.png and b/media/profiler-traces.png differ