[2.11.0-beta1] experimental deferred request properties (#1198)
* squash changes * resolve merge conflict * save worknig test * this works * finished, should refactor * move HttpContext to separate helper class * TODO * fix compile * code review concerns * change Base SDK version to 2.11 beta1 * Switch tests from DisableTrackingProperties to Experimental Features
This commit is contained in:
Родитель
9ce3e9554e
Коммит
9169d6e7f2
|
@ -4,7 +4,7 @@
|
|||
- [Add support for Event Counter collection.](https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/1222)
|
||||
- [Support for Process CPU and Process Memory perf counters in all platforms including Linux.](https://github.com/microsoft/ApplicationInsights-dotnet-server/issues/1189)
|
||||
- [Azure Web App for Windows Containers to use regular PerfCounter mechanism.](https://github.com/microsoft/ApplicationInsights-dotnet-server/pull/1167)
|
||||
- [Defer populating RequestTelemetry properties.](https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/1173)
|
||||
- Experimental: [Defer populating RequestTelemetry properties.](https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/1173)
|
||||
- [Fix: Replaced non-threadsafe HashSet with ConcurrentDictionary in RequestTrackingTelemetryModule.IsHandlerToFilter](https://github.com/microsoft/ApplicationInsights-dotnet-server/pull/1211)
|
||||
- SDL: [Guard against malicious headers in quickpulse](https://github.com/microsoft/ApplicationInsights-dotnet-server/pull/1191)
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
<Compile Include="$(MSBuildThisFileDirectory)ExceptionUtilities.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)GuidExtensions.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HeadersUtilities.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ExperimentalConstants.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)InjectionGuardConstants.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)PropertyFetcher.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)RequestResponseHeaders.cs" />
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#if DEPENDENCY_COLLECTOR
|
||||
namespace Microsoft.ApplicationInsights.Common
|
||||
#else
|
||||
namespace Microsoft.ApplicationInsights.Common.Internal
|
||||
#endif
|
||||
{
|
||||
/// <summary>
|
||||
/// These values are listed to guard against malicious injections by limiting the max size allowed in an HTTP Response.
|
||||
/// These max limits are intentionally exaggerated to allow for unexpected responses, while still guarding against unreasonably large responses.
|
||||
/// Example: While a 32 character response may be expected, 50 characters may be permitted while a 10,000 character response would be unreasonable and malicious.
|
||||
/// </summary>
|
||||
internal static class ExperimentalConstants
|
||||
{
|
||||
/// <summary>
|
||||
/// This is used to defer setting properties on RequestTelemetry until after Sampling.
|
||||
/// QuickPulse expects these properties so we have to set them here as well.
|
||||
/// Used to set QuickPulseTelemetryProcessor.EvaluateDisabledTrackingProperties and RequestTrackingTelemetryModule.DisableTrackingProperties.
|
||||
/// </summary>
|
||||
public const string DeferRequestTrackingProperties = nameof(DeferRequestTrackingProperties);
|
||||
}
|
||||
}
|
|
@ -26,7 +26,7 @@
|
|||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.2" >
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.2">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MicroBuild.Core" Version="0.3.0">
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), 'Test.props'))\Test.props" />
|
||||
<PropertyGroup>
|
||||
|
@ -90,4 +90,4 @@
|
|||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'Common.targets'))\Common.targets" />
|
||||
</Project>
|
||||
</Project>
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.ApplicationInsights" version="2.11.0-beta1" targetFramework="net451" />
|
||||
<package id="StyleCop.Analyzers" version="1.0.2" targetFramework="net451" developmentDependency="true" />
|
||||
|
@ -9,4 +9,4 @@
|
|||
<package id="xunit.core" version="2.1.0" targetFramework="net451" />
|
||||
<package id="xunit.extensibility.core" version="2.1.0" targetFramework="net451" />
|
||||
<package id="xunit.extensibility.execution" version="2.1.0" targetFramework="net451" />
|
||||
</packages>
|
||||
</packages>
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), 'Test.props'))\Test.props" />
|
||||
<PropertyGroup>
|
||||
|
@ -85,4 +85,4 @@
|
|||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'Common.targets'))\Common.targets" />
|
||||
</Project>
|
||||
</Project>
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="MicroBuild.Core" version="0.3.0" targetFramework="net45" developmentDependency="true" />
|
||||
<package id="Microsoft.ApplicationInsights" version="2.11.0-beta1" targetFramework="net45" />
|
||||
<package id="StyleCop.Analyzers" version="1.0.2" targetFramework="net45" developmentDependency="true" />
|
||||
<package id="System.Diagnostics.DiagnosticSource" version="4.5.0" targetFramework="net45" />
|
||||
</packages>
|
||||
</packages>
|
|
@ -26,7 +26,7 @@
|
|||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.2" >
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.2">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MicroBuild.Core" Version="0.3.0">
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
<Reference Include="System.Net" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.XML" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Tests.Helpers
|
||||
{
|
||||
#if NET45
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
#endif
|
||||
|
||||
public static class HttpContextHelper
|
||||
{
|
||||
#if NET45
|
||||
/// <summary>
|
||||
/// Sets the static HttpContext.Current for use in unit tests.
|
||||
/// Request URL is set specifically to evaluate httpContext.Request.Url during tests.
|
||||
/// </summary>
|
||||
public static HttpContext SetFakeHttpContext(IDictionary<string, string> headers = null, Func<string> remoteAddr = null)
|
||||
{
|
||||
string urlPath = "/SeLog.svc/EventData";
|
||||
string urlQueryString = "eventDetail=2";
|
||||
|
||||
Thread.GetDomain().SetData(".appPath", string.Empty);
|
||||
Thread.GetDomain().SetData(".appVPath", string.Empty);
|
||||
|
||||
var workerRequest = new SimpleWorkerRequestWithHeaders(urlPath, urlQueryString, new StringWriter(CultureInfo.InvariantCulture), headers, remoteAddr);
|
||||
|
||||
var context = new HttpContext(workerRequest);
|
||||
HttpContext.Current = context;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
private class SimpleWorkerRequestWithHeaders : SimpleWorkerRequest
|
||||
{
|
||||
private readonly IDictionary<string, string> headers;
|
||||
|
||||
private readonly Func<string> getRemoteAddress;
|
||||
|
||||
public SimpleWorkerRequestWithHeaders(string page, string query, TextWriter output, IDictionary<string, string> headers, Func<string> getRemoteAddress = null)
|
||||
: base(page, query, output)
|
||||
{
|
||||
if (headers != null)
|
||||
{
|
||||
this.headers = headers;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.headers = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
this.getRemoteAddress = getRemoteAddress;
|
||||
}
|
||||
|
||||
public override string[][] GetUnknownRequestHeaders()
|
||||
{
|
||||
List<string[]> result = new List<string[]>();
|
||||
|
||||
foreach (var header in this.headers)
|
||||
{
|
||||
result.Add(new string[] { header.Key, header.Value });
|
||||
}
|
||||
|
||||
var baseResult = base.GetUnknownRequestHeaders();
|
||||
if (baseResult != null)
|
||||
{
|
||||
result.AddRange(baseResult);
|
||||
}
|
||||
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
public override string GetUnknownRequestHeader(string name)
|
||||
{
|
||||
if (this.headers.ContainsKey(name))
|
||||
{
|
||||
return this.headers[name];
|
||||
}
|
||||
|
||||
return base.GetUnknownRequestHeader(name);
|
||||
}
|
||||
|
||||
public override string GetKnownRequestHeader(int index)
|
||||
{
|
||||
var name = HttpWorkerRequest.GetKnownRequestHeaderName(index);
|
||||
|
||||
if (this.headers.ContainsKey(name))
|
||||
{
|
||||
return this.headers[name];
|
||||
}
|
||||
|
||||
return base.GetKnownRequestHeader(index);
|
||||
}
|
||||
|
||||
public override string GetRemoteAddress()
|
||||
{
|
||||
if (this.getRemoteAddress != null)
|
||||
{
|
||||
return this.getRemoteAddress();
|
||||
}
|
||||
|
||||
return base.GetRemoteAddress();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
<Compile Include="$(MSBuildThisFileDirectory)Filtering\FilterTests.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Filtering\Mocks\TelemetryMock.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)GlobalSuppressions.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Helpers\HttpContextHelper.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Helpers\SimpleTelemetryProcessorSpy.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Mocks\PerformanceCollectorMock.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)PerformanceCollectorEventSourceTests.cs" />
|
||||
|
|
|
@ -5,13 +5,14 @@
|
|||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Microsoft.ApplicationInsights.Common.Internal;
|
||||
using Microsoft.ApplicationInsights.DataContracts;
|
||||
using Microsoft.ApplicationInsights.Extensibility;
|
||||
using Microsoft.ApplicationInsights.Extensibility.Filtering;
|
||||
using Microsoft.ApplicationInsights.Extensibility.Implementation;
|
||||
using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.QuickPulse;
|
||||
using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.QuickPulse;
|
||||
using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Tests.Helpers;
|
||||
using Microsoft.ApplicationInsights.Web.Helpers;
|
||||
using Microsoft.ManagementServices.RealTimeDataProcessing.QuickPulseService;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
@ -2986,5 +2987,165 @@
|
|||
Assert.AreEqual((taskCount / 2) + 1, allBadSlowMinValue);
|
||||
Assert.AreEqual(taskCount - 1, allBadSlowMaxValue);
|
||||
}
|
||||
|
||||
#if NET45
|
||||
[TestMethod]
|
||||
public void VerifyInitializationWhenDeferredIsTrue()
|
||||
{
|
||||
var config = new TelemetryConfiguration();
|
||||
config.ExperimentalFeatures.Add(ExperimentalConstants.DeferRequestTrackingProperties);
|
||||
|
||||
var spy = new SimpleTelemetryProcessorSpy();
|
||||
var telemetryProcessor = new QuickPulseTelemetryProcessor(spy);
|
||||
telemetryProcessor.Initialize(config);
|
||||
|
||||
Assert.IsTrue(telemetryProcessor.EvaluateDisabledTrackingProperties);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void VerifyInitializationWhenDeferredIsFalse()
|
||||
{
|
||||
var spy = new SimpleTelemetryProcessorSpy();
|
||||
var telemetryProcessor = new QuickPulseTelemetryProcessor(spy);
|
||||
telemetryProcessor.Initialize(new TelemetryConfiguration());
|
||||
|
||||
Assert.IsFalse(telemetryProcessor.EvaluateDisabledTrackingProperties);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void VerifyBehaviorWhenDeferredIsTrue()
|
||||
{
|
||||
// SETUP CONFIG
|
||||
var instrumentationKey = "some ikey";
|
||||
var config = new TelemetryConfiguration()
|
||||
{
|
||||
InstrumentationKey = instrumentationKey
|
||||
};
|
||||
config.ExperimentalFeatures.Add(ExperimentalConstants.DeferRequestTrackingProperties);
|
||||
|
||||
// ARRANGE
|
||||
var accumulatorManager = GetAccumulationManager();
|
||||
var telemetryProcessor = GetQuickPulseTelemetryProcessor(accumulatorManager, config);
|
||||
|
||||
// ASSERT QuickPulseTelemetryProcessor was Initialized
|
||||
Assert.IsTrue(telemetryProcessor.EvaluateDisabledTrackingProperties);
|
||||
|
||||
// ACT
|
||||
var request = new RequestTelemetry()
|
||||
{
|
||||
Name = Guid.NewGuid().ToString(),
|
||||
Success = true,
|
||||
ResponseCode = "500",
|
||||
Context = { InstrumentationKey = instrumentationKey },
|
||||
Url = null, // THIS IS WHAT WE'RE TESTING
|
||||
};
|
||||
|
||||
var httpContext = HttpContextHelper.SetFakeHttpContext(); // QuickPulseTelemetryProcessor should use the Url from the Current HttpContext.
|
||||
|
||||
telemetryProcessor.Process(request);
|
||||
|
||||
// ASSERT
|
||||
Assert.IsFalse(accumulatorManager.CurrentDataAccumulator.GlobalDocumentQuotaReached);
|
||||
Assert.AreEqual(1, accumulatorManager.CurrentDataAccumulator.TelemetryDocuments.Count);
|
||||
var collectedTelemetry = accumulatorManager.CurrentDataAccumulator.TelemetryDocuments.ToArray().Reverse().ToArray();
|
||||
|
||||
Assert.AreEqual(TelemetryDocumentType.Request, Enum.Parse(typeof(TelemetryDocumentType), collectedTelemetry[0].DocumentType));
|
||||
var requestTelemetryDocument = (RequestTelemetryDocument)collectedTelemetry[0];
|
||||
|
||||
Assert.AreEqual(request.Name, requestTelemetryDocument.Name);
|
||||
|
||||
// this is what we care about
|
||||
Assert.IsNotNull(requestTelemetryDocument.Url, "request url was not set");
|
||||
Assert.AreEqual(httpContext.Request.Url, requestTelemetryDocument.Url, "RequestTelemetryDocument should use the URL of the httpcontext");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void VerifyBehaviorWhenDeferredIsFalse()
|
||||
{
|
||||
// SETUP CONFIG
|
||||
var instrumentationKey = "some ikey";
|
||||
var config = new TelemetryConfiguration()
|
||||
{
|
||||
InstrumentationKey = instrumentationKey
|
||||
};
|
||||
|
||||
// ARRANGE
|
||||
var accumulatorManager = GetAccumulationManager();
|
||||
var telemetryProcessor = GetQuickPulseTelemetryProcessor(accumulatorManager, config);
|
||||
|
||||
// ASSERT QuickPulseTelemetryProcessor was Initialized
|
||||
Assert.IsFalse(telemetryProcessor.EvaluateDisabledTrackingProperties);
|
||||
|
||||
// ACT
|
||||
var request = new RequestTelemetry()
|
||||
{
|
||||
Name = Guid.NewGuid().ToString(),
|
||||
Success = true,
|
||||
ResponseCode = "500",
|
||||
Context = { InstrumentationKey = instrumentationKey },
|
||||
Url = null, // THIS IS WHAT WE'RE TESTING
|
||||
};
|
||||
|
||||
telemetryProcessor.Process(request);
|
||||
|
||||
// ASSERT
|
||||
Assert.IsFalse(accumulatorManager.CurrentDataAccumulator.GlobalDocumentQuotaReached);
|
||||
Assert.AreEqual(1, accumulatorManager.CurrentDataAccumulator.TelemetryDocuments.Count);
|
||||
var collectedTelemetry = accumulatorManager.CurrentDataAccumulator.TelemetryDocuments.ToArray().Reverse().ToArray();
|
||||
|
||||
Assert.AreEqual(TelemetryDocumentType.Request, Enum.Parse(typeof(TelemetryDocumentType), collectedTelemetry[0].DocumentType));
|
||||
var requestTelemetryDocument = (RequestTelemetryDocument)collectedTelemetry[0];
|
||||
|
||||
Assert.AreEqual(request.Name, requestTelemetryDocument.Name);
|
||||
|
||||
// this is what we care about
|
||||
Assert.IsNull(requestTelemetryDocument.Url, "request url was not set");
|
||||
}
|
||||
#endif
|
||||
|
||||
private static QuickPulseDataAccumulatorManager GetAccumulationManager()
|
||||
{
|
||||
var requestsDocumentStreamInfo = new DocumentStreamInfo()
|
||||
{
|
||||
Id = "StreamRequests",
|
||||
DocumentFilterGroups =
|
||||
new[]
|
||||
{
|
||||
// TODO: SHOULD GET THESE FILTERS FROM THE PARAMATER SO OTHER TESTS CAN SHARE THIS METHOD
|
||||
new DocumentFilterConjunctionGroupInfo()
|
||||
{
|
||||
TelemetryType = TelemetryType.Request,
|
||||
Filters =
|
||||
new FilterConjunctionGroupInfo
|
||||
{
|
||||
Filters = new[] { new FilterInfo { FieldName = "Success", Predicate = Predicate.Equal, Comparand = "0" } }
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
var collectionConfigurationInfo = new CollectionConfigurationInfo()
|
||||
{
|
||||
DocumentStreams = new[] { requestsDocumentStreamInfo },
|
||||
};
|
||||
var collectionConfiguration = new CollectionConfiguration(collectionConfigurationInfo, out errors, new ClockMock());
|
||||
var accumulatorManager = new QuickPulseDataAccumulatorManager(collectionConfiguration);
|
||||
|
||||
return accumulatorManager;
|
||||
}
|
||||
|
||||
private static QuickPulseTelemetryProcessor GetQuickPulseTelemetryProcessor(QuickPulseDataAccumulatorManager accumulatorManager, TelemetryConfiguration configuration)
|
||||
{
|
||||
var spy = new SimpleTelemetryProcessorSpy();
|
||||
var telemetryProcessor = new QuickPulseTelemetryProcessor(spy);
|
||||
telemetryProcessor.Initialize(configuration);
|
||||
|
||||
((IQuickPulseTelemetryProcessor)telemetryProcessor).StartCollection(
|
||||
accumulatorManager,
|
||||
new Uri("http://microsoft.com"),
|
||||
configuration);
|
||||
|
||||
return telemetryProcessor;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,9 +9,11 @@
|
|||
|
||||
using Microsoft.ApplicationInsights.Channel;
|
||||
using Microsoft.ApplicationInsights.Common;
|
||||
using Microsoft.ApplicationInsights.Common.Internal;
|
||||
using Microsoft.ApplicationInsights.DataContracts;
|
||||
using Microsoft.ApplicationInsights.Extensibility.Filtering;
|
||||
using Microsoft.ApplicationInsights.Extensibility.Implementation;
|
||||
using Microsoft.ApplicationInsights.Extensibility.Implementation.Experimental;
|
||||
using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing;
|
||||
using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.QuickPulse;
|
||||
using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.QuickPulse.Helpers;
|
||||
|
@ -114,6 +116,8 @@
|
|||
this telemetry processor will only collect for whichever instrumentation key is specified by the module in StartCollection call.
|
||||
*/
|
||||
|
||||
this.EvaluateDisabledTrackingProperties = configuration.EvaluateExperimentalFeature(ExperimentalConstants.DeferRequestTrackingProperties);
|
||||
|
||||
this.Register();
|
||||
}
|
||||
|
||||
|
@ -194,7 +198,7 @@
|
|||
{
|
||||
try
|
||||
{
|
||||
// some of the requestTelemetry properties might be deffered by using RequestTrackingTelemetryModule.DisableTrackingProperties.
|
||||
// some of the requestTelemetry properties might be deferred by using RequestTrackingTelemetryModule.DisableTrackingProperties.
|
||||
// evaluate them now
|
||||
// note: RequestTrackingUtilities.UpdateRequestTelemetryFromRequest is not used here, since not all fields need to be populated
|
||||
var request = System.Web.HttpContext.Current?.Request;
|
||||
|
@ -217,7 +221,7 @@
|
|||
Success = requestTelemetry.Success,
|
||||
Duration = requestTelemetry.Duration,
|
||||
ResponseCode = requestTelemetry.ResponseCode,
|
||||
Url = requestTelemetry.Url,
|
||||
Url = url,
|
||||
Properties = GetProperties(requestTelemetry),
|
||||
};
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.2" >
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.2">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MicroBuild.Core" Version="0.3.0">
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), 'Test.props'))\Test.props" />
|
||||
<PropertyGroup>
|
||||
|
@ -144,4 +144,4 @@
|
|||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'Common.targets'))\Common.targets" />
|
||||
<Import Project="..\..\TestFramework\Shared\TestFramework.Shared.projitems" Label="Shared" />
|
||||
</Project>
|
||||
</Project>
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Castle.Core" version="4.4.0" targetFramework="net451" />
|
||||
<package id="Microsoft.ApplicationInsights" version="2.11.0-beta1" targetFramework="net451" />
|
||||
|
@ -24,4 +24,4 @@
|
|||
<package id="xunit.core" version="2.1.0" targetFramework="net451" />
|
||||
<package id="xunit.extensibility.core" version="2.1.0" targetFramework="net451" />
|
||||
<package id="xunit.extensibility.execution" version="2.1.0" targetFramework="net451" />
|
||||
</packages>
|
||||
</packages>
|
|
@ -10,17 +10,20 @@
|
|||
|
||||
using Microsoft.ApplicationInsights.Channel;
|
||||
using Microsoft.ApplicationInsights.Common;
|
||||
using Microsoft.ApplicationInsights.Common.Internal;
|
||||
using Microsoft.ApplicationInsights.DataContracts;
|
||||
using Microsoft.ApplicationInsights.Extensibility;
|
||||
using Microsoft.ApplicationInsights.Extensibility.Implementation;
|
||||
using Microsoft.ApplicationInsights.Extensibility.W3C;
|
||||
using Microsoft.ApplicationInsights.TestFramework;
|
||||
using Microsoft.ApplicationInsights.Web.Extensibility.Implementation;
|
||||
using Microsoft.ApplicationInsights.Web.Helpers;
|
||||
using Microsoft.ApplicationInsights.Web.Implementation;
|
||||
using Microsoft.ApplicationInsights.Web.TestFramework;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
using Xunit.Sdk;
|
||||
using Assert = Xunit.Assert;
|
||||
using MsAssert = Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
|
||||
|
||||
/// <summary>
|
||||
/// Platform independent tests for RequestTrackingTelemetryModule.
|
||||
|
@ -393,9 +396,9 @@
|
|||
var config = TelemetryConfiguration.CreateDefault();
|
||||
config.InstrumentationKey = TestInstrumentationKey1;
|
||||
config.ApplicationIdProvider = new MockApplicationIdProvider(TestInstrumentationKey1, TestApplicationId1);
|
||||
config.ExperimentalFeatures.Add("DeferRequestTrackingProperties");
|
||||
|
||||
var module = this.RequestTrackingTelemetryModuleFactory(null /*use default*/);
|
||||
module.DisableTrackingProperties = true;
|
||||
|
||||
// ACT
|
||||
module.Initialize(config);
|
||||
|
@ -478,6 +481,53 @@
|
|||
Assert.True(intermediateRequest.Properties.ContainsKey("AI internal"));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void VerifyBehaviorWhenDeferredIsFalse()
|
||||
{
|
||||
var config = this.CreateDefaultConfig(HttpModuleHelper.GetFakeHttpContext());
|
||||
var context = HttpModuleHelper.GetFakeHttpContext();
|
||||
|
||||
// Create, Initialize, and Validate RequestTrackingTelemetryModule
|
||||
var module = this.RequestTrackingTelemetryModuleFactory(config);
|
||||
MsAssert.IsFalse(module.DisableTrackingProperties, $"{nameof(module.DisableTrackingProperties)} should be False by default.");
|
||||
|
||||
// Validate Telemetry Processor Chain
|
||||
MsAssert.IsFalse(config.DefaultTelemetrySink.TelemetryProcessors.Any(x => x is PostSamplingTelemetryProcessor));
|
||||
|
||||
// Run test to generate requestTelemetry
|
||||
module.OnBeginRequest(context);
|
||||
module.OnEndRequest(context);
|
||||
var requestTelemetry = context.GetRequestTelemetry();
|
||||
|
||||
// Validate requestTelemetry
|
||||
MsAssert.IsNotNull(requestTelemetry, "TEST ERROR: Failed to create requestTelemetry.");
|
||||
MsAssert.IsNotNull(requestTelemetry.Url);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void VerifyBehaviorWhenDeferredIsTrue()
|
||||
{
|
||||
var context = HttpModuleHelper.GetFakeHttpContext();
|
||||
var config = new TelemetryConfiguration();
|
||||
config.ExperimentalFeatures.Add(ExperimentalConstants.DeferRequestTrackingProperties);
|
||||
|
||||
// Create and Validate RequestTrackingTelemetryModule
|
||||
var module = this.RequestTrackingTelemetryModuleFactory(config);
|
||||
MsAssert.IsTrue(module.DisableTrackingProperties, "TEST ERROR: Module was not initialized with custom config.");
|
||||
|
||||
// Validate Telemetry Processor Chain
|
||||
MsAssert.IsTrue(config.DefaultTelemetrySink.TelemetryProcessors.Any(x => x is PostSamplingTelemetryProcessor), "Module should inject PostSamplingTelemetryProcessor");
|
||||
|
||||
// Run test to generate requestTelemetry
|
||||
module.OnBeginRequest(context);
|
||||
module.OnEndRequest(context);
|
||||
var requestTelemetry = context.GetRequestTelemetry();
|
||||
|
||||
// Validate requestTelemetry
|
||||
MsAssert.IsNotNull(requestTelemetry, "TEST ERROR: Failed to create requestTelemetry.");
|
||||
MsAssert.IsNotNull(requestTelemetry.Url); // set by PostSamplingTelemetryProcessor
|
||||
}
|
||||
|
||||
private TelemetryConfiguration CreateDefaultConfig(HttpContext fakeContext, string rootIdHeaderName = null, string parentIdHeaderName = null, string instrumentationKey = null)
|
||||
{
|
||||
var telemetryChannel = new StubTelemetryChannel()
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
using Microsoft.ApplicationInsights.DataContracts;
|
||||
using Microsoft.ApplicationInsights.Extensibility;
|
||||
using Microsoft.ApplicationInsights.Extensibility.Implementation;
|
||||
using Microsoft.ApplicationInsights.Extensibility.Implementation.Experimental;
|
||||
using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing;
|
||||
using Microsoft.ApplicationInsights.Web.Extensibility.Implementation;
|
||||
using Microsoft.ApplicationInsights.Web.Implementation;
|
||||
|
@ -265,6 +266,13 @@
|
|||
this.telemetryClient = new TelemetryClient(configuration);
|
||||
this.telemetryClient.Context.GetInternalContext().SdkVersion = SdkVersionUtils.GetSdkVersion("web:");
|
||||
|
||||
this.DisableTrackingProperties = configuration.EvaluateExperimentalFeature(Microsoft.ApplicationInsights.Common.Internal.ExperimentalConstants.DeferRequestTrackingProperties);
|
||||
if (this.DisableTrackingProperties)
|
||||
{
|
||||
configuration.DefaultTelemetrySink.TelemetryProcessorChainBuilder.Use(next => new PostSamplingTelemetryProcessor(next));
|
||||
configuration.DefaultTelemetrySink.TelemetryProcessorChainBuilder.Build();
|
||||
}
|
||||
|
||||
// Headers will be read-only in a classic iis pipeline
|
||||
// Exception System.PlatformNotSupportedException: This operation requires IIS integrated pipeline mode.
|
||||
if (HttpRuntime.UsingIntegratedPipeline && this.EnableChildRequestTrackingSuppression)
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.2" >
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.2">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MicroBuild.Core" Version="0.3.0">
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), 'Test.props'))\Test.props" />
|
||||
<PropertyGroup>
|
||||
|
@ -106,4 +106,4 @@
|
|||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'Common.targets'))\Common.targets" />
|
||||
<Import Project="..\..\TestFramework\Shared\TestFramework.Shared.projitems" Label="Shared" />
|
||||
<Import Project="..\WindowsServer.Shared.Tests\WindowsServer.Shared.Tests.projitems" Label="Shared" />
|
||||
</Project>
|
||||
</Project>
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.ApplicationInsights" version="2.11.0-beta1" targetFramework="net45" />
|
||||
<package id="StyleCop.Analyzers" version="1.0.2" targetFramework="net45" developmentDependency="true" />
|
||||
|
@ -9,4 +9,4 @@
|
|||
<package id="xunit.core" version="2.1.0" targetFramework="net45" />
|
||||
<package id="xunit.extensibility.core" version="2.1.0" targetFramework="net45" />
|
||||
<package id="xunit.extensibility.execution" version="2.1.0" targetFramework="net45" />
|
||||
</packages>
|
||||
</packages>
|
Загрузка…
Ссылка в новой задаче