#353,#354 Add telemetry for begin/end request and unhandled exceptions.

This commit is contained in:
Chris R 2015-09-16 11:01:29 -07:00
parent 10176373c8
commit 6758010e1a
5 changed files with 147 additions and 5 deletions

View File

@ -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 });
}
});

View File

@ -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>();

View File

@ -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-*"

View File

@ -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)

View File

@ -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": {