diff --git a/src/Microsoft.AspNet.TelemetryCorrelation/ActivityHelper.cs b/src/Microsoft.AspNet.TelemetryCorrelation/ActivityHelper.cs
index 73cdba5..5423f1d 100644
--- a/src/Microsoft.AspNet.TelemetryCorrelation/ActivityHelper.cs
+++ b/src/Microsoft.AspNet.TelemetryCorrelation/ActivityHelper.cs
@@ -1,6 +1,7 @@
// 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.Collections;
using System.Diagnostics;
using System.Web;
@@ -27,53 +28,35 @@ internal static class ActivityHelper
public const string AspNetActivityStartName = "Microsoft.AspNet.HttpReqIn.Start";
///
- /// Event name for the activity stop event.
+ /// Event name for the lost activity stop event.
///
public const string AspNetActivityLostStopName = "Microsoft.AspNet.HttpReqIn.ActivityLost.Stop";
+ ///
+ /// Event name for the restored activity stop event.
+ ///
+ public const string AspNetActivityRestoredStopName = "Microsoft.AspNet.HttpReqIn.ActivityRestored.Stop";
+
///
/// Key to store the activity in HttpContext.
///
public const string ActivityKey = "__AspnetActivity__";
- private const int MaxActivityStackSize = 128;
- private static readonly DiagnosticListener AspNetListener = new DiagnosticListener(AspNetListenerName);
-
///
- /// It's possible that a request is executed in both native threads and managed threads,
- /// in such case Activity.Current will be lost during native thread and managed thread switch.
- /// This method is intended to restore the current activity in order to correlate the child
- /// activities with the root activity of the request.
+ /// Key to store the restored activity in HttpContext.
///
- /// Root activity id for the current request.
- /// If it returns an activity, it will be silently stopped with the parent activity
- public static Activity RestoreCurrentActivity(Activity root)
- {
- Debug.Assert(root != null);
-
- // workaround to restore the root activity, because we don't
- // have a way to change the Activity.Current
- var childActivity = new Activity(root.OperationName);
- childActivity.SetParentId(root.Id);
- childActivity.SetStartTime(root.StartTimeUtc);
- foreach (var item in root.Baggage)
- {
- childActivity.AddBaggage(item.Key, item.Value);
- }
+ public const string RestoredActivityKey = "__AspnetActivityRestored__";
- childActivity.Start();
-
- AspNetTelemetryCorrelationEventSource.Log.ActivityStarted(childActivity.Id);
- return childActivity;
- }
+ private const int MaxActivityStackSize = 128;
+ private static readonly DiagnosticListener AspNetListener = new DiagnosticListener(AspNetListenerName);
///
/// Stops the activity and notifies listeners about it.
///
/// Activity to stop.
- /// Current HttpContext.
+ /// HttpContext.Items.
/// True if activity was found in the stack, false otherwise.
- public static bool StopAspNetActivity(Activity activity, HttpContext context)
+ public static bool StopAspNetActivity(Activity activity, IDictionary contextItems)
{
var currentActivity = Activity.Current;
if (activity != null && currentActivity != null)
@@ -87,11 +70,11 @@ public static bool StopAspNetActivity(Activity activity, HttpContext context)
if (newCurrentActivity == null)
{
- break;
+ return false;
}
// there could be a case when request or any child activity is stopped
- // from the child execution context. In this case, Activity is present in the Current Stack,
+ // from the child execution context. In this case, Activity is present in the Current Stack,
// but is finished, i.e. stopping it has no effect on the Current.
if (newCurrentActivity == currentActivity)
{
@@ -116,13 +99,11 @@ public static bool StopAspNetActivity(Activity activity, HttpContext context)
}
// if activity is in the stack, stop it with Stop event
- if (Activity.Current != null)
- {
- AspNetListener.StopActivity(Activity.Current, new { });
- RemoveCurrentActivity(context);
- AspNetTelemetryCorrelationEventSource.Log.ActivityStopped(activity.Id);
- return true;
- }
+ AspNetListener.StopActivity(currentActivity, new { });
+ contextItems[ActivityKey] = null;
+
+ AspNetTelemetryCorrelationEventSource.Log.ActivityStopped(currentActivity.Id, currentActivity.OperationName);
+ return true;
}
return false;
@@ -135,12 +116,21 @@ public static bool StopAspNetActivity(Activity activity, HttpContext context)
/// Current HttpContext.
public static void StopLostActivity(Activity activity, HttpContext context)
{
- if (activity != null)
- {
- AspNetListener.Write(AspNetActivityLostStopName, new { activity });
- RemoveCurrentActivity(context);
- AspNetTelemetryCorrelationEventSource.Log.ActivityStopped(activity.Id, true);
- }
+ context.Items[ActivityKey] = null;
+ AspNetListener.Write(AspNetActivityLostStopName, new { activity });
+ AspNetTelemetryCorrelationEventSource.Log.ActivityStopped(activity.Id, AspNetActivityLostStopName);
+ }
+
+ ///
+ /// Notifies listeners that there the lost activity was lost during execution and there was an intermediate activity.
+ ///
+ /// Activity to notify about.
+ /// Current HttpContext.
+ public static void StopRestoredActivity(Activity activity, HttpContext context)
+ {
+ context.Items[RestoredActivityKey] = null;
+ AspNetListener.Write(AspNetActivityRestoredStopName, new { Activity = activity });
+ AspNetTelemetryCorrelationEventSource.Log.ActivityStopped(activity.Id, AspNetActivityRestoredStopName);
}
///
@@ -152,12 +142,12 @@ public static Activity CreateRootActivity(HttpContext context)
{
if (AspNetListener.IsEnabled() && AspNetListener.IsEnabled(AspNetActivityName))
{
- var rootActivity = new Activity(ActivityHelper.AspNetActivityName);
+ var rootActivity = new Activity(AspNetActivityName);
rootActivity.Extract(context.Request.Unvalidated.Headers);
if (StartAspNetActivity(rootActivity))
{
- SaveCurrentActivity(context, rootActivity);
+ context.Items[ActivityKey] = rootActivity;
AspNetTelemetryCorrelationEventSource.Log.ActivityStarted(rootActivity.Id);
return rootActivity;
}
@@ -167,16 +157,56 @@ public static Activity CreateRootActivity(HttpContext context)
}
///
- /// This should be called after the Activity starts and only for root activity of a request.
+ /// Saves activity in the HttpContext.Items.
///
- /// Context to save context to.
+ /// Context to save context to.
+ /// Slot name.
/// Activity to save.
- internal static void SaveCurrentActivity(HttpContext context, Activity activity)
+ internal static void SaveCurrentActivity(IDictionary contextItems, string key, Activity activity)
{
- Debug.Assert(context != null);
+ Debug.Assert(contextItems != null);
Debug.Assert(activity != null);
- context.Items[ActivityKey] = activity;
+ contextItems[key] = activity;
+ }
+
+ ///
+ /// It's possible that a request is executed in both native threads and managed threads,
+ /// in such case Activity.Current will be lost during native thread and managed thread switch.
+ /// This method is intended to restore the current activity in order to correlate the child
+ /// activities with the root activity of the request.
+ ///
+ /// HttpContext.Items dictionary.
+ internal static void RestoreActivityIfNeeded(IDictionary contextItems)
+ {
+ if (Activity.Current == null)
+ {
+ var rootActivity = (Activity)contextItems[ActivityKey];
+ if (rootActivity != null && !contextItems.Contains(RestoredActivityKey))
+ {
+ contextItems[RestoredActivityKey] = RestoreActivity(rootActivity);
+ }
+ }
+ }
+
+ private static Activity RestoreActivity(Activity root)
+ {
+ Debug.Assert(root != null);
+
+ // workaround to restore the root activity, because we don't
+ // have a way to change the Activity.Current
+ var childActivity = new Activity(root.OperationName);
+ childActivity.SetParentId(root.Id);
+ childActivity.SetStartTime(root.StartTimeUtc);
+ foreach (var item in root.Baggage)
+ {
+ childActivity.AddBaggage(item.Key, item.Value);
+ }
+
+ childActivity.Start();
+
+ AspNetTelemetryCorrelationEventSource.Log.ActivityRestored(childActivity.Id);
+ return childActivity;
}
private static bool StartAspNetActivity(Activity activity)
@@ -197,11 +227,5 @@ private static bool StartAspNetActivity(Activity activity)
return false;
}
-
- private static void RemoveCurrentActivity(HttpContext context)
- {
- Debug.Assert(context != null);
- context.Items[ActivityKey] = null;
- }
}
}
diff --git a/src/Microsoft.AspNet.TelemetryCorrelation/AspNetTelemetryCorrelationEventSource.cs b/src/Microsoft.AspNet.TelemetryCorrelation/AspNetTelemetryCorrelationEventSource.cs
index 8b6591f..5f5fb94 100644
--- a/src/Microsoft.AspNet.TelemetryCorrelation/AspNetTelemetryCorrelationEventSource.cs
+++ b/src/Microsoft.AspNet.TelemetryCorrelation/AspNetTelemetryCorrelationEventSource.cs
@@ -29,10 +29,10 @@ public void ActivityStarted(string id)
WriteEvent(2, id);
}
- [Event(3, Message = "Activity stopped, Id='{0}', lost {1}", Level = EventLevel.Verbose)]
- public void ActivityStopped(string id, bool lost = false)
+ [Event(3, Message = "Activity stopped, Id='{0}', Name='{1}'", Level = EventLevel.Verbose)]
+ public void ActivityStopped(string id, string eventName)
{
- WriteEvent(3, id, lost);
+ WriteEvent(3, id, eventName);
}
[Event(4, Message = "Failed to parse header '{0}', value: '{1}'", Level = EventLevel.Informational)]
@@ -58,6 +58,12 @@ public void ActivityStackIsTooDeep(string id, string name)
{
WriteEvent(7, id, name);
}
+
+ [Event(8, Message = "Activity restored, Id='{0}'", Level = EventLevel.Informational)]
+ public void ActivityRestored(string id)
+ {
+ WriteEvent(8, id);
+ }
}
}
#pragma warning restore SA1600 // Elements must be documented
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.TelemetryCorrelation/TelemetryCorrelationHttpModule.cs b/src/Microsoft.AspNet.TelemetryCorrelation/TelemetryCorrelationHttpModule.cs
index 25c3063..de4e480 100644
--- a/src/Microsoft.AspNet.TelemetryCorrelation/TelemetryCorrelationHttpModule.cs
+++ b/src/Microsoft.AspNet.TelemetryCorrelation/TelemetryCorrelationHttpModule.cs
@@ -3,6 +3,7 @@
using System;
using System.Diagnostics;
+using System.Reflection;
using System.Web;
namespace Microsoft.AspNet.TelemetryCorrelation
@@ -13,6 +14,12 @@ namespace Microsoft.AspNet.TelemetryCorrelation
public class TelemetryCorrelationHttpModule : IHttpModule
{
private const string BeginCalledFlag = "Microsoft.AspNet.TelemetryCorrelation.BeginCalled";
+ private static MethodInfo onStepMethodInfo = null;
+
+ static TelemetryCorrelationHttpModule()
+ {
+ onStepMethodInfo = typeof(HttpApplication).GetMethod("OnExecuteRequestStep");
+ }
///
public void Dispose()
@@ -24,7 +31,40 @@ public void Init(HttpApplication context)
{
context.BeginRequest += Application_BeginRequest;
context.EndRequest += Application_EndRequest;
- context.PreRequestHandlerExecute += Application_PreRequestHandlerExecute;
+
+ // OnExecuteRequestStep is availabile starting with 4.7.1
+ // If this is executed in 4.7.1 runtime (regardless of targeted .NET version),
+ // we will use it to restore lost activity, otherwise keep PreRequestHandlerExecute
+ if (onStepMethodInfo != null)
+ {
+ onStepMethodInfo.Invoke(context, new object[] { (Action)OnExecuteRequestStep });
+ }
+ else
+ {
+ context.PreRequestHandlerExecute += Application_PreRequestHandlerExecute;
+ }
+ }
+
+ ///
+ /// Restores Activity before each pipeline step if it was lost.
+ ///
+ /// HttpContext instance.
+ /// Step to be executed.
+ internal void OnExecuteRequestStep(HttpContextBase context, Action step)
+ {
+ // Once we have public Activity.Current setter (https://github.com/dotnet/corefx/issues/29207) this method will be
+ // simplified to just assign Current if is was lost.
+ // In the mean time, we are creating child Activity to restore the context. We have to send
+ // event with this Activity to tracing system. It created a lot of issues for listeners as
+ // we may potentially have a lot of them for different stages.
+ // To reduce amount of events, we only care about ExecuteRequestHandler stage - restore activity here and
+ // stop/report it to tracing system in EndRequest.
+ if (context.CurrentNotification == RequestNotification.ExecuteRequestHandler && !context.IsPostNotification)
+ {
+ ActivityHelper.RestoreActivityIfNeeded(context.Items);
+ }
+
+ step();
}
private void Application_BeginRequest(object sender, EventArgs e)
@@ -38,13 +78,7 @@ private void Application_BeginRequest(object sender, EventArgs e)
private void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
AspNetTelemetryCorrelationEventSource.Log.TraceCallback("Application_PreRequestHandlerExecute");
- var context = ((HttpApplication)sender).Context;
-
- var rootActivity = (Activity)context.Items[ActivityHelper.ActivityKey];
- if (Activity.Current == null && rootActivity != null)
- {
- ActivityHelper.RestoreCurrentActivity(rootActivity);
- }
+ ActivityHelper.RestoreActivityIfNeeded(((HttpApplication)sender).Context.Items);
}
private void Application_EndRequest(object sender, EventArgs e)
@@ -59,16 +93,25 @@ private void Application_EndRequest(object sender, EventArgs e)
{
// Activity has never been started
var activity = ActivityHelper.CreateRootActivity(context);
- ActivityHelper.StopAspNetActivity(activity, context);
+ ActivityHelper.StopAspNetActivity(activity, context.Items);
}
else
{
var activity = (Activity)context.Items[ActivityHelper.ActivityKey];
// try to stop activity if it's in the Current stack
- if (!ActivityHelper.StopAspNetActivity(activity, context))
+ // stop all running Activities on the way
+ if (!ActivityHelper.StopAspNetActivity(activity, context.Items))
{
- // Activity we created was lost, let's report it
+ // perhaps we attempted to restore the Activity before
+ var restoredActivity = (Activity)context.Items[ActivityHelper.RestoredActivityKey];
+ if (restoredActivity != null)
+ {
+ // if so, report it
+ ActivityHelper.StopRestoredActivity(restoredActivity, context);
+ }
+
+ // Activity we created was lost let's report it
if (activity != null)
{
ActivityHelper.StopLostActivity(activity, context);
diff --git a/test/Microsoft.AspNet.TelemetryCorrelation.Tests/ActivityHelperTest.cs b/test/Microsoft.AspNet.TelemetryCorrelation.Tests/ActivityHelperTest.cs
index 7a6c94f..89ecbb4 100644
--- a/test/Microsoft.AspNet.TelemetryCorrelation.Tests/ActivityHelperTest.cs
+++ b/test/Microsoft.AspNet.TelemetryCorrelation.Tests/ActivityHelperTest.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
@@ -15,11 +16,13 @@
namespace Microsoft.AspNet.TelemetryCorrelation.Tests
{
- public class ActivityHelperTest
+ public class ActivityHelperTest : IDisposable
{
private const string TestActivityName = "Activity.Test";
private readonly List> _baggageItems;
private readonly string _baggageInHeader;
+ private IDisposable subscriptionAllListeners;
+ private IDisposable subscriptionAspNetListener;
public ActivityHelperTest()
{
@@ -38,9 +41,15 @@ public ActivityHelperTest()
var aspnetListenerField = typeof(ActivityHelper).
GetField("AspNetListener", BindingFlags.Static | BindingFlags.NonPublic);
aspnetListenerField.SetValue(null, new DiagnosticListener(ActivityHelper.AspNetListenerName));
- }
+ }
+
+ public void Dispose()
+ {
+ subscriptionAspNetListener?.Dispose();
+ subscriptionAllListeners?.Dispose();
+ }
- #region RestoreCurrentActivity tests
+ #region RestoreActivity tests
[Fact]
public async Task Can_Restore_Activity()
{
@@ -53,15 +62,84 @@ await Task.Run(() =>
});
Assert.Null(Activity.Current);
- var restoredActivity = ActivityHelper.RestoreCurrentActivity(rootActivity);
+ ActivityHelper.RestoreActivityIfNeeded(context.Items);
- Assert.NotNull(restoredActivity);
- Assert.True(rootActivity.Id == restoredActivity.ParentId);
- Assert.True(!string.IsNullOrEmpty(restoredActivity.Id));
- var expectedBaggage = _baggageItems.OrderBy(item => item.Value);
- var actualBaggage = rootActivity.Baggage.OrderBy(item => item.Value);
- Assert.Equal(expectedBaggage, actualBaggage);
+ AssertIsRestoredActivity(rootActivity, Activity.Current);
+ }
+
+
+ [Fact]
+ public void Do_Not_Restore_Activity_When_There_Is_No_Activity_In_Context()
+ {
+ ActivityHelper.RestoreActivityIfNeeded(HttpContextHelper.GetFakeHttpContext().Items);
+
+ Assert.Null(Activity.Current);
+ }
+
+ [Fact]
+ public void Do_Not_Restore_Activity_When_It_Is_Not_Lost()
+ {
+ var root = new Activity("root").Start();
+
+ var context = HttpContextHelper.GetFakeHttpContext();
+ context.Items[ActivityHelper.ActivityKey] = root;
+
+ var module = new TelemetryCorrelationHttpModule();
+
+ ActivityHelper.RestoreActivityIfNeeded(context.Items);
+
+ Assert.Equal(root, Activity.Current);
}
+
+ [Fact]
+ public async Task Stop_Restored_Activity_Deletes_It_From_Items()
+ {
+ var context = HttpContextHelper.GetFakeHttpContext();
+ var root = new Activity("root");
+
+ await Task.Run(() =>
+ {
+ root.Start();
+ context.Items[ActivityHelper.ActivityKey] = root;
+ });
+
+ ActivityHelper.RestoreActivityIfNeeded(context.Items);
+
+ var child = Activity.Current;
+
+ ActivityHelper.StopRestoredActivity(child, context);
+ Assert.NotNull(context.Items[ActivityHelper.ActivityKey]);
+ Assert.Null(context.Items[ActivityHelper.RestoredActivityKey]);
+ }
+
+ [Fact]
+ public async Task Stop_Restored_Activity_Fires_Event()
+ {
+ var context = HttpContextHelper.GetFakeHttpContext();
+ var root = new Activity("root");
+
+ await Task.Run(() =>
+ {
+ root.Start();
+ context.Items[ActivityHelper.ActivityKey] = root;
+ });
+
+ ActivityHelper.RestoreActivityIfNeeded(context.Items);
+ Activity restored = Activity.Current;
+
+ var events = new ConcurrentQueue>();
+ EnableAll((kvp) => events.Enqueue(kvp));
+
+ ActivityHelper.StopRestoredActivity(restored, context);
+
+ Assert.Single(events);
+ string eventName = events.Single().Key;
+ object eventPayload = events.Single().Value;
+
+ Assert.Equal(ActivityHelper.AspNetActivityRestoredStopName, eventName);
+ Assert.Same(restored, eventPayload.GetProperty("Activity"));
+ }
+
#endregion
#region StopAspNetActivity tests
@@ -72,7 +150,7 @@ public void Can_Stop_Activity_Without_AspNetListener_Enabled()
var rootActivity = CreateActivity();
rootActivity.Start();
Thread.Sleep(100);
- ActivityHelper.StopAspNetActivity(rootActivity, context);
+ ActivityHelper.StopAspNetActivity(rootActivity, context.Items);
Assert.True(rootActivity.Duration != TimeSpan.Zero);
Assert.Null(rootActivity.Parent);
@@ -87,7 +165,7 @@ public void Can_Stop_Activity_With_AspNetListener_Enabled()
rootActivity.Start();
Thread.Sleep(100);
EnableAspNetListenerOnly();
- ActivityHelper.StopAspNetActivity(rootActivity, context);
+ ActivityHelper.StopAspNetActivity(rootActivity, context.Items);
Assert.True(rootActivity.Duration != TimeSpan.Zero);
Assert.Null(rootActivity.Parent);
@@ -104,7 +182,7 @@ public void Can_Stop_Root_Activity_With_All_Children()
new Activity("child").Start();
new Activity("grandchild").Start();
- ActivityHelper.StopAspNetActivity(rootActivity, context);
+ ActivityHelper.StopAspNetActivity(rootActivity, context.Items);
Assert.True(rootActivity.Duration != TimeSpan.Zero);
Assert.Null(rootActivity.Parent);
@@ -120,7 +198,7 @@ public void Can_Stop_Child_Activity_With_All_Children()
var child = new Activity("child").Start();
new Activity("grandchild").Start();
- ActivityHelper.StopAspNetActivity(child, context);
+ ActivityHelper.StopAspNetActivity(child, context.Items);
Assert.True(child.Duration != TimeSpan.Zero);
Assert.Equal(rootActivity, Activity.Current);
@@ -132,8 +210,7 @@ public async Task Can_Stop_Root_Activity_If_It_Is_Broken()
{
var context = HttpContextHelper.GetFakeHttpContext();
var root = new Activity("root").Start();
- ActivityHelper.SaveCurrentActivity(context, root);
-
+ context.Items[ActivityHelper.ActivityKey] = root;
new Activity("child").Start();
for (int i = 0; i < 2; i++)
@@ -151,7 +228,7 @@ await Task.Run(() =>
// do not affect 'parent' context in which Task.Run is called.
// But 'child' Activity is stopped, thus consequent calls to Stop will
// not update Current
- Assert.False(ActivityHelper.StopAspNetActivity(root, context));
+ Assert.False(ActivityHelper.StopAspNetActivity(root, context.Items));
Assert.NotNull(context.Items[ActivityHelper.ActivityKey]);
Assert.Null(Activity.Current);
}
@@ -161,7 +238,7 @@ public void Stop_Root_Activity_With_129_Nesting_Depth()
{
var context = HttpContextHelper.GetFakeHttpContext();
var root = new Activity("root").Start();
- ActivityHelper.SaveCurrentActivity(context, root);
+ context.Items[ActivityHelper.ActivityKey] = root;
for (int i = 0; i < 129; i++)
{
@@ -170,12 +247,11 @@ public void Stop_Root_Activity_With_129_Nesting_Depth()
// we do not allow more than 128 nested activities here
// only to protect from hypothetical cycles in Activity stack
- Assert.False(ActivityHelper.StopAspNetActivity(root, context));
+ Assert.False(ActivityHelper.StopAspNetActivity(root, context.Items));
Assert.NotNull(context.Items[ActivityHelper.ActivityKey]);
Assert.Null(Activity.Current);
}
-
#endregion
#region CreateRootActivity tests
@@ -252,6 +328,19 @@ public void Can_Create_RootActivity_And_Saved_In_HttContext()
#endregion
#region Helper methods
+
+ private void AssertIsRestoredActivity(Activity original, Activity restored)
+ {
+ Assert.NotNull(restored);
+ Assert.Equal(original.RootId, restored.RootId);
+ Assert.Equal(original.Id, restored.ParentId);
+ Assert.Equal(original.StartTimeUtc, restored.StartTimeUtc);
+ Assert.False(string.IsNullOrEmpty(restored.Id));
+ var expectedBaggage = original.Baggage.OrderBy(item => item.Value);
+ var actualBaggage = restored.Baggage.OrderBy(item => item.Value);
+ Assert.Equal(expectedBaggage, actualBaggage);
+ }
+
private Activity CreateActivity()
{
var activity = new Activity(TestActivityName);
@@ -260,15 +349,27 @@ private Activity CreateActivity()
return activity;
}
+ private void EnableAll(Action> onNext = null)
+ {
+ subscriptionAllListeners = DiagnosticListener.AllListeners.Subscribe(listener =>
+ {
+ // if AspNetListener has subscription, then it is enabled
+ if (listener.Name == ActivityHelper.AspNetListenerName)
+ {
+ subscriptionAspNetListener = listener.Subscribe(new TestDiagnosticListener(onNext), (name) => true);
+ }
+ });
+ }
+
private void EnableAspNetListenerAndDisableActivity(Action> onNext = null,
string ActivityName = ActivityHelper.AspNetActivityName)
{
- DiagnosticListener.AllListeners.Subscribe(listener =>
+ subscriptionAllListeners = DiagnosticListener.AllListeners.Subscribe(listener =>
{
// if AspNetListener has subscription, then it is enabled
if (listener.Name == ActivityHelper.AspNetListenerName)
{
- listener.Subscribe(new TestDiagnosticListener(onNext),
+ subscriptionAspNetListener = listener.Subscribe(new TestDiagnosticListener(onNext),
(name, arg1, arg2) => name == ActivityName && arg1 == null);
}
});
@@ -277,12 +378,12 @@ private void EnableAspNetListenerAndDisableActivity(Action> onNext = null,
string ActivityName = ActivityHelper.AspNetActivityName)
{
- DiagnosticListener.AllListeners.Subscribe(listener =>
+ subscriptionAllListeners = DiagnosticListener.AllListeners.Subscribe(listener =>
{
// if AspNetListener has subscription, then it is enabled
if (listener.Name == ActivityHelper.AspNetListenerName)
{
- listener.Subscribe(new TestDiagnosticListener(onNext),
+ subscriptionAspNetListener = listener.Subscribe(new TestDiagnosticListener(onNext),
(name, arg1, arg2) => name == ActivityName);
}
});
@@ -290,42 +391,20 @@ private void EnableAspNetListenerAndActivity(Action
private void EnableAspNetListenerOnly(Action> onNext = null)
{
- DiagnosticListener.AllListeners.Subscribe(listener =>
+ subscriptionAllListeners = DiagnosticListener.AllListeners.Subscribe(listener =>
{
// if AspNetListener has subscription, then it is enabled
if (listener.Name == ActivityHelper.AspNetListenerName)
{
- listener.Subscribe(new TestDiagnosticListener(onNext),
+ subscriptionAspNetListener = listener.Subscribe(new TestDiagnosticListener(onNext),
activityName => false);
}
});
}
+
#endregion
#region Helper Class
- private class TestDiagnosticListener : IObserver>
- {
- Action> _onNextCallBack;
-
- public TestDiagnosticListener(Action> onNext)
- {
- _onNextCallBack = onNext;
- }
-
- public void OnCompleted()
- {
- }
-
- public void OnError(Exception error)
- {
- }
-
- public void OnNext(KeyValuePair value)
- {
- _onNextCallBack?.Invoke(value);
- }
- }
-
private class TestHttpRequest : HttpRequestBase
{
NameValueCollection _headers = new NameValueCollection();
diff --git a/test/Microsoft.AspNet.TelemetryCorrelation.Tests/HttpContextHelper.cs b/test/Microsoft.AspNet.TelemetryCorrelation.Tests/HttpContextHelper.cs
index 19121b7..3024d14 100644
--- a/test/Microsoft.AspNet.TelemetryCorrelation.Tests/HttpContextHelper.cs
+++ b/test/Microsoft.AspNet.TelemetryCorrelation.Tests/HttpContextHelper.cs
@@ -18,12 +18,17 @@ public static HttpContext GetFakeHttpContext(string page = "/page", string query
Thread.GetDomain().SetData(".appVPath", string.Empty);
var workerRequest = new SimpleWorkerRequestWithHeaders(page, query, new StringWriter(CultureInfo.InvariantCulture), headers);
-
var context = new HttpContext(workerRequest);
HttpContext.Current = context;
return context;
}
+ public static HttpContextBase GetFakeHttpContextBase(string page = "/page", string query = "", IDictionary headers = null)
+ {
+ var context = GetFakeHttpContext(page, query, headers);
+ return new HttpContextWrapper(context);
+ }
+
private class SimpleWorkerRequestWithHeaders : SimpleWorkerRequest
{
private readonly IDictionary headers;
diff --git a/test/Microsoft.AspNet.TelemetryCorrelation.Tests/Microsoft.AspNet.TelemetryCorrelation.Tests.csproj b/test/Microsoft.AspNet.TelemetryCorrelation.Tests/Microsoft.AspNet.TelemetryCorrelation.Tests.csproj
index c0b2d93..b40fc87 100644
--- a/test/Microsoft.AspNet.TelemetryCorrelation.Tests/Microsoft.AspNet.TelemetryCorrelation.Tests.csproj
+++ b/test/Microsoft.AspNet.TelemetryCorrelation.Tests/Microsoft.AspNet.TelemetryCorrelation.Tests.csproj
@@ -1,7 +1,8 @@
+
+
-
@@ -67,17 +68,14 @@
..\..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll
True
-
- ..\..\packages\xunit.assert.2.2.0\lib\netstandard1.1\xunit.assert.dll
- True
+
+ ..\..\packages\xunit.assert.2.3.1\lib\netstandard1.1\xunit.assert.dll
-
- ..\..\packages\xunit.extensibility.core.2.2.0\lib\netstandard1.1\xunit.core.dll
- True
+
+ ..\..\packages\xunit.extensibility.core.2.3.1\lib\netstandard1.1\xunit.core.dll
-
- ..\..\packages\xunit.extensibility.execution.2.2.0\lib\net452\xunit.execution.desktop.dll
- True
+
+ ..\..\packages\xunit.extensibility.execution.2.3.1\lib\net452\xunit.execution.desktop.dll
@@ -85,6 +83,7 @@
+
@@ -107,6 +106,9 @@
+
+
+