diff --git a/aspnet/Microsoft.ApplicationInsights.Middleware.sln b/aspnet/Microsoft.ApplicationInsights.Middleware.sln new file mode 100644 index 0000000..13037c6 --- /dev/null +++ b/aspnet/Microsoft.ApplicationInsights.Middleware.sln @@ -0,0 +1,32 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.22609.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{2E6DDE9E-8C75-4F9C-8906-08EBDD6E73EF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{62AD20FD-640F-4F99-94EF-96A7581F1CF9}" + ProjectSection(SolutionItems) = preProject + global.json = global.json + EndProjectSection +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.ApplicationInsights.Middleware", "src\AI.MW.P2\Microsoft.ApplicationInsights.Middleware.kproj", "{95EC3635-22E4-4C3A-A066-F5823A0648DA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {95EC3635-22E4-4C3A-A066-F5823A0648DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {95EC3635-22E4-4C3A-A066-F5823A0648DA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {95EC3635-22E4-4C3A-A066-F5823A0648DA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {95EC3635-22E4-4C3A-A066-F5823A0648DA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {95EC3635-22E4-4C3A-A066-F5823A0648DA} = {2E6DDE9E-8C75-4F9C-8906-08EBDD6E73EF} + EndGlobalSection +EndGlobal diff --git a/aspnet/global.json b/aspnet/global.json new file mode 100644 index 0000000..d6a8b85 --- /dev/null +++ b/aspnet/global.json @@ -0,0 +1,6 @@ +{ + "sources": [ "src", "test" ], + "sdk": { + "version": "1.0.0-beta3" + } +} diff --git a/aspnet/src/AI.MW.P2/ApplicationInsightsExtensions.cs b/aspnet/src/AI.MW.P2/ApplicationInsightsExtensions.cs new file mode 100644 index 0000000..353c820 --- /dev/null +++ b/aspnet/src/AI.MW.P2/ApplicationInsightsExtensions.cs @@ -0,0 +1,155 @@ +using Microsoft.ApplicationInsights; +using Microsoft.ApplicationInsights.DataContracts; +using Microsoft.ApplicationInsights.Extensibility; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Hosting; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.RequestContainer; +using Microsoft.Framework.ConfigurationModel; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.Logging; +using System; +using System.Threading.Tasks; + +namespace Microsoft.ApplicationInsights.Middleware +{ + public static class ApplicationInsightsExtensions + { + public static void AddTelemetryClient(this IServiceCollection serviceCollection, IConfiguration configuration) + { + serviceCollection.AddScoped(sp => RegisterClient(sp, configuration)); + } + + public static void UseApplicationInsightsForRequests(this IApplicationBuilder app) + { + app.UseMiddleware(); + } + + public static void UseApplicationInsightsForExceptions(this IApplicationBuilder app) + { + app.UseMiddleware(); + } + + private static TelemetryClient RegisterClient(IServiceProvider serviceProvider, IConfiguration configuration) + { + TelemetryClient client = null; + try + { + string key = configuration.Get("InstrumentationKey"); + + if (string.IsNullOrEmpty(key)) + { + // TODO; check logger for null + serviceProvider.GetService().WriteError("InstrumentationKey not registered"); + return null; + } + + var aiConfig = new TelemetryConfiguration(); + aiConfig.InstrumentationKey = key; + var channel = new Channel.InProcessTelemetryChannel(); + aiConfig.TelemetryChannel = channel; + + var env = serviceProvider.GetService(); + + if (string.Equals(env.EnvironmentName, "Development", StringComparison.OrdinalIgnoreCase)) + { + aiConfig.TelemetryChannel.DeveloperMode = true; + } + + client = new TelemetryClient(aiConfig); + channel.Initialize(aiConfig); + } + catch (Exception e) + { + serviceProvider.GetService().WriteError(e.ToString()); + } + + return client; + } + + private class AppInsightsRequestMiddleware + { + private readonly RequestDelegate _next; + private readonly IServiceProvider _services; + + public AppInsightsRequestMiddleware(RequestDelegate next, IServiceProvider services) + { + _services = services; + _next = next; + } + + public async Task Invoke(HttpContext httpContext) + { + using (var container = RequestServicesContainer.EnsureRequestServices(httpContext, _services)) + { + var client = httpContext.RequestServices.GetService(); + + if (client == null) + { + _services.GetService().WriteError("AI TelemetryClient is not registered."); + } + + var now = DateTime.UtcNow; + + try + { + await _next.Invoke(httpContext); + } + finally + { + if (client != null) + { + var telemetry = new RequestTelemetry( + httpContext.Request.Method + " " + httpContext.Request.Path.Value, + now, + DateTime.UtcNow - now, + httpContext.Response.StatusCode.ToString(), + httpContext.Response.StatusCode < 400); + + client.TrackRequest(telemetry); + } + } + } + } + } + + private class AppInsightsExceptionMiddleware + { + private readonly RequestDelegate _next; + private readonly IServiceProvider _services; + + public AppInsightsExceptionMiddleware(RequestDelegate next, IServiceProvider services) + { + _services = services; + _next = next; + } + + public async Task Invoke(HttpContext httpContext) + { + using (var container = RequestServicesContainer.EnsureRequestServices(httpContext, _services)) + { + var client = httpContext.RequestServices.GetService(); + + if (client == null) + { + _services.GetService().WriteWarning("AI TelemetryClient is not registered."); + } + + try + { + await _next.Invoke(httpContext); + } + catch (Exception exp) + { + if (client != null) + { + client.TrackException(exp); + } + + throw; + } + } + } + } + } +} diff --git a/aspnet/src/AI.MW.P2/Microsoft.ApplicationInsights.Middleware.kproj b/aspnet/src/AI.MW.P2/Microsoft.ApplicationInsights.Middleware.kproj new file mode 100644 index 0000000..0ffea48 --- /dev/null +++ b/aspnet/src/AI.MW.P2/Microsoft.ApplicationInsights.Middleware.kproj @@ -0,0 +1,21 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 95ec3635-22e4-4c3a-a066-f5823a0648da + Microsoft.ApplicationInsights.Middleware + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ + + + Microsoft.ApplicationInsights.Middleware + + + 2.0 + + + \ No newline at end of file diff --git a/aspnet/src/AI.MW.P2/project.json b/aspnet/src/AI.MW.P2/project.json new file mode 100644 index 0000000..cd116e8 --- /dev/null +++ b/aspnet/src/AI.MW.P2/project.json @@ -0,0 +1,22 @@ +{ + "version": "0.30.0.1-beta", + "dependencies": { + "Microsoft.AspNet.Hosting": "1.0.0-beta3", + "Microsoft.Framework.Logging": "1.0.0-beta3", + "Microsoft.AspNet.Http.Extensions": "1.0.0-beta3", + "Microsoft.AspNet.RequestContainer": "1.0.0-beta3", + "Microsoft.ApplicationInsights.Portable": "0.30.0.0-beta" + }, + + "frameworks" : { + "aspnet50" : { + "dependencies": { + } + }, + "aspnetcore50" : { + "dependencies": { + "System.Runtime": "4.0.20-*" + } + } + } +}