From 8fee01b5439ad7780e2d6782a642c36627c44970 Mon Sep 17 00:00:00 2001 From: Saar Shen Date: Fri, 16 Aug 2019 13:36:13 -0700 Subject: [PATCH] Examples/generic host (#194) * Update the code * Clean up the code a bit * Add readme for the exmaple --- examples/.vscode/launch.json | 8 +- examples/.vscode/tasks.json | 13 ++ examples/GenericHost/Readme.md | 150 ++++++++++++++++++ examples/GenericHost/media/result.png | Bin 0 -> 41623 bytes .../GenericHost/src/AIK8sGenericHost.csproj | 16 ++ examples/GenericHost/src/Dockerfile | 16 ++ examples/GenericHost/src/K8s.yaml | 14 ++ examples/GenericHost/src/Program.cs | 63 ++++++++ .../GenericHost/src/SendAIEventService.cs | 37 +++++ 9 files changed, 313 insertions(+), 4 deletions(-) create mode 100644 examples/GenericHost/Readme.md create mode 100644 examples/GenericHost/media/result.png create mode 100644 examples/GenericHost/src/AIK8sGenericHost.csproj create mode 100644 examples/GenericHost/src/Dockerfile create mode 100644 examples/GenericHost/src/K8s.yaml create mode 100644 examples/GenericHost/src/Program.cs create mode 100644 examples/GenericHost/src/SendAIEventService.cs diff --git a/examples/.vscode/launch.json b/examples/.vscode/launch.json index d285367..5c74779 100644 --- a/examples/.vscode/launch.json +++ b/examples/.vscode/launch.json @@ -5,14 +5,14 @@ "version": "0.2.0", "configurations": [ { - "name": ".NET Core Launch (console)", + "name": ".NET Core Launch - .NET Generic Host", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "Build Example - .NET Generic Host", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/BasicConsoleAppILogger/bin/Debug/netcoreapp2.2/BasicConsoleAppILogger.dll", + "program": "${workspaceFolder}/GenericHost/src/bin/Debug/netcoreapp2.2/AIK8sGenericHost.dll", "args": [], - "cwd": "${workspaceFolder}/BasicConsoleAppILogger", + "cwd": "${workspaceFolder}/GenericHost/src", // For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window "console": "internalConsole", "stopAtEntry": false diff --git a/examples/.vscode/tasks.json b/examples/.vscode/tasks.json index 2d37e05..b80f84f 100644 --- a/examples/.vscode/tasks.json +++ b/examples/.vscode/tasks.json @@ -79,5 +79,18 @@ "cwd": "${workspaceFolder}/WindowsContainer/" } }, + { + "label": "Build Example - .NET Generic Host", + "command": "dotnet", + "type": "shell", + "group": "build", + "problemMatcher":"$msCompile", + "args": [ + "build" + ], + "options": { + "cwd": "${workspaceFolder}/GenericHost/src/" + } + } ] } \ No newline at end of file diff --git a/examples/GenericHost/Readme.md b/examples/GenericHost/Readme.md new file mode 100644 index 0000000..17544a1 --- /dev/null +++ b/examples/GenericHost/Readme.md @@ -0,0 +1,150 @@ +# Use Application Insights for Kubernetes in .NET Generic Host project + +This is an example of enabling Application Insights for Kubernetes in .NET Generic Host project. If you are looking into enabling profiler on a plain Console Application, refer to [Enable Application Insights for Kubernetes in .NET Core Console Application](../BasicConsoleAppILogger/Readme.md). + +## Why .NET Generic Host + +According to [.NET Generic Host](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-2.2): + +> "The purpose of Generic Host is to decouple the HTTP pipeline from the Web Host API to enable a wider array of host scenarios. Messaging, background tasks, and other non-HTTP workloads based on Generic Host benefit from cross-cutting capabilities, such as configuration, dependency injection (DI), and logging." + +And also notice: +> Generic Host is new in ASP.NET Core 2.1 and isn't suitable for web hosting scenarios. For web hosting scenarios, use the Web Host. Generic Host will replace Web Host in a future release and act as the primary host API in both HTTP and non-HTTP scenarios. + +Now that you know what the .NET Generic Host is used for, lets dive in. + +## Walk-through + +### Create an empty console app + +```bash +dotnet new console -n AIK8sGenericHost +``` + +### Adding necessary packages + +```bash +dotnet add package Microsoft.Extensions.Hosting +dotnet add package Microsoft.Extensions.DependencyInjection +dotnet add package Microsoft.Extensions.Logging.ApplicationInsights +dotnet add package Microsoft.Extensions.Logging.Console +``` + +Reference to [AIK8sGenericHost.csproj](./src/AIK8sGenericHost.csproj) for the final results. + +### Set up a host + +```csharp +using System.Threading.Tasks; +using Microsoft.Extensions.Hosting; + +namespace AIK8sGenericHost +{ + class Program + { + public static async Task Main(string[] args) + { + var host = new HostBuilder() + .Build(); + + await host.RunAsync(); + } + } +} +``` + +### Enable Application Insights and its Kubernetes enricher + +```csharp + var host = new HostBuilder() + .ConfigureServices((context, services) => + { + var channel = new InMemoryChannel(); + + // Add application insights for Kubernetes. Making sure this is called before services.Configure(). + services.AddApplicationInsightsKubernetesEnricher(); + + services.Configure( + (config) => + { + config.TelemetryChannel = channel; + } + ); + + // Add the logging pipelines to use. We are using Application Insights only here. + services.AddLogging(builder => + { + // Optional: Apply filters to configure LogLevel Trace or above is sent to + // Application Insights for all categories. + builder.AddFilter + ("", LogLevel.Trace); + builder.AddApplicationInsights("--YourAIKeyHere--"); + }); + + // Register your services that implemented IHostedService interface. For example, SendAIEventService. You will need to uncomment this later. + // services.AddHostedService(); + }).Build(); +``` + +Largely, those implementations come from [ApplicationInsightsLoggerProvider for .NET Core ILogger logs](https://docs.microsoft.com/en-us/azure/azure-monitor/app/ilogger). + +### Create a hosted service + +Refer to [SendAIEventService](./src/SendAIEventService.cs) for the implementation. + +Now that the service is created, it could be registered into the dependency injection container: + +```csharp +// Register your services that implemented IHostedService interface. For example, SendAIEventService. +services.AddHostedService(); +``` + +### Flush the channel with lifetime methods + +Since the telemetry won't necessary be flushed, we should flush the channel at the end of the life cycle of the host. +One way of doing that is to register to the application lifetime: + +```csharp + IApplicationLifetime lifetime = host.Services.GetRequiredService(); + lifetime.ApplicationStopping.Register(() => + { + channel.Flush(); + // Work around Application Insights issue: + // https://github.com/Microsoft/ApplicationInsights-dotnet/issues/407 + System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2)); + }); +``` + +### Containerize the application + +* Create a docker file like [this](./src/Dockerfile). +* Build and push the images: + +```bash +docker build -t dockeraccount/aik8sgenerichost . +docker push dockeraccount/aik8sgenerichost:latest +``` + +### Deploy it to Kubernetes + +* Create a Kubernetes deployment file like [this](./src/K8s.yaml). +* Deploy it: + +```bash +kubectl create -f K8s.yaml +``` + +For RBAC enabled Kubernetes cluster (AKS for example), you will need to have proper service account bindings. Refer to [here](../BasicUsage_clr21_RBAC/README.MD#setup-the-default-service-account-for-rbac-enabled-cluster) to see how to do it. + +### Result + +Go to the application insights and you will see traces with kubernetes properties. + +![Traces in Application Insights](./media/result.png) + +## References + +* [.NET Generic Host](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-2.2) +* [USING HOSTBUILDER AND THE GENERIC HOST IN .NET CORE MICROSERVICES](https://www.stevejgordon.co.uk/using-generic-host-in-dotnet-core-console-based-microservices) +* [ApplicationInsightsLoggerProvider for .NET Core ILogger logs](https://docs.microsoft.com/en-us/azure/azure-monitor/app/ilogger) + * Specifically, [Console application](https://docs.microsoft.com/en-us/azure/azure-monitor/app/ilogger#console-application) part. diff --git a/examples/GenericHost/media/result.png b/examples/GenericHost/media/result.png new file mode 100644 index 0000000000000000000000000000000000000000..db77db69ffc2392d3f3329b93ebaed64897f4522 GIT binary patch literal 41623 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%0AhKPO5aPX} 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 + + + Exe + netcoreapp2.2 + + + + + + + + + + + diff --git a/examples/GenericHost/src/Dockerfile b/examples/GenericHost/src/Dockerfile new file mode 100644 index 0000000..2b7f9a9 --- /dev/null +++ b/examples/GenericHost/src/Dockerfile @@ -0,0 +1,16 @@ +FROM mcr.microsoft.com/dotnet/core/sdk:2.2 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/runtime:2.2 +WORKDIR /app +COPY --from=build-env /app/out . +ENTRYPOINT ["dotnet", "AIK8sGenericHost.dll"] \ No newline at end of file diff --git a/examples/GenericHost/src/K8s.yaml b/examples/GenericHost/src/K8s.yaml new file mode 100644 index 0000000..12b0ddf --- /dev/null +++ b/examples/GenericHost/src/K8s.yaml @@ -0,0 +1,14 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: ai-k8s-generic-host +spec: + replicas: 1 + template: + metadata: + labels: + app: consoleapp + spec: + containers: + - name: ai-k8s-generic-host-container + image: dockeraccount/aik8sgenerichost:latest \ No newline at end of file diff --git a/examples/GenericHost/src/Program.cs b/examples/GenericHost/src/Program.cs new file mode 100644 index 0000000..e38b36a --- /dev/null +++ b/examples/GenericHost/src/Program.cs @@ -0,0 +1,63 @@ +using System; +using System.Diagnostics; +using System.Threading.Tasks; +using Microsoft.ApplicationInsights.Channel; +using Microsoft.ApplicationInsights.Extensibility; +using Microsoft.ApplicationInsights.Kubernetes.Debugging; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +namespace AIK8sGenericHost +{ + class Program + { + public static async Task Main(string[] args) + { + // Channel is explicitly configured to do flush on it later. + var channel = new InMemoryChannel(); + + var host = new HostBuilder() + .ConfigureServices((context, services) => + { + // Uncomment the following lines for debugging AI.K8s. + // Refer to https://github.com/microsoft/ApplicationInsights-Kubernetes/blob/develop/docs/SelfDiagnostics.MD for details. + // var observer = new ApplicationInsightsKubernetesDiagnosticObserver(DiagnosticLogLevel.Trace); + // ApplicationInsightsKubernetesDiagnosticSource.Instance.Observable.SubscribeWithAdapter(observer); + + // Add application insights for Kubernetes. Making sure this is called before services.Configure(). + services.AddApplicationInsightsKubernetesEnricher(); + + services.Configure( + (config) => + { + config.TelemetryChannel = channel; + } + ); + + // Add the logging pipelines to use. We are using Application Insights only here. + services.AddLogging(builder => + { + // Optional: Apply filters to configure LogLevel Trace or above is sent to + // Application Insights for all categories. + builder.AddFilter + ("", LogLevel.Trace); + builder.AddApplicationInsights("----Your instrumentation key----"); + builder.AddConsole(); + }); + + // Register your services that implemented IHostedService interface. For example, SendAIEventService + services.AddHostedService(); + }).Build(); + + IApplicationLifetime lifetime = host.Services.GetRequiredService(); + lifetime.ApplicationStopping.Register(() => + { + channel.Flush(); + // Work around Application Insights issue: + // https://github.com/Microsoft/ApplicationInsights-dotnet/issues/407 + System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2)); + }); + await host.RunAsync(); + } + } +} diff --git a/examples/GenericHost/src/SendAIEventService.cs b/examples/GenericHost/src/SendAIEventService.cs new file mode 100644 index 0000000..b7261bc --- /dev/null +++ b/examples/GenericHost/src/SendAIEventService.cs @@ -0,0 +1,37 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace AIK8sGenericHost +{ + public class SendAIEventService : IHostedService + { + private readonly ILogger _logger; + + public SendAIEventService(ILogger logger) + { + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + public Task StartAsync(CancellationToken cancellationToken) + { + Task _ = Task.Run(async () => await RunUntilCancelledAsync(cancellationToken)); + return Task.CompletedTask; + } + + public Task StopAsync(CancellationToken cancellationToken) + { + return Task.CompletedTask; + } + + public async Task RunUntilCancelledAsync(CancellationToken cancellationToken) + { + while (!cancellationToken.IsCancellationRequested) + { + _logger.LogInformation("Application Insights for Kubernetes is working . . ."); + await Task.Delay(5000).ConfigureAwait(false); + } + } + } +} \ No newline at end of file