Hosting#318 Add middleware analysis tools, sample.
This commit is contained in:
parent
c49547245b
commit
c8990bcc29
|
|
@ -44,6 +44,12 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ElmPageSample", "samples\El
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "DatabaseErrorPageSample", "samples\DatabaseErrorPageSample\DatabaseErrorPageSample.xproj", "{FF7F11A1-14E7-4948-A853-2487D99DE0C6}"
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "DatabaseErrorPageSample", "samples\DatabaseErrorPageSample\DatabaseErrorPageSample.xproj", "{FF7F11A1-14E7-4948-A853-2487D99DE0C6}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.MiddlewareAnalysis", "src\Microsoft.AspNet.MiddlewareAnalysis\Microsoft.AspNet.MiddlewareAnalysis.xproj", "{C2DEDD37-D1EB-4819-9A9C-475E37A52358}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "MiddlewareAnalysisSample", "samples\MiddlewareAnalysisSample\MiddlewareAnalysisSample.xproj", "{95981429-F212-44E1-83AA-32DA9E2A517C}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.MiddlewareAnalysis.Tests", "test\Microsoft.AspNet.MiddlewareAnalysis.Tests\Microsoft.AspNet.MiddlewareAnalysis.Tests.xproj", "{B0166AED-738F-42EE-AF4D-C487C8B21521}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|
@ -220,6 +226,42 @@ Global
|
||||||
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Release|x86.ActiveCfg = Release|Any CPU
|
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Release|x86.Build.0 = Release|Any CPU
|
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||||
|
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||||
|
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
|
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
|
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||||
|
{95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||||
|
{95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{95981429-F212-44E1-83AA-32DA9E2A517C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{95981429-F212-44E1-83AA-32DA9E2A517C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{95981429-F212-44E1-83AA-32DA9E2A517C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
|
{95981429-F212-44E1-83AA-32DA9E2A517C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
|
{95981429-F212-44E1-83AA-32DA9E2A517C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{95981429-F212-44E1-83AA-32DA9E2A517C}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||||
|
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||||
|
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
|
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
|
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
@ -240,5 +282,8 @@ Global
|
||||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D}
|
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D}
|
||||||
{FFD28DCF-C24F-4C59-9B6B-F3B74CE13129} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
|
{FFD28DCF-C24F-4C59-9B6B-F3B74CE13129} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
|
||||||
{FF7F11A1-14E7-4948-A853-2487D99DE0C6} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
|
{FF7F11A1-14E7-4948-A853-2487D99DE0C6} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
|
||||||
|
{C2DEDD37-D1EB-4819-9A9C-475E37A52358} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D}
|
||||||
|
{95981429-F212-44E1-83AA-32DA9E2A517C} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
|
||||||
|
{B0166AED-738F-42EE-AF4D-C487C8B21521} = {2AF90579-B118-4583-AE88-672EFACB5BC4}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>95981429-f212-44e1-83aa-32da9e2a517c</ProjectGuid>
|
||||||
|
<RootNamespace>MiddlewareAnalysisSample</RootNamespace>
|
||||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
<DevelopmentServerPort>2764</DevelopmentServerPort>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using Microsoft.AspNet.Builder;
|
||||||
|
using Microsoft.AspNet.Http;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.DiagnosticAdapter;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace MiddlewareAnaysisSample
|
||||||
|
{
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddMiddlewareAnalysis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Configure(IApplicationBuilder app, ILoggerFactory factory, DiagnosticListener diagnosticListener)
|
||||||
|
{
|
||||||
|
// Displays all log levels
|
||||||
|
factory.AddConsole(LogLevel.Verbose);
|
||||||
|
|
||||||
|
// Listen for middleware events and log them to the console.
|
||||||
|
var listener = new TestDiagnosticListener();
|
||||||
|
diagnosticListener.SubscribeWithAdapter(listener);
|
||||||
|
|
||||||
|
// Build our application pipeline
|
||||||
|
|
||||||
|
// Named via app.UseMiddleware<T>()
|
||||||
|
app.UseDeveloperExceptionPage();
|
||||||
|
app.UseIISPlatformHandler();
|
||||||
|
|
||||||
|
// Anonymous method inline middleware
|
||||||
|
app.Use((context, next) =>
|
||||||
|
{
|
||||||
|
// No-op
|
||||||
|
return next();
|
||||||
|
});
|
||||||
|
|
||||||
|
app.Map("/map", subApp =>
|
||||||
|
{
|
||||||
|
subApp.Run(context =>
|
||||||
|
{
|
||||||
|
return context.Response.WriteAsync("Hello World");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Low level anonymous method inline middleware, named Diagnostics.Middleware.Analysis.Startup+<>c by default
|
||||||
|
app.Use(next =>
|
||||||
|
{
|
||||||
|
return context =>
|
||||||
|
{
|
||||||
|
return next(context);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
app.Map("/throw", throwApp =>
|
||||||
|
{
|
||||||
|
throwApp.Run(context => { throw new Exception("Application Exception"); });
|
||||||
|
});
|
||||||
|
|
||||||
|
// The home page.
|
||||||
|
app.Properties["analysis.NextMiddlewareName"] = "HomePage";
|
||||||
|
app.Use(async (context, next) =>
|
||||||
|
{
|
||||||
|
if (context.Request.Path == "/")
|
||||||
|
{
|
||||||
|
context.Response.ContentType = "text/html";
|
||||||
|
await context.Response.WriteAsync("<html><body>Welcome to the sample<br><br>\r\n");
|
||||||
|
await context.Response.WriteAsync("Click here to take a side branch: <a href=\"/map/foo\">Map</a><br>\r\n");
|
||||||
|
await context.Response.WriteAsync("Click here to throw an exception: <a href=\"/throw\">Throw</a><br>\r\n");
|
||||||
|
await context.Response.WriteAsync("Click here to for a 404: <a href=\"/404\">404</a><br>\r\n");
|
||||||
|
await context.Response.WriteAsync("</body></html>\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await next();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Note there's always a default 404 middleware at the end of the pipeline.
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TestDiagnosticListener
|
||||||
|
{
|
||||||
|
[DiagnosticName("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareStarting")]
|
||||||
|
public virtual void OnMiddlewareStarting(HttpContext httpContext, string name)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"MiddlewareStarting: {name}; {httpContext.Request.Path}");
|
||||||
|
}
|
||||||
|
|
||||||
|
[DiagnosticName("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareException")]
|
||||||
|
public virtual void OnMiddlewareException(Exception exception, string name)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"MiddlewareException: {name}; {exception.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
[DiagnosticName("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareFinished")]
|
||||||
|
public virtual void OnMiddlewareFinished(HttpContext httpContext, string name)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"MiddlewareFinished: {name}; {httpContext.Response.StatusCode}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.AspNet.Diagnostics": "1.0.0-*",
|
||||||
|
"Microsoft.AspNet.IISPlatformHandler": "1.0.0-*",
|
||||||
|
"Microsoft.AspNet.MiddlewareAnalysis": "1.0.0-*",
|
||||||
|
"Microsoft.AspNet.Server.Kestrel": "1.0.0-*",
|
||||||
|
"Microsoft.AspNet.Server.WebListener": "1.0.0-*",
|
||||||
|
"Microsoft.Extensions.DiagnosticAdapter": "1.0.0-*",
|
||||||
|
"Microsoft.Extensions.Logging.Console": "1.0.0-*"
|
||||||
|
},
|
||||||
|
"commands": {
|
||||||
|
"web": "Microsoft.AspNet.Server.Kestrel",
|
||||||
|
"weblistener": "Microsoft.AspNet.Server.WebListener"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"dnx451": { },
|
||||||
|
"dnxcore50": { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.AspNet.Builder;
|
||||||
|
using Microsoft.AspNet.Http;
|
||||||
|
using Microsoft.AspNet.Http.Features;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.MiddlewareAnalysis
|
||||||
|
{
|
||||||
|
public class AnalysisBuilder : IApplicationBuilder
|
||||||
|
{
|
||||||
|
private const string NextMiddlewareName = "analysis.NextMiddlewareName";
|
||||||
|
|
||||||
|
public AnalysisBuilder(IApplicationBuilder inner)
|
||||||
|
{
|
||||||
|
InnerBuilder = inner;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IApplicationBuilder InnerBuilder { get; }
|
||||||
|
|
||||||
|
public IServiceProvider ApplicationServices
|
||||||
|
{
|
||||||
|
get { return InnerBuilder.ApplicationServices; }
|
||||||
|
set { InnerBuilder.ApplicationServices = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDictionary<string, object> Properties
|
||||||
|
{
|
||||||
|
get { return InnerBuilder.Properties; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IFeatureCollection ServerFeatures
|
||||||
|
{
|
||||||
|
get { return InnerBuilder.ServerFeatures;}
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestDelegate Build()
|
||||||
|
{
|
||||||
|
// Add one maker at the end before the default 404 middleware (or any fancy Join middleware).
|
||||||
|
return InnerBuilder.UseMiddleware<AnalysisMiddleware>("EndOfPipeline")
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IApplicationBuilder New()
|
||||||
|
{
|
||||||
|
return new AnalysisBuilder(InnerBuilder.New());
|
||||||
|
}
|
||||||
|
|
||||||
|
public IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware)
|
||||||
|
{
|
||||||
|
string middlewareName = string.Empty; // UseMiddleware doesn't work with null params.
|
||||||
|
object middlewareNameObj;
|
||||||
|
if (Properties.TryGetValue(NextMiddlewareName, out middlewareNameObj))
|
||||||
|
{
|
||||||
|
middlewareName = middlewareNameObj?.ToString();
|
||||||
|
Properties.Remove(NextMiddlewareName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return InnerBuilder.UseMiddleware<AnalysisMiddleware>(middlewareName)
|
||||||
|
.Use(middleware);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Http;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.MiddlewareAnalysis
|
||||||
|
{
|
||||||
|
public class AnalysisMiddleware
|
||||||
|
{
|
||||||
|
private readonly RequestDelegate _next;
|
||||||
|
private readonly DiagnosticSource _diagnostics;
|
||||||
|
private readonly string _middlewareName;
|
||||||
|
|
||||||
|
public AnalysisMiddleware(RequestDelegate next, DiagnosticSource diagnosticSource, string middlewareName)
|
||||||
|
{
|
||||||
|
_next = next;
|
||||||
|
_diagnostics = diagnosticSource;
|
||||||
|
if (string.IsNullOrEmpty(middlewareName))
|
||||||
|
{
|
||||||
|
middlewareName = next.Target.GetType().FullName;
|
||||||
|
}
|
||||||
|
_middlewareName = middlewareName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Invoke(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
if (_diagnostics.IsEnabled("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareStarting"))
|
||||||
|
{
|
||||||
|
_diagnostics.Write("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareStarting", new { name = _middlewareName, httpContext = httpContext });
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _next(httpContext);
|
||||||
|
|
||||||
|
if (_diagnostics.IsEnabled("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareFinished"))
|
||||||
|
{
|
||||||
|
_diagnostics.Write("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareFinished", new { name = _middlewareName, httpContext = httpContext });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (_diagnostics.IsEnabled("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareException"))
|
||||||
|
{
|
||||||
|
_diagnostics.Write("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareException", new { name = _middlewareName, httpContext = httpContext, exception = ex });
|
||||||
|
}
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using Microsoft.AspNet.Hosting;
|
||||||
|
using Microsoft.AspNet.MiddlewareAnalysis;
|
||||||
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
|
|
||||||
|
namespace Microsoft.Extensions.DependencyInjection
|
||||||
|
{
|
||||||
|
public static class AnalysisServiceCollectionExtensions
|
||||||
|
{
|
||||||
|
public static IServiceCollection AddMiddlewareAnalysis(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
// This should prevent AnalysisStartupFilter from being registered more than once.
|
||||||
|
services.TryAddEnumerable(ServiceDescriptor.Transient<IStartupFilter, AnalysisStartupFilter>());
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Microsoft.AspNet.Builder;
|
||||||
|
using Microsoft.AspNet.Hosting;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.MiddlewareAnalysis
|
||||||
|
{
|
||||||
|
public class AnalysisStartupFilter : IStartupFilter
|
||||||
|
{
|
||||||
|
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
|
||||||
|
{
|
||||||
|
return builder =>
|
||||||
|
{
|
||||||
|
var wrappedBuilder = new AnalysisBuilder(builder);
|
||||||
|
next(wrappedBuilder);
|
||||||
|
|
||||||
|
// The caller doesn't call build on our new builder, they call it on the original. Add this
|
||||||
|
// default middleware to the end. Compare with AnalysisBuilder.Build();
|
||||||
|
|
||||||
|
// Add one maker at the end before the default 404 middleware (or any fancy Join middleware).
|
||||||
|
builder.UseMiddleware<AnalysisMiddleware>("EndOfPipeline");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>c2dedd37-d1eb-4819-9a9c-475e37a52358</ProjectGuid>
|
||||||
|
<RootNamespace>Microsoft.AspNet.MiddlewareAnalysis</RootNamespace>
|
||||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Resources;
|
||||||
|
|
||||||
|
[assembly: AssemblyMetadata("Serviceable", "True")]
|
||||||
|
[assembly: NeutralResourcesLanguage("en-US")]
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
"description": "ASP.NET 5 Middleware for analyzing middleware in the request pipeline.",
|
||||||
|
"compilationOptions": {
|
||||||
|
"warningsAsErrors": true,
|
||||||
|
"keyFile": "../../tools/Key.snk"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git://github.com/aspnet/diagnostics"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.AspNet.Hosting.Abstractions": "1.0.0-*",
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions": "1.0.0-*",
|
||||||
|
"System.Diagnostics.DiagnosticSource": "4.0.0-beta-*"
|
||||||
|
},
|
||||||
|
|
||||||
|
"frameworks": {
|
||||||
|
"net451": { },
|
||||||
|
"dotnet5.4": { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0.23107" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.23107</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>b0166aed-738f-42ee-af4d-c487c8b21521</ProjectGuid>
|
||||||
|
<RootNamespace>Microsoft.AspNet.MiddlewareAnalysis.Tests</RootNamespace>
|
||||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Builder;
|
||||||
|
using Microsoft.AspNet.TestHost;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.MiddlewareAnalysis
|
||||||
|
{
|
||||||
|
public class MiddlewareAnalysisTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task ExceptionWrittenToDiagnostics()
|
||||||
|
{
|
||||||
|
DiagnosticListener diagnosticListener = null;
|
||||||
|
|
||||||
|
var server = TestServer.Create(app =>
|
||||||
|
{
|
||||||
|
diagnosticListener = app.ApplicationServices.GetRequiredService<DiagnosticListener>();
|
||||||
|
|
||||||
|
app.UseDeveloperExceptionPage();
|
||||||
|
app.Run(context =>
|
||||||
|
{
|
||||||
|
throw new Exception("Test exception");
|
||||||
|
});
|
||||||
|
}, services => services.AddMiddlewareAnalysis());
|
||||||
|
|
||||||
|
var listener = new TestDiagnosticListener();
|
||||||
|
diagnosticListener.SubscribeWithAdapter(listener);
|
||||||
|
|
||||||
|
await server.CreateClient().GetAsync(string.Empty);
|
||||||
|
|
||||||
|
// "Microsoft.AspnNet.Hosting.RequestServicesContainerMiddleware","Microsoft.AspnNet.Diagnostics.DeveloperExceptionPageMiddleware",
|
||||||
|
// "Microsoft.AspNet.MiddlewareAnalysis.MiddlewareAnalysisTests.+<>c"
|
||||||
|
Assert.Equal(3, listener.MiddlewareStarting.Count);
|
||||||
|
Assert.Equal("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareAnalysisTests+<>c", listener.MiddlewareStarting[2]);
|
||||||
|
// reversed "RunInlineMiddleware"
|
||||||
|
Assert.Equal(1, listener.MiddlewareException.Count);
|
||||||
|
Assert.Equal("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareAnalysisTests+<>c", listener.MiddlewareException[0]);
|
||||||
|
// reversed "Microsoft.AspnNet.Diagnostics.DeveloperExceptionPageMiddleware","Microsoft.AspnNet.Hosting.RequestServicesContainerMiddleware"
|
||||||
|
Assert.Equal(2, listener.MiddlewareFinished.Count);
|
||||||
|
Assert.Equal("Microsoft.AspNet.Diagnostics.DeveloperExceptionPageMiddleware", listener.MiddlewareFinished[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.AspNet.Http;
|
||||||
|
using Microsoft.Extensions.DiagnosticAdapter;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.MiddlewareAnalysis
|
||||||
|
{
|
||||||
|
public class TestDiagnosticListener
|
||||||
|
{
|
||||||
|
public IList<string> MiddlewareStarting { get; } = new List<string>();
|
||||||
|
public IList<string> MiddlewareFinished { get; } = new List<string>();
|
||||||
|
public IList<string> MiddlewareException { get; } = new List<string>();
|
||||||
|
|
||||||
|
[DiagnosticName("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareStarting")]
|
||||||
|
public virtual void OnMiddlewareStarting(HttpContext httpContext, string name)
|
||||||
|
{
|
||||||
|
MiddlewareStarting.Add(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
[DiagnosticName("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareException")]
|
||||||
|
public virtual void OnMiddlewareException(Exception exception, string name)
|
||||||
|
{
|
||||||
|
MiddlewareException.Add(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
[DiagnosticName("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareFinished")]
|
||||||
|
public virtual void OnMiddlewareFinished(HttpContext httpContext, string name)
|
||||||
|
{
|
||||||
|
MiddlewareFinished.Add(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"compilationOptions": {
|
||||||
|
"warningsAsErrors": false
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.AspNet.Diagnostics": "1.0.0-*",
|
||||||
|
"Microsoft.AspNet.MiddlewareAnalysis": "1.0.0-*",
|
||||||
|
"Microsoft.AspNet.TestHost": "1.0.0-*",
|
||||||
|
"Microsoft.AspNet.Testing": "1.0.0-*",
|
||||||
|
"Microsoft.Extensions.DependencyInjection": "1.0.0-*",
|
||||||
|
"Microsoft.Extensions.DiagnosticAdapter": "1.0.0-*",
|
||||||
|
"xunit.runner.aspnet": "2.0.0-aspnet-*"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"dnx451": {},
|
||||||
|
"dnxcore50": {}
|
||||||
|
},
|
||||||
|
"commands": {
|
||||||
|
"test": "xunit.runner.aspnet"
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue