#353,#354 Add telemetry for begin/end request and unhandled exceptions.
This commit is contained in:
parent
10176373c8
commit
6758010e1a
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Tracing;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Microsoft.AspNet.Builder;
|
||||
|
|
@ -82,6 +83,7 @@ namespace Microsoft.AspNet.Hosting.Internal
|
|||
var logger = _applicationServices.GetRequiredService<ILogger<HostingEngine>>();
|
||||
var contextFactory = _applicationServices.GetRequiredService<IHttpContextFactory>();
|
||||
var contextAccessor = _applicationServices.GetRequiredService<IHttpContextAccessor>();
|
||||
var telemetrySource = _applicationServices.GetRequiredService<TelemetrySource>();
|
||||
var server = ServerFactory.Start(_serverInstance,
|
||||
async features =>
|
||||
{
|
||||
|
|
@ -89,10 +91,32 @@ namespace Microsoft.AspNet.Hosting.Internal
|
|||
httpContext.ApplicationServices = _applicationServices;
|
||||
var requestIdentifier = GetRequestIdentifier(httpContext);
|
||||
|
||||
using (logger.BeginScope("Request Id: {RequestId}", requestIdentifier))
|
||||
if (telemetrySource.IsEnabled("Microsoft.AspNet.Hosting.BeginRequest"))
|
||||
{
|
||||
contextAccessor.HttpContext = httpContext;
|
||||
await application(httpContext);
|
||||
telemetrySource.WriteTelemetry("Microsoft.AspNet.Hosting.BeginRequest", new { httpContext = httpContext });
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using (logger.BeginScope("Request Id: {RequestId}", requestIdentifier))
|
||||
{
|
||||
contextAccessor.HttpContext = httpContext;
|
||||
await application(httpContext);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (telemetrySource.IsEnabled("Microsoft.AspNet.Hosting.UnhandledException"))
|
||||
{
|
||||
telemetrySource.WriteTelemetry("Microsoft.AspNet.Hosting.UnhandledException", new { httpContext = httpContext, exception = ex });
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
if (telemetrySource.IsEnabled("Microsoft.AspNet.Hosting.EndRequest"))
|
||||
{
|
||||
telemetrySource.WriteTelemetry("Microsoft.AspNet.Hosting.EndRequest", new { httpContext = httpContext });
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.Tracing;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Hosting.Builder;
|
||||
using Microsoft.AspNet.Hosting.Internal;
|
||||
|
|
@ -91,6 +92,10 @@ namespace Microsoft.AspNet.Hosting
|
|||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
services.AddLogging();
|
||||
|
||||
var telemetrySource = new TelemetryListener("Microsoft.AspNet");
|
||||
services.AddInstance<TelemetrySource>(telemetrySource);
|
||||
services.AddInstance<TelemetryListener>(telemetrySource);
|
||||
|
||||
// Conjure up a RequestServices
|
||||
services.AddTransient<IStartupFilter, AutoRequestServicesStartupFilter>();
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,15 @@
|
|||
"Microsoft.Framework.DependencyInjection": "1.0.0-*",
|
||||
"Microsoft.Framework.Logging": "1.0.0-*",
|
||||
"Microsoft.Dnx.Runtime.Abstractions": "1.0.0-*",
|
||||
"Newtonsoft.Json": "6.0.6"
|
||||
"Newtonsoft.Json": "6.0.6",
|
||||
"System.Diagnostics.Tracing.Telemetry": "4.0.0-beta-*"
|
||||
},
|
||||
"frameworks": {
|
||||
"dnx451": { },
|
||||
"dnx451": {
|
||||
"frameworkAssemblies": {
|
||||
"System.Runtime": ""
|
||||
}
|
||||
},
|
||||
"dnxcore50": {
|
||||
"dependencies": {
|
||||
"System.Console": "4.0.0-beta-*"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.Tracing;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
|
|
@ -13,6 +14,7 @@ using Microsoft.AspNet.Http;
|
|||
using Microsoft.Framework.Configuration;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.Logging;
|
||||
using Microsoft.Framework.TelemetryAdapter;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.TestHost
|
||||
|
|
@ -310,6 +312,111 @@ namespace Microsoft.AspNet.TestHost
|
|||
Assert.Equal("FoundFoo:False", await result.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BeginEndTelemetryAvailable()
|
||||
{
|
||||
TelemetryListener telemetryListener = null;
|
||||
var server = TestServer.Create(app =>
|
||||
{
|
||||
telemetryListener = app.ApplicationServices.GetRequiredService<TelemetryListener>();
|
||||
app.Run(context =>
|
||||
{
|
||||
return context.Response.WriteAsync("Hello World");
|
||||
});
|
||||
});
|
||||
var listener = new TestTelemetryListener();
|
||||
telemetryListener.SubscribeWithAdapter(listener);
|
||||
var result = await server.CreateClient().GetStringAsync("/path");
|
||||
|
||||
Assert.Equal("Hello World", result);
|
||||
Assert.NotNull(listener.BeginRequest?.HttpContext);
|
||||
Assert.NotNull(listener.EndRequest?.HttpContext);
|
||||
Assert.Null(listener.UnhandledException);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ExceptionTelemetryAvailable()
|
||||
{
|
||||
TelemetryListener telemetryListener = null;
|
||||
var server = TestServer.Create(app =>
|
||||
{
|
||||
telemetryListener = app.ApplicationServices.GetRequiredService<TelemetryListener>();
|
||||
app.Run(context =>
|
||||
{
|
||||
throw new Exception("Test exception");
|
||||
});
|
||||
});
|
||||
var listener = new TestTelemetryListener();
|
||||
telemetryListener.SubscribeWithAdapter(listener);
|
||||
await Assert.ThrowsAsync<Exception>(() => server.CreateClient().GetAsync("/path"));
|
||||
|
||||
Assert.NotNull(listener.BeginRequest?.HttpContext);
|
||||
Assert.Null(listener.EndRequest?.HttpContext);
|
||||
Assert.NotNull(listener.UnhandledException?.HttpContext);
|
||||
Assert.NotNull(listener.UnhandledException?.Exception);
|
||||
}
|
||||
|
||||
public class TestTelemetryListener
|
||||
{
|
||||
public class OnBeginRequestEventData
|
||||
{
|
||||
public IProxyHttpContext HttpContext { get; set; }
|
||||
}
|
||||
|
||||
public OnBeginRequestEventData BeginRequest { get; set; }
|
||||
|
||||
[TelemetryName("Microsoft.AspNet.Hosting.BeginRequest")]
|
||||
public virtual void OnBeginRequest(IProxyHttpContext httpContext)
|
||||
{
|
||||
BeginRequest = new OnBeginRequestEventData()
|
||||
{
|
||||
HttpContext = httpContext,
|
||||
};
|
||||
}
|
||||
|
||||
public class OnEndRequestEventData
|
||||
{
|
||||
public IProxyHttpContext HttpContext { get; set; }
|
||||
}
|
||||
|
||||
public OnEndRequestEventData EndRequest { get; set; }
|
||||
|
||||
[TelemetryName("Microsoft.AspNet.Hosting.EndRequest")]
|
||||
public virtual void OnEndRequest(IProxyHttpContext httpContext)
|
||||
{
|
||||
EndRequest = new OnEndRequestEventData()
|
||||
{
|
||||
HttpContext = httpContext,
|
||||
};
|
||||
}
|
||||
|
||||
public class OnUnhandledExceptionEventData
|
||||
{
|
||||
public IProxyHttpContext HttpContext { get; set; }
|
||||
public IProxyException Exception { get; set; }
|
||||
}
|
||||
|
||||
public OnUnhandledExceptionEventData UnhandledException { get; set; }
|
||||
|
||||
[TelemetryName("Microsoft.AspNet.Hosting.UnhandledException")]
|
||||
public virtual void OnUnhandledException(IProxyHttpContext httpContext, IProxyException exception)
|
||||
{
|
||||
UnhandledException = new OnUnhandledExceptionEventData()
|
||||
{
|
||||
HttpContext = httpContext,
|
||||
Exception = exception,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public interface IProxyHttpContext
|
||||
{
|
||||
}
|
||||
|
||||
public interface IProxyException
|
||||
{
|
||||
}
|
||||
|
||||
public class Startup
|
||||
{
|
||||
public void Configure(IApplicationBuilder builder)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
"dependencies": {
|
||||
"Microsoft.AspNet.Testing": "1.0.0-*",
|
||||
"Microsoft.AspNet.TestHost": "1.0.0-*",
|
||||
"Microsoft.Framework.TelemetryAdapter": "1.0.0-*",
|
||||
"xunit.runner.aspnet": "2.0.0-aspnet-*"
|
||||
},
|
||||
"commands": {
|
||||
|
|
|
|||
Loading…
Reference in New Issue