From afe655199acb9a7baaaa7f09961794ab61dd0174 Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Thu, 4 Jun 2020 15:53:07 -0700 Subject: [PATCH 1/3] Fix issue - https://github.com/aspnet/Microsoft.AspNet.TelemetryCorrelation/issues/73 --- .../TelemetryCorrelationHttpModule.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.AspNet.TelemetryCorrelation/TelemetryCorrelationHttpModule.cs b/src/Microsoft.AspNet.TelemetryCorrelation/TelemetryCorrelationHttpModule.cs index 220bb33..ccfa55f 100644 --- a/src/Microsoft.AspNet.TelemetryCorrelation/TelemetryCorrelationHttpModule.cs +++ b/src/Microsoft.AspNet.TelemetryCorrelation/TelemetryCorrelationHttpModule.cs @@ -105,8 +105,21 @@ private void Application_EndRequest(object sender, EventArgs e) // BeginRequest has never been called if (!context.Items.Contains(BeginCalledFlag)) { - // Activity has never been started - ActivityHelper.CreateRootActivity(context, ParseHeaders); + // Exception happened before BeginRequest + if (context.Error != null) + { + // Activity has never been started + ActivityHelper.CreateRootActivity(context, ParseHeaders); + } + else + { + // Rewrite: In case of rewrite, a new request context is created, called the child request, and it goes through the entire IIS/ASP.NET integrated pipeline. + // The child request can be mapped to any of the handlers configured in IIS, and it's execution is no different than it would be if it was received via the HTTP stack. + // The parent request jumps ahead in the pipeline to the end request notification, and waits for the child request to complete. + // When the child request completes, the parent request executes the end request notifications and completes itself. + // Ignore creating root activity for parent request as control got transferred from rewrite module to EndRequest with no request flow. + return; + } } ActivityHelper.StopAspNetActivity(context.Items); From b613b9e0920ca2de17bcd28400694d6abe6ca2bb Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Thu, 4 Jun 2020 17:12:50 -0700 Subject: [PATCH 2/3] Added flag to check instead of return. --- .../TelemetryCorrelationHttpModule.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.AspNet.TelemetryCorrelation/TelemetryCorrelationHttpModule.cs b/src/Microsoft.AspNet.TelemetryCorrelation/TelemetryCorrelationHttpModule.cs index ccfa55f..c66965f 100644 --- a/src/Microsoft.AspNet.TelemetryCorrelation/TelemetryCorrelationHttpModule.cs +++ b/src/Microsoft.AspNet.TelemetryCorrelation/TelemetryCorrelationHttpModule.cs @@ -98,6 +98,7 @@ private void Application_PreRequestHandlerExecute(object sender, EventArgs e) private void Application_EndRequest(object sender, EventArgs e) { AspNetTelemetryCorrelationEventSource.Log.TraceCallback("Application_EndRequest"); + bool trackActivity = true; var context = ((HttpApplication)sender).Context; @@ -118,11 +119,14 @@ private void Application_EndRequest(object sender, EventArgs e) // The parent request jumps ahead in the pipeline to the end request notification, and waits for the child request to complete. // When the child request completes, the parent request executes the end request notifications and completes itself. // Ignore creating root activity for parent request as control got transferred from rewrite module to EndRequest with no request flow. - return; + trackActivity = false; } } - ActivityHelper.StopAspNetActivity(context.Items); + if (trackActivity) + { + ActivityHelper.StopAspNetActivity(context.Items); + } } } } From b32e9f8c22d1c6f76d01dda7984963f9457238fb Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Tue, 23 Jun 2020 14:35:09 -0700 Subject: [PATCH 3/3] Fixed to track end request from other modules. --- .../TelemetryCorrelationHttpModule.cs | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/Microsoft.AspNet.TelemetryCorrelation/TelemetryCorrelationHttpModule.cs b/src/Microsoft.AspNet.TelemetryCorrelation/TelemetryCorrelationHttpModule.cs index c66965f..8ee6d5f 100644 --- a/src/Microsoft.AspNet.TelemetryCorrelation/TelemetryCorrelationHttpModule.cs +++ b/src/Microsoft.AspNet.TelemetryCorrelation/TelemetryCorrelationHttpModule.cs @@ -15,6 +15,13 @@ namespace Microsoft.AspNet.TelemetryCorrelation public class TelemetryCorrelationHttpModule : IHttpModule { private const string BeginCalledFlag = "Microsoft.AspNet.TelemetryCorrelation.BeginCalled"; + + // ServerVariable set only on rewritten HttpContext by URL Rewrite module. + private const string URLRewriteRewrittenRequest = "IIS_WasUrlRewritten"; + + // ServerVariable set on every request if URL module is registered in HttpModule pipeline. + private const string URLRewriteModuleVersion = "IIS_UrlRewriteModule"; + private static MethodInfo onStepMethodInfo = null; static TelemetryCorrelationHttpModule() @@ -106,20 +113,21 @@ private void Application_EndRequest(object sender, EventArgs e) // BeginRequest has never been called if (!context.Items.Contains(BeginCalledFlag)) { - // Exception happened before BeginRequest - if (context.Error != null) + // Rewrite: In case of rewrite, a new request context is created, called the child request, and it goes through the entire IIS/ASP.NET integrated pipeline. + // The child request can be mapped to any of the handlers configured in IIS, and it's execution is no different than it would be if it was received via the HTTP stack. + // The parent request jumps ahead in the pipeline to the end request notification, and waits for the child request to complete. + // When the child request completes, the parent request executes the end request notifications and completes itself. + // Do not create activity for parent request. Parent request has IIS_UrlRewriteModule ServerVariable with success response code. + // Child request contains an additional ServerVariable named - IIS_WasUrlRewritten. + // Track failed response activity: Different modules in the pipleline has ability to end the response. For example, authentication module could set HTTP 401 in OnBeginRequest and end the response. + if (context.Request.ServerVariables != null && context.Request.ServerVariables[URLRewriteRewrittenRequest] == null && context.Request.ServerVariables[URLRewriteModuleVersion] != null && context.Response.StatusCode == 200) { - // Activity has never been started - ActivityHelper.CreateRootActivity(context, ParseHeaders); + trackActivity = false; } else { - // Rewrite: In case of rewrite, a new request context is created, called the child request, and it goes through the entire IIS/ASP.NET integrated pipeline. - // The child request can be mapped to any of the handlers configured in IIS, and it's execution is no different than it would be if it was received via the HTTP stack. - // The parent request jumps ahead in the pipeline to the end request notification, and waits for the child request to complete. - // When the child request completes, the parent request executes the end request notifications and completes itself. - // Ignore creating root activity for parent request as control got transferred from rewrite module to EndRequest with no request flow. - trackActivity = false; + // Activity has never been started + ActivityHelper.CreateRootActivity(context, ParseHeaders); } }