1
0
Форкнуть 0

WIP ASP.NET Core Pert Fixes - 2 (#907)

* Remove DiagnosticAdapter and use DiagnosticListener directly

* minor fixes

* switch

* Initialize IKey

* Fix typo

* GetUri with Concat

* Set Header fixes, use Properties for AspNetCoreEnv.

* SetHeader fixes

* Test Fixes - 1

* fix tests

* Keep Public vs. Internal

* Changelog update

* Listeners, SetAppId, Ifs vs. Switch, RequestPool

* Join listeners.

* Refactor pre-sampling

* Remove request pool

* Update AI SDK

* Remove unnecessary code and files

* Repalce MVC Listener in tests

* Fix unit tests

* Fix Nuget Config

* Fix tests - 2

* Code Review - 1

* Fix merge

* Fix tests after merge - 2

* Finish merge

* Fix AppId perf back

* Use experimental feature flag for proactive sampling

* Keep source for unsampled items (it only does one check for header internally anyway)

* Cijo CR - 1

* SetAppId feature flag

* Rename head sampling, fix predicate

* Changelog and version

* AppId as a method

* Remove unnecessary settings for release
This commit is contained in:
Dmitry-Matveev 2019-07-10 19:17:23 -07:00 коммит произвёл GitHub
Родитель 4c037ea3b0
Коммит e2f7731d96
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
31 изменённых файлов: 602 добавлений и 301 удалений

Просмотреть файл

@ -2,6 +2,7 @@
## Version 2.8.0-beta1
- [Add EventCounter collection.](https://github.com/microsoft/ApplicationInsights-aspnetcore/issues/913)
- [Performance fixes: One DiagSource Listener; Head Sampling Feature; No Concurrent Dictionary; etc...](https://github.com/microsoft/ApplicationInsights-aspnetcore/pull/907)
- [Fix: Add `IJavaScriptSnippet` service interface and update the `IServiceCollection` extension to register it for `JavaScriptSnippet`.](https://github.com/microsoft/ApplicationInsights-aspnetcore/issues/890)
- [Make JavaScriptEncoder optional and Fallback to JavaScriptEncoder.Default.](https://github.com/microsoft/ApplicationInsights-aspnetcore/pull/918)

Просмотреть файл

@ -6,13 +6,15 @@
using System.Globalization;
using System.Linq;
using System.Text;
using Extensibility.Implementation.Tracing;
using Microsoft.ApplicationInsights.AspNetCore.DiagnosticListeners.Implementation;
using Microsoft.ApplicationInsights.AspNetCore.Extensibility.Implementation.Tracing;
using Microsoft.ApplicationInsights.AspNetCore.Extensions;
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.Common;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.Implementation;
using Microsoft.ApplicationInsights.Extensibility.Implementation.Experimental;
using Microsoft.ApplicationInsights.Extensibility.W3C;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;
@ -23,6 +25,8 @@
internal class HostingDiagnosticListener : IApplicationInsightDiagnosticListener
{
private const string ActivityCreatedByHostingDiagnosticListener = "ActivityCreatedByHostingDiagnosticListener";
private const string ProactiveSamplingFeatureFlagName = "proactiveSampling";
private const string ConditionalAppIdFeatureFlagName = "conditionalAppId";
/// <summary>
/// Determine whether the running AspNetCore Hosting version is 2.0 or higher. This will affect what DiagnosticSource events we receive.
@ -31,6 +35,10 @@
/// </summary>
private readonly bool enableNewDiagnosticEvents;
private readonly bool proactiveSamplingEnabled = false;
private readonly bool conditionalAppIdEnabled = false;
private readonly TelemetryConfiguration configuration;
private readonly TelemetryClient client;
private readonly IApplicationIdProvider applicationIdProvider;
private readonly string sdkVersion = SdkVersionUtils.GetVersion();
@ -39,7 +47,12 @@
private readonly bool enableW3CHeaders;
private static readonly ActiveSubsciptionManager SubscriptionManager = new ActiveSubsciptionManager();
#region fetchers
// fetch is unique per event and per property
private readonly PropertyFetcher httpContextFetcherOnBeforeAction = new PropertyFetcher("httpContext");
private readonly PropertyFetcher routeDataFetcher = new PropertyFetcher("routeData");
private readonly PropertyFetcher routeValuesFetcher = new PropertyFetcher("Values");
private readonly PropertyFetcher httpContextFetcherStart = new PropertyFetcher("HttpContext");
private readonly PropertyFetcher httpContextFetcherStop = new PropertyFetcher("HttpContext");
private readonly PropertyFetcher httpContextFetcherBeginRequest = new PropertyFetcher("httpContext");
@ -53,6 +66,10 @@
private readonly PropertyFetcher timestampFetcherBeginRequest = new PropertyFetcher("timestamp");
private readonly PropertyFetcher timestampFetcherEndRequest = new PropertyFetcher("timestamp");
#endregion
private string lastIKeyLookedUp;
private string lastAppIdUsed;
/// <summary>
/// Initializes a new instance of the <see cref="HostingDiagnosticListener"/> class.
@ -79,6 +96,31 @@
this.enableW3CHeaders = enableW3CHeaders;
}
/// <summary>
/// Initializes a new instance of the <see cref="HostingDiagnosticListener"/> class.
/// </summary>
/// <param name="configuration"><see cref="TelemetryConfiguration"/> as a settings source.</param>
/// <param name="client"><see cref="TelemetryClient"/> to post traces to.</param>
/// <param name="applicationIdProvider">Provider for resolving application Id to be used in multiple instruemntation keys scenarios.</param>
/// <param name="injectResponseHeaders">Flag that indicates that response headers should be injected.</param>
/// <param name="trackExceptions">Flag that indicates that exceptions should be tracked.</param>
/// <param name="enableW3CHeaders">Flag that indicates that W3C header parsing should be enabled.</param>
/// <param name="enableNewDiagnosticEvents">Flag that indicates that new diagnostic events are supported by AspNetCore</param>
public HostingDiagnosticListener(
TelemetryConfiguration configuration,
TelemetryClient client,
IApplicationIdProvider applicationIdProvider,
bool injectResponseHeaders,
bool trackExceptions,
bool enableW3CHeaders,
bool enableNewDiagnosticEvents = true)
: this(client, applicationIdProvider, injectResponseHeaders, trackExceptions, enableW3CHeaders, enableNewDiagnosticEvents)
{
this.configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
this.proactiveSamplingEnabled = this.configuration.EvaluateExperimentalFeature(ProactiveSamplingFeatureFlagName);
this.conditionalAppIdEnabled = this.configuration.EvaluateExperimentalFeature(ConditionalAppIdFeatureFlagName);
}
/// <inheritdoc />
public void OnSubscribe()
{
@ -88,6 +130,77 @@
/// <inheritdoc/>
public string ListenerName { get; } = "Microsoft.AspNetCore";
/// <summary>
/// Diagnostic event handler method for 'Microsoft.AspNetCore.Mvc.BeforeAction' event
/// </summary>
public void OnBeforeAction(HttpContext httpContext, IDictionary<string, object> routeValues)
{
var telemetry = httpContext.Features.Get<RequestTelemetry>();
if (telemetry != null && string.IsNullOrEmpty(telemetry.Name))
{
string name = this.GetNameFromRouteContext(routeValues);
if (!string.IsNullOrEmpty(name))
{
name = httpContext.Request.Method + " " + name;
telemetry.Name = name;
}
}
}
private string GetNameFromRouteContext(IDictionary<string, object> routeValues)
{
string name = null;
if (routeValues.Count > 0)
{
object controller;
routeValues.TryGetValue("controller", out controller);
string controllerString = (controller == null) ? string.Empty : controller.ToString();
if (!string.IsNullOrEmpty(controllerString))
{
name = controllerString;
if (routeValues.TryGetValue("action", out var action) && action != null)
{
name += "/" + action.ToString();
}
if (routeValues.Keys.Count > 2)
{
// Add parameters
var sortedKeys = routeValues.Keys
.Where(key =>
!string.Equals(key, "controller", StringComparison.OrdinalIgnoreCase) &&
!string.Equals(key, "action", StringComparison.OrdinalIgnoreCase) &&
!string.Equals(key, "!__route_group", StringComparison.OrdinalIgnoreCase))
.OrderBy(key => key, StringComparer.OrdinalIgnoreCase)
.ToArray();
if (sortedKeys.Length > 0)
{
string arguments = string.Join(@"/", sortedKeys);
name += " [" + arguments + "]";
}
}
}
else
{
object page;
routeValues.TryGetValue("page", out page);
string pageString = (page == null) ? string.Empty : page.ToString();
if (!string.IsNullOrEmpty(pageString))
{
name = pageString;
}
}
}
return name;
}
/// <summary>
/// Diagnostic event handler method for 'Microsoft.AspNetCore.Hosting.HttpRequestIn.Start' event.
/// </summary>
@ -183,7 +296,8 @@
}
requestTelemetry.Context.Operation.ParentId = originalParentId;
this.SetAppIdInResponseHeader(httpContext, requestTelemetry);
this.AddAppIdToResponseIfRequired(httpContext, requestTelemetry);
}
}
@ -296,7 +410,8 @@
// fix parent that may be modified by non-W3C operation correlation
requestTelemetry.Context.Operation.ParentId = originalParentId;
this.SetAppIdInResponseHeader(httpContext, requestTelemetry);
this.AddAppIdToResponseIfRequired(httpContext, requestTelemetry);
}
}
@ -342,98 +457,22 @@
this.OnException(httpContext, exception);
}
public void Dispose()
private void AddAppIdToResponseIfRequired(HttpContext httpContext, RequestTelemetry requestTelemetry)
{
SubscriptionManager.Detach(this);
}
public void OnNext(KeyValuePair<string, object> value)
{
HttpContext httpContext = null;
Exception exception = null;
long? timestamp = null;
try
if (this.conditionalAppIdEnabled)
{
switch (value.Key)
// Only reply back with AppId if we got an indication that we need to set one
if (!string.IsNullOrWhiteSpace(requestTelemetry.Source))
{
case "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start":
httpContext = this.httpContextFetcherStart.Fetch(value.Value) as HttpContext;
if (httpContext != null)
{
this.OnHttpRequestInStart(httpContext);
}
break;
case "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop":
httpContext = this.httpContextFetcherStop.Fetch(value.Value) as HttpContext;
if (httpContext != null)
{
this.OnHttpRequestInStop(httpContext);
}
break;
case "Microsoft.AspNetCore.Hosting.BeginRequest":
httpContext = this.httpContextFetcherBeginRequest.Fetch(value.Value) as HttpContext;
timestamp = this.timestampFetcherBeginRequest.Fetch(value.Value) as long?;
if (httpContext != null && timestamp.HasValue)
{
this.OnBeginRequest(httpContext, timestamp.Value);
}
break;
case "Microsoft.AspNetCore.Hosting.EndRequest":
httpContext = this.httpContextFetcherEndRequest.Fetch(value.Value) as HttpContext;
timestamp = this.timestampFetcherEndRequest.Fetch(value.Value) as long?;
if (httpContext != null && timestamp.HasValue)
{
this.OnEndRequest(httpContext, timestamp.Value);
}
break;
case "Microsoft.AspNetCore.Diagnostics.UnhandledException":
httpContext = this.httpContextFetcherDiagExceptionUnhandled.Fetch(value.Value) as HttpContext;
exception = this.exceptionFetcherDiagExceptionUnhandled.Fetch(value.Value) as Exception;
if (httpContext != null && exception != null)
{
this.OnDiagnosticsUnhandledException(httpContext, exception);
}
break;
case "Microsoft.AspNetCore.Diagnostics.HandledException":
httpContext = this.httpContextFetcherDiagExceptionHandled.Fetch(value.Value) as HttpContext;
exception = this.exceptionFetcherDiagExceptionHandled.Fetch(value.Value) as Exception;
if (httpContext != null && exception != null)
{
this.OnDiagnosticsHandledException(httpContext, exception);
}
break;
case "Microsoft.AspNetCore.Hosting.UnhandledException":
httpContext = this.httpContextFetcherHostingExceptionUnhandled.Fetch(value.Value) as HttpContext;
exception = this.exceptionFetcherHostingExceptionUnhandled.Fetch(value.Value) as Exception;
if (httpContext != null && exception != null)
{
this.OnHostingException(httpContext, exception);
}
break;
this.SetAppIdInResponseHeader(httpContext, requestTelemetry);
}
}
catch (Exception ex)
else
{
AspNetCoreEventSource.Instance.DiagnosticListenerWarning("HostingDiagnosticListener", value.Key, ex.Message);
this.SetAppIdInResponseHeader(httpContext, requestTelemetry);
}
}
/// <inheritdoc />
public void OnError(Exception error)
{
}
/// <inheritdoc />
public void OnCompleted()
{
}
private RequestTelemetry InitializeRequestTelemetry(HttpContext httpContext, Activity activity, long timestamp)
{
var requestTelemetry = new RequestTelemetry();
@ -448,17 +487,31 @@
activity.UpdateTelemetry(requestTelemetry, false);
}
foreach (var prop in activity.Baggage)
if (this.proactiveSamplingEnabled
&& this.configuration != null
&& !string.IsNullOrEmpty(requestTelemetry.Context.Operation.Id)
&& SamplingScoreGenerator.GetSamplingScore(requestTelemetry.Context.Operation.Id) >= this.configuration.GetLastObservedSamplingPercentage(requestTelemetry.ItemTypeFlag))
{
if (!requestTelemetry.Properties.ContainsKey(prop.Key))
requestTelemetry.IsSampledOutAtHead = true;
AspNetCoreEventSource.Instance.TelemetryItemWasSampledOutAtHead(requestTelemetry.Context.Operation.Id);
}
//// When the item is proactively sampled out, we can avoid heavy operations that do not have known dependency later in the pipeline.
//// We mostly exclude operations that were deemed heavy as per the corresponding profiler trace of this code path.
if (!requestTelemetry.IsSampledOutAtHead)
{
foreach (var prop in activity.Baggage)
{
requestTelemetry.Properties[prop.Key] = prop.Value;
if (!requestTelemetry.Properties.ContainsKey(prop.Key))
{
requestTelemetry.Properties[prop.Key] = prop.Value;
}
}
}
this.client.InitializeInstrumentationKey(requestTelemetry);
requestTelemetry.Source = this.GetAppIdFromRequestHeader(httpContext.Request.Headers, requestTelemetry.Context.InstrumentationKey);
requestTelemetry.Source = GetAppIdFromRequestHeader(httpContext.Request.Headers, requestTelemetry.Context.InstrumentationKey);
requestTelemetry.Start(timestamp);
httpContext.Features.Set(requestTelemetry);
@ -503,16 +556,14 @@
responseHeaders,
RequestResponseHeaders.RequestContextTargetKey)))
{
string applicationId = null;
if (this.applicationIdProvider?.TryGetApplicationId(
requestTelemetry.Context.InstrumentationKey,
out applicationId) ?? false)
if (this.lastIKeyLookedUp != requestTelemetry.Context.InstrumentationKey)
{
HttpHeadersUtilities.SetRequestContextKeyValue(
responseHeaders,
RequestResponseHeaders.RequestContextTargetKey,
applicationId);
this.lastIKeyLookedUp = requestTelemetry.Context.InstrumentationKey;
this.applicationIdProvider?.TryGetApplicationId(requestTelemetry.Context.InstrumentationKey, out this.lastAppIdUsed);
}
HttpHeadersUtilities.SetRequestContextKeyValue(responseHeaders,
RequestResponseHeaders.RequestContextTargetKey, this.lastAppIdUsed);
}
}
}
@ -556,8 +607,12 @@
telemetry.Name = httpContext.Request.Method + " " + httpContext.Request.Path.Value;
}
telemetry.Url = httpContext.Request.GetUri();
telemetry.Context.GetInternalContext().SdkVersion = this.sdkVersion;
if (!telemetry.IsSampledOutAtHead)
{
telemetry.Url = httpContext.Request.GetUri();
telemetry.Context.GetInternalContext().SdkVersion = this.sdkVersion;
}
this.client.TrackRequest(telemetry);
var activity = httpContext?.Features.Get<Activity>();
@ -672,5 +727,105 @@
appId = appIds[0];
return true;
}
public void Dispose()
{
SubscriptionManager.Detach(this);
}
public void OnNext(KeyValuePair<string, object> value)
{
HttpContext httpContext = null;
Exception exception = null;
long? timestamp = null;
//// Top messages in if-else are the most often used messages.
//// It starts with ASP.NET Core 2.0 events, then 1.0 events, then exception events.
//// Switch is compiled into GetHashCode() and binary search, if-else without GetHashCode() is faster if 2.0 events are used.
if (value.Key == "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start")
{
httpContext = this.httpContextFetcherStart.Fetch(value.Value) as HttpContext;
if (httpContext != null)
{
this.OnHttpRequestInStart(httpContext);
}
}
else if (value.Key == "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop")
{
httpContext = this.httpContextFetcherStop.Fetch(value.Value) as HttpContext;
if (httpContext != null)
{
this.OnHttpRequestInStop(httpContext);
}
}
else if (value.Key == "Microsoft.AspNetCore.Mvc.BeforeAction")
{
var context = this.httpContextFetcherOnBeforeAction.Fetch(value.Value) as HttpContext;
var routeData = this.routeDataFetcher.Fetch(value.Value);
var routeValues = this.routeValuesFetcher.Fetch(routeData) as IDictionary<string, object>;
if (context != null && routeValues != null)
{
this.OnBeforeAction(context, routeValues);
}
}
else if (value.Key == "Microsoft.AspNetCore.Hosting.BeginRequest")
{
httpContext = this.httpContextFetcherBeginRequest.Fetch(value.Value) as HttpContext;
timestamp = this.timestampFetcherBeginRequest.Fetch(value.Value) as long?;
if (httpContext != null && timestamp.HasValue)
{
this.OnBeginRequest(httpContext, timestamp.Value);
}
}
else if (value.Key == "Microsoft.AspNetCore.Hosting.EndRequest")
{
httpContext = this.httpContextFetcherEndRequest.Fetch(value.Value) as HttpContext;
timestamp = this.timestampFetcherEndRequest.Fetch(value.Value) as long?;
if (httpContext != null && timestamp.HasValue)
{
this.OnEndRequest(httpContext, timestamp.Value);
}
}
else if (value.Key == "Microsoft.AspNetCore.Diagnostics.UnhandledException")
{
httpContext = this.httpContextFetcherDiagExceptionUnhandled.Fetch(value.Value) as HttpContext;
exception = this.exceptionFetcherDiagExceptionUnhandled.Fetch(value.Value) as Exception;
if (httpContext != null && exception != null)
{
this.OnDiagnosticsUnhandledException(httpContext, exception);
}
}
else if (value.Key == "Microsoft.AspNetCore.Diagnostics.HandledException")
{
httpContext = this.httpContextFetcherDiagExceptionHandled.Fetch(value.Value) as HttpContext;
exception = this.exceptionFetcherDiagExceptionHandled.Fetch(value.Value) as Exception;
if (httpContext != null && exception != null)
{
this.OnDiagnosticsHandledException(httpContext, exception);
}
}
else if (value.Key == "Microsoft.AspNetCore.Hosting.UnhandledException")
{
httpContext = this.httpContextFetcherHostingExceptionUnhandled.Fetch(value.Value) as HttpContext;
exception = this.exceptionFetcherHostingExceptionUnhandled.Fetch(value.Value) as Exception;
if (httpContext != null && exception != null)
{
this.OnHostingException(httpContext, exception);
}
}
}
/// <inheritdoc />
public void OnError(Exception error)
{
}
/// <inheritdoc />
public void OnCompleted()
{
}
}
}

Просмотреть файл

@ -11,6 +11,7 @@ namespace Microsoft.ApplicationInsights.AspNetCore.DiagnosticListeners
/// <summary>
/// <see cref="IApplicationInsightDiagnosticListener"/> implementation that listens for evens specific to AspNetCore Mvc layer
/// </summary>
[Obsolete("This class was merged with HostingDiagnosticsListener to optimize Diagnostics Source subscription performance")]
public class MvcDiagnosticsListener : IApplicationInsightDiagnosticListener
{
/// <inheritdoc />

Просмотреть файл

@ -173,6 +173,16 @@ namespace Microsoft.ApplicationInsights.AspNetCore.Extensibility.Implementation.
this.WriteEvent(17, errorMessage, this.ApplicationName);
}
[Event(
18,
Keywords = Keywords.Diagnostics,
Message = "Telemetry item was sampled out at head, OperationId: '{0}'",
Level = EventLevel.Verbose)]
public void TelemetryItemWasSampledOutAtHead(string operationId, string appDomainName = "Incorrect")
{
this.WriteEvent(18, operationId, this.ApplicationName);
}
/// <summary>
/// Keywords for the AspNetEventSource.
/// </summary>

Просмотреть файл

@ -13,6 +13,8 @@ namespace Microsoft.Extensions.DependencyInjection
using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.QuickPulse;
using Microsoft.ApplicationInsights.Extensibility.W3C;
using Microsoft.Extensions.Options;
using Microsoft.ApplicationInsights.WindowsServer.Channel.Implementation;
using Microsoft.ApplicationInsights.DataContracts;
/// <summary>
/// Initializes TelemetryConfiguration based on values in <see cref="ApplicationInsightsServiceOptions"/>
@ -163,7 +165,17 @@ namespace Microsoft.Extensions.DependencyInjection
{
if (this.applicationInsightsServiceOptions.EnableAdaptiveSampling)
{
configuration.DefaultTelemetrySink.TelemetryProcessorChainBuilder.UseAdaptiveSampling(5, excludedTypes: "Event");
AdaptiveSamplingPercentageEvaluatedCallback samplingCallback = (ratePerSecond, currentPercentage, newPercentage, isChanged, estimatorSettings) =>
{
if (isChanged)
{
configuration.SetLastObservedSamplingPercentage(SamplingTelemetryItemTypes.Request, newPercentage);
}
};
SamplingPercentageEstimatorSettings settings = new SamplingPercentageEstimatorSettings();
settings.MaxTelemetryItemsPerSecond = 5;
configuration.DefaultTelemetrySink.TelemetryProcessorChainBuilder.UseAdaptiveSampling(settings, samplingCallback, excludedTypes: "Event");
configuration.DefaultTelemetrySink.TelemetryProcessorChainBuilder.UseAdaptiveSampling(5, includedTypes: "Event");
}
}

Просмотреть файл

@ -2,7 +2,6 @@ namespace Microsoft.ApplicationInsights.AspNetCore
{
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Threading;
@ -17,15 +16,20 @@ namespace Microsoft.ApplicationInsights.AspNetCore
/// </summary>
public class RequestTrackingTelemetryModule : ITelemetryModule, IObserver<DiagnosticListener>, IDisposable
{
private TelemetryClient telemetryClient;
private readonly IApplicationIdProvider applicationIdProvider;
private ConcurrentBag<IDisposable> subscriptions;
private readonly List<IApplicationInsightDiagnosticListener> diagnosticListeners;
private bool isInitialized = false;
// We are only interested in BeforeAction event from Microsoft.AspNetCore.Mvc source.
// We are interested in Microsoft.AspNetCore.Hosting and Microsoft.AspNetCore.Diagnostics as well.
// Below filter achieves acceptable performance, character 22 shoudl not be M unless event is BeforeAction.
private static readonly Predicate<string> HostingPredicate = (string eventName) => (eventName != null) ? !(eventName[21] == 'M') || eventName == "Microsoft.AspNetCore.Mvc.BeforeAction" : false;
private readonly object lockObject = new object();
private readonly IApplicationIdProvider applicationIdProvider;
private TelemetryClient telemetryClient;
private ConcurrentBag<IDisposable> subscriptions;
private HostingDiagnosticListener diagnosticListener;
private bool isInitialized = false;
/// <summary>
/// RequestTrackingTelemetryModule.
/// Initializes a new instance of the <see cref="RequestTrackingTelemetryModule"/> class.
/// </summary>
public RequestTrackingTelemetryModule()
: this(null)
@ -34,14 +38,13 @@ namespace Microsoft.ApplicationInsights.AspNetCore
}
/// <summary>
/// Creates RequestTrackingTelemetryModule.
/// Initializes a new instance of the <see cref="RequestTrackingTelemetryModule"/> class.
/// </summary>
/// <param name="applicationIdProvider"></param>
/// <param name="applicationIdProvider">Provider to resolve Application Id</param>
public RequestTrackingTelemetryModule(IApplicationIdProvider applicationIdProvider)
{
this.applicationIdProvider = applicationIdProvider;
this.subscriptions = new ConcurrentBag<IDisposable>();
this.diagnosticListeners = new List<IApplicationInsightDiagnosticListener>();
}
/// <summary>
@ -75,16 +78,14 @@ namespace Microsoft.ApplicationInsights.AspNetCore
// ignore any errors
}
this.diagnosticListeners.Add(new HostingDiagnosticListener(
this.diagnosticListener = new HostingDiagnosticListener(
configuration,
this.telemetryClient,
this.applicationIdProvider,
this.CollectionOptions.InjectResponseHeaders,
this.CollectionOptions.TrackExceptions,
this.CollectionOptions.EnableW3CDistributedTracing,
enableNewDiagnosticEvents));
this.diagnosticListeners.Add
(new MvcDiagnosticsListener());
enableNewDiagnosticEvents);
this.subscriptions?.Add(DiagnosticListener.AllListeners.Subscribe(this));
@ -108,13 +109,10 @@ namespace Microsoft.ApplicationInsights.AspNetCore
return;
}
foreach (var applicationInsightDiagnosticListener in this.diagnosticListeners)
if (this.diagnosticListener.ListenerName == value.Name)
{
if (applicationInsightDiagnosticListener.ListenerName == value.Name)
{
subs.Add(value.Subscribe(applicationInsightDiagnosticListener));
applicationInsightDiagnosticListener.OnSubscribe();
}
subs.Add(value.Subscribe(this.diagnosticListener, HostingPredicate));
this.diagnosticListener.OnSubscribe();
}
}
@ -156,9 +154,9 @@ namespace Microsoft.ApplicationInsights.AspNetCore
subscription.Dispose();
}
foreach (var listener in this.diagnosticListeners)
if (this.diagnosticListener != null)
{
listener.Dispose();
this.diagnosticListener.Dispose();
}
}
}

Просмотреть файл

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
//
// Tool : Bond Compiler 0.10.0.0
// Tool : Bond Compiler 0.10.1.0
// File : AvailabilityData_types.cs
//
// Changes to this file may cause incorrect behavior and will be lost when
@ -30,7 +30,7 @@ namespace AI
[global::Bond.Attribute("Description", "Instances of AvailabilityData represent the result of executing an availability test.")]
[global::Bond.Schema]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.0.0")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
public partial class AvailabilityData
: Domain
{
@ -73,13 +73,13 @@ namespace AI
[global::Bond.Attribute("Description", "Collection of custom properties.")]
[global::Bond.Attribute("MaxKeyLength", "150")]
[global::Bond.Attribute("MaxValueLength", "8192")]
[global::Bond.Id(100), global::Bond.Type(typeof(Dictionary<string, string>))]
public IDictionary<string, string> properties { get; set; }
[global::Bond.Id(100)]
public Dictionary<string, string> properties { get; set; }
[global::Bond.Attribute("Description", "Collection of custom measurements.")]
[global::Bond.Attribute("MaxKeyLength", "150")]
[global::Bond.Id(200), global::Bond.Type(typeof(Dictionary<string, double>))]
public IDictionary<string, double> measurements { get; set; }
[global::Bond.Id(200)]
public Dictionary<string, double> measurements { get; set; }
public AvailabilityData()
: this("AI.AvailabilityData", "AvailabilityData")

Просмотреть файл

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
//
// Tool : Bond Compiler 0.10.0.0
// Tool : Bond Compiler 0.10.1.0
// File : Base_types.cs
//
// Changes to this file may cause incorrect behavior and will be lost when
@ -30,7 +30,7 @@ namespace AI
[global::Bond.Attribute("Description", "Data struct to contain only C section with custom fields.")]
[global::Bond.Schema]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.0.0")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
public partial class Base
{
[global::Bond.Attribute("Name", "ItemTypeName")]

Просмотреть файл

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
//
// Tool : Bond Compiler 0.10.0.0
// Tool : Bond Compiler 0.10.1.0
// File : ContextTagKeys_types.cs
//
// Changes to this file may cause incorrect behavior and will be lost when
@ -31,7 +31,7 @@ namespace AI
[global::Bond.Attribute("ContextContract", "Emit")]
[global::Bond.Attribute("PseudoType", "JSMap")]
[global::Bond.Schema]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.0.0")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
public partial class ContextTagKeys
{
[global::Bond.Attribute("Description", "Application version. Information in the application context fields is always about the application that is sending the telemetry.")]
@ -69,7 +69,7 @@ namespace AI
[global::Bond.Id(160)]
public string DeviceType { get; set; }
[global::Bond.Attribute("Description", "The IP address of the client device. IPv4 and IPv6 is supported. Information in the location context fields is always about the end user. When telemetry is sent from a service, the location context is about the user that initiated the operation in the service.")]
[global::Bond.Attribute("Description", "The IPv4 IP address of the client device. IPv6 is not currently supported. Information in the location context fields is always about the end user. When telemetry is sent from a service, the location context is about the user that initiated the operation in the service.")]
[global::Bond.Attribute("MaxStringLength", "45")]
[global::Bond.Id(200)]
public string LocationIp { get; set; }
@ -115,7 +115,7 @@ namespace AI
[global::Bond.Id(505)]
public string UserAccountId { get; set; }
[global::Bond.Attribute("Description", "The browser's user agent string as reported by the browser. This property will be used to extract information regarding the customer's browser but will not be stored. Use custom properties to store the original user agent.")]
[global::Bond.Attribute("Description", "The browser's user agent string as reported by the browser. This property will be used to extract informaiton regarding the customer's browser but will not be stored. Use custom properties to store the original user agent.")]
[global::Bond.Attribute("MaxStringLength", "2048")]
[global::Bond.Id(510)]
public string UserAgent { get; set; }
@ -135,7 +135,7 @@ namespace AI
[global::Bond.Id(705)]
public string CloudRole { get; set; }
[global::Bond.Attribute("Description", "Name of the instance where the application is running. Computer name for on-premises, instance name for Azure.")]
[global::Bond.Attribute("Description", "Name of the instance where the application is running. Computer name for on-premisis, instance name for Azure.")]
[global::Bond.Attribute("MaxStringLength", "256")]
[global::Bond.Id(715)]
public string CloudRoleInstance { get; set; }
@ -150,11 +150,6 @@ namespace AI
[global::Bond.Id(1001)]
public string InternalAgentVersion { get; set; }
[global::Bond.Attribute("Description", "This is the node name used for billing purposes. Use it to override the standard detection of nodes.")]
[global::Bond.Attribute("MaxStringLength", "256")]
[global::Bond.Id(1002)]
public string InternalNodeName { get; set; }
public ContextTagKeys()
: this("AI.ContextTagKeys", "ContextTagKeys")
{}
@ -184,7 +179,6 @@ namespace AI
CloudRoleInstance = "ai.cloud.roleInstance";
InternalSdkVersion = "ai.internal.sdkVersion";
InternalAgentVersion = "ai.internal.agentVersion";
InternalNodeName = "ai.internal.nodeName";
}
}
} // AI

Просмотреть файл

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
//
// Tool : Bond Compiler 0.10.0.0
// Tool : Bond Compiler 0.10.1.0
// File : DataPointType_types.cs
//
// Changes to this file may cause incorrect behavior and will be lost when
@ -29,7 +29,7 @@ namespace AI
using System.Collections.Generic;
[global::Bond.Attribute("Description", "Type of the metric data measurement.")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.0.0")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
public enum DataPointType
{
Measurement,

Просмотреть файл

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
//
// Tool : Bond Compiler 0.10.0.0
// Tool : Bond Compiler 0.10.1.0
// File : DataPoint_types.cs
//
// Changes to this file may cause incorrect behavior and will be lost when
@ -30,7 +30,7 @@ namespace AI
[global::Bond.Attribute("Description", "Metric data single measurement.")]
[global::Bond.Schema]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.0.0")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
public partial class DataPoint
{
[global::Bond.Attribute("Description", "Name of the metric.")]

Просмотреть файл

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
//
// Tool : Bond Compiler 0.10.0.0
// Tool : Bond Compiler 0.10.1.0
// File : Data_types.cs
//
// Changes to this file may cause incorrect behavior and will be lost when
@ -30,7 +30,7 @@ namespace AI
[global::Bond.Attribute("Description", "Data struct to contain both B and C sections.")]
[global::Bond.Schema]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.0.0")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
public partial class Data<TDomain>
: Base
{

Просмотреть файл

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
//
// Tool : Bond Compiler 0.10.0.0
// Tool : Bond Compiler 0.10.1.0
// File : Domain_types.cs
//
// Changes to this file may cause incorrect behavior and will be lost when
@ -30,7 +30,7 @@ namespace AI
[global::Bond.Attribute("Description", "The abstract common base of all domains.")]
[global::Bond.Schema]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.0.0")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
public partial class Domain
{

Просмотреть файл

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
//
// Tool : Bond Compiler 0.10.0.0
// Tool : Bond Compiler 0.10.1.0
// File : Envelope_types.cs
//
// Changes to this file may cause incorrect behavior and will be lost when
@ -30,7 +30,7 @@ namespace AI
[global::Bond.Attribute("Description", "System variables for a telemetry item.")]
[global::Bond.Schema]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.0.0")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
public partial class Envelope
{
[global::Bond.Attribute("Description", "Envelope version. For internal use only. By assigning this the default, it will not be serialized within the payload unless changed to a value other than #1.")]
@ -74,8 +74,8 @@ namespace AI
[global::Bond.Attribute("Name", "Tags")]
[global::Bond.Attribute("TypeAlias", "ContextTagKeys")]
[global::Bond.Attribute("Description", "Key/value collection of context properties. See ContextTagKeys for information on available properties.")]
[global::Bond.Id(500), global::Bond.Type(typeof(Dictionary<string, string>))]
public IDictionary<string, string> tags { get; set; }
[global::Bond.Id(500)]
public Dictionary<string, string> tags { get; set; }
[global::Bond.Attribute("Name", "TelemetryData")]
[global::Bond.Attribute("Description", "Telemetry data item.")]

Просмотреть файл

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
//
// Tool : Bond Compiler 0.10.0.0
// Tool : Bond Compiler 0.10.1.0
// File : EventData_types.cs
//
// Changes to this file may cause incorrect behavior and will be lost when
@ -30,7 +30,7 @@ namespace AI
[global::Bond.Attribute("Description", "Instances of Event represent structured event records that can be grouped and searched by their properties. Event data item also creates a metric of event count by name.")]
[global::Bond.Schema]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.0.0")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
public partial class EventData
: Domain
{
@ -47,13 +47,13 @@ namespace AI
[global::Bond.Attribute("Description", "Collection of custom properties.")]
[global::Bond.Attribute("MaxKeyLength", "150")]
[global::Bond.Attribute("MaxValueLength", "8192")]
[global::Bond.Id(100), global::Bond.Type(typeof(Dictionary<string, string>))]
public IDictionary<string, string> properties { get; set; }
[global::Bond.Id(100)]
public Dictionary<string, string> properties { get; set; }
[global::Bond.Attribute("Description", "Collection of custom measurements.")]
[global::Bond.Attribute("MaxKeyLength", "150")]
[global::Bond.Id(200), global::Bond.Type(typeof(Dictionary<string, double>))]
public IDictionary<string, double> measurements { get; set; }
[global::Bond.Id(200)]
public Dictionary<string, double> measurements { get; set; }
public EventData()
: this("AI.EventData", "EventData")

Просмотреть файл

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
//
// Tool : Bond Compiler 0.10.0.0
// Tool : Bond Compiler 0.10.1.0
// File : ExceptionData_types.cs
//
// Changes to this file may cause incorrect behavior and will be lost when
@ -30,7 +30,7 @@ namespace AI
[global::Bond.Attribute("Description", "An instance of Exception represents a handled or unhandled exception that occurred during execution of the monitored application.")]
[global::Bond.Schema]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.0.0")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
public partial class ExceptionData
: Domain
{
@ -39,8 +39,8 @@ namespace AI
public int ver { get; set; }
[global::Bond.Attribute("Description", "Exception chain - list of inner exceptions.")]
[global::Bond.Id(50), global::Bond.Type(typeof(List<ExceptionDetails>)), global::Bond.Required]
public IList<ExceptionDetails> exceptions { get; set; }
[global::Bond.Id(50), global::Bond.Required]
public List<ExceptionDetails> exceptions { get; set; }
[global::Bond.Attribute("Description", "Severity level. Mostly used to indicate exception severity level when it is reported by logging library.")]
[global::Bond.Id(60), global::Bond.Type(typeof(global::Bond.Tag.nullable<SeverityLevel>))]
@ -54,13 +54,13 @@ namespace AI
[global::Bond.Attribute("Description", "Collection of custom properties.")]
[global::Bond.Attribute("MaxKeyLength", "150")]
[global::Bond.Attribute("MaxValueLength", "8192")]
[global::Bond.Id(100), global::Bond.Type(typeof(Dictionary<string, string>))]
public IDictionary<string, string> properties { get; set; }
[global::Bond.Id(100)]
public Dictionary<string, string> properties { get; set; }
[global::Bond.Attribute("Description", "Collection of custom measurements.")]
[global::Bond.Attribute("MaxKeyLength", "150")]
[global::Bond.Id(200), global::Bond.Type(typeof(Dictionary<string, double>))]
public IDictionary<string, double> measurements { get; set; }
[global::Bond.Id(200)]
public Dictionary<string, double> measurements { get; set; }
public ExceptionData()
: this("AI.ExceptionData", "ExceptionData")

Просмотреть файл

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
//
// Tool : Bond Compiler 0.10.0.0
// Tool : Bond Compiler 0.10.1.0
// File : ExceptionDetails_types.cs
//
// Changes to this file may cause incorrect behavior and will be lost when
@ -30,7 +30,7 @@ namespace AI
[global::Bond.Attribute("Description", "Exception details of the exception in a chain.")]
[global::Bond.Schema]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.0.0")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
public partial class ExceptionDetails
{
[global::Bond.Attribute("Description", "In case exception is nested (outer exception contains inner one), the id and outerId properties are used to represent the nesting.")]
@ -47,7 +47,7 @@ namespace AI
public string typeName { get; set; }
[global::Bond.Attribute("Description", "Exception message.")]
[global::Bond.Attribute("MaxStringLength", "32768")]
[global::Bond.Attribute("MaxStringLength", "1024")]
[global::Bond.Id(40), global::Bond.Required]
public string message { get; set; }
@ -61,8 +61,8 @@ namespace AI
public string stack { get; set; }
[global::Bond.Attribute("Description", "List of stack frames. Either stack or parsedStack should have a value.")]
[global::Bond.Id(70), global::Bond.Type(typeof(List<StackFrame>))]
public IList<StackFrame> parsedStack { get; set; }
[global::Bond.Id(70)]
public List<StackFrame> parsedStack { get; set; }
public ExceptionDetails()
: this("AI.ExceptionDetails", "ExceptionDetails")

Просмотреть файл

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
//
// Tool : Bond Compiler 0.10.0.0
// Tool : Bond Compiler 0.10.1.0
// File : MessageData_types.cs
//
// Changes to this file may cause incorrect behavior and will be lost when
@ -28,9 +28,9 @@ namespace AI
{
using System.Collections.Generic;
[global::Bond.Attribute("Description", "Instances of Message represent printf-like trace statements that are text-searched. Log4Net, NLog and other text-based log file entries are translated into instances of this type. The message does not have measurements.")]
[global::Bond.Attribute("Description", "Instances of Message represent printf-like trace statements that are text-searched. Log4Net, NLog and other text-based log file entries are translated into intances of this type. The message does not have measurements.")]
[global::Bond.Schema]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.0.0")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
public partial class MessageData
: Domain
{
@ -50,8 +50,8 @@ namespace AI
[global::Bond.Attribute("Description", "Collection of custom properties.")]
[global::Bond.Attribute("MaxKeyLength", "150")]
[global::Bond.Attribute("MaxValueLength", "8192")]
[global::Bond.Id(100), global::Bond.Type(typeof(Dictionary<string, string>))]
public IDictionary<string, string> properties { get; set; }
[global::Bond.Id(100)]
public Dictionary<string, string> properties { get; set; }
public MessageData()
: this("AI.MessageData", "MessageData")

Просмотреть файл

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
//
// Tool : Bond Compiler 0.10.0.0
// Tool : Bond Compiler 0.10.1.0
// File : MetricData_types.cs
//
// Changes to this file may cause incorrect behavior and will be lost when
@ -30,7 +30,7 @@ namespace AI
[global::Bond.Attribute("Description", "An instance of the Metric item is a list of measurements (single data points) and/or aggregations.")]
[global::Bond.Schema]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.0.0")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
public partial class MetricData
: Domain
{
@ -39,14 +39,14 @@ namespace AI
public int ver { get; set; }
[global::Bond.Attribute("Description", "List of metrics.")]
[global::Bond.Id(20), global::Bond.Type(typeof(List<DataPoint>)), global::Bond.Required]
public IList<DataPoint> metrics { get; set; }
[global::Bond.Id(20), global::Bond.Required]
public List<DataPoint> metrics { get; set; }
[global::Bond.Attribute("Description", "Collection of custom properties.")]
[global::Bond.Attribute("MaxKeyLength", "150")]
[global::Bond.Attribute("MaxValueLength", "8192")]
[global::Bond.Id(100), global::Bond.Type(typeof(Dictionary<string, string>))]
public IDictionary<string, string> properties { get; set; }
[global::Bond.Id(100)]
public Dictionary<string, string> properties { get; set; }
public MetricData()
: this("AI.MetricData", "MetricData")

Просмотреть файл

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
//
// Tool : Bond Compiler 0.10.0.0
// Tool : Bond Compiler 0.10.1.0
// File : PageViewData_types.cs
//
// Changes to this file may cause incorrect behavior and will be lost when
@ -31,7 +31,7 @@ namespace AI
[global::Bond.Attribute("Description", "An instance of PageView represents a generic action on a page like a button click. It is also the base type for PageView.")]
[global::Bond.Attribute("Alias", "PageviewData;PageEventData")]
[global::Bond.Schema]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.0.0")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
public partial class PageViewData
: EventData
{

Просмотреть файл

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
//
// Tool : Bond Compiler 0.10.0.0
// Tool : Bond Compiler 0.10.1.0
// File : PageViewPerfData_types.cs
//
// Changes to this file may cause incorrect behavior and will be lost when
@ -31,7 +31,7 @@ namespace AI
[global::Bond.Attribute("Description", "An instance of PageViewPerf represents: a page view with no performance data, a page view with performance data, or just the performance data of an earlier page request.")]
[global::Bond.Attribute("Alias", "PageViewPerformanceData;PageviewPerformanceData")]
[global::Bond.Schema]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.0.0")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
public partial class PageViewPerfData
: PageViewData
{

Просмотреть файл

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
//
// Tool : Bond Compiler 0.10.0.0
// Tool : Bond Compiler 0.10.1.0
// File : RemoteDependencyData_types.cs
//
// Changes to this file may cause incorrect behavior and will be lost when
@ -30,7 +30,7 @@ namespace AI
[global::Bond.Attribute("Description", "An instance of Remote Dependency represents an interaction of the monitored component with a remote component/service like SQL or an HTTP endpoint.")]
[global::Bond.Schema]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.0.0")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
public partial class RemoteDependencyData
: Domain
{
@ -59,7 +59,7 @@ namespace AI
[global::Bond.Id(61), global::Bond.Required]
public string duration { get; set; }
[global::Bond.Attribute("Description", "Indication of successful or unsuccessful call.")]
[global::Bond.Attribute("Description", "Indication of successfull or unsuccessfull call.")]
[global::Bond.Id(120)]
public bool success { get; set; }
@ -81,13 +81,13 @@ namespace AI
[global::Bond.Attribute("Description", "Collection of custom properties.")]
[global::Bond.Attribute("MaxKeyLength", "150")]
[global::Bond.Attribute("MaxValueLength", "8192")]
[global::Bond.Id(200), global::Bond.Type(typeof(Dictionary<string, string>))]
public IDictionary<string, string> properties { get; set; }
[global::Bond.Id(200)]
public Dictionary<string, string> properties { get; set; }
[global::Bond.Attribute("Description", "Collection of custom measurements.")]
[global::Bond.Attribute("MaxKeyLength", "150")]
[global::Bond.Id(300), global::Bond.Type(typeof(Dictionary<string, double>))]
public IDictionary<string, double> measurements { get; set; }
[global::Bond.Id(300)]
public Dictionary<string, double> measurements { get; set; }
public RemoteDependencyData()
: this("AI.RemoteDependencyData", "RemoteDependencyData")

Просмотреть файл

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
//
// Tool : Bond Compiler 0.10.0.0
// Tool : Bond Compiler 0.10.1.0
// File : RequestData_types.cs
//
// Changes to this file may cause incorrect behavior and will be lost when
@ -30,7 +30,7 @@ namespace AI
[global::Bond.Attribute("Description", "An instance of Request represents completion of an external request to the application to do work and contains a summary of that request execution and the results.")]
[global::Bond.Schema]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.0.0")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
public partial class RequestData
: Domain
{
@ -43,11 +43,6 @@ namespace AI
[global::Bond.Id(20), global::Bond.Required]
public string id { get; set; }
[global::Bond.Attribute("MaxStringLength", "1024")]
[global::Bond.Attribute("Description", "Source of the request. Examples are the instrumentation key of the caller or the ip address of the caller.")]
[global::Bond.Id(29)]
public string source { get; set; }
[global::Bond.Attribute("MaxStringLength", "1024")]
[global::Bond.Attribute("Description", "Name of the request. Represents code path taken to process request. Low cardinality value to allow better grouping of requests. For HTTP requests it represents the HTTP method and URL path template like 'GET /values/{id}'.")]
[global::Bond.Id(30)]
@ -63,7 +58,7 @@ namespace AI
[global::Bond.Id(60), global::Bond.Required]
public string responseCode { get; set; }
[global::Bond.Attribute("Description", "Indication of successful or unsuccessful call.")]
[global::Bond.Attribute("Description", "Indication of successfull or unsuccessfull call.")]
[global::Bond.Id(70), global::Bond.Required]
public bool success { get; set; }
@ -75,13 +70,13 @@ namespace AI
[global::Bond.Attribute("Description", "Collection of custom properties.")]
[global::Bond.Attribute("MaxKeyLength", "150")]
[global::Bond.Attribute("MaxValueLength", "8192")]
[global::Bond.Id(100), global::Bond.Type(typeof(Dictionary<string, string>))]
public IDictionary<string, string> properties { get; set; }
[global::Bond.Id(100)]
public Dictionary<string, string> properties { get; set; }
[global::Bond.Attribute("Description", "Collection of custom measurements.")]
[global::Bond.Attribute("MaxKeyLength", "150")]
[global::Bond.Id(200), global::Bond.Type(typeof(Dictionary<string, double>))]
public IDictionary<string, double> measurements { get; set; }
[global::Bond.Id(200)]
public Dictionary<string, double> measurements { get; set; }
public RequestData()
: this("AI.RequestData", "RequestData")
@ -91,7 +86,6 @@ namespace AI
{
ver = 2;
id = "";
source = "";
this.name = "";
duration = "";
responseCode = "";

Просмотреть файл

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
//
// Tool : Bond Compiler 0.10.0.0
// Tool : Bond Compiler 0.10.1.0
// File : SeverityLevel_types.cs
//
// Changes to this file may cause incorrect behavior and will be lost when
@ -29,7 +29,7 @@ namespace AI
using System.Collections.Generic;
[global::Bond.Attribute("Description", "Defines the level of severity for the event.")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.0.0")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
public enum SeverityLevel
{
Verbose,

Просмотреть файл

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
//
// Tool : Bond Compiler 0.10.0.0
// Tool : Bond Compiler 0.10.1.0
// File : StackFrame_types.cs
//
// Changes to this file may cause incorrect behavior and will be lost when
@ -30,7 +30,7 @@ namespace AI
[global::Bond.Attribute("Description", "Stack frame information.")]
[global::Bond.Schema]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.0.0")]
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
public partial class StackFrame
{
[global::Bond.Attribute("Description", "Level in the call stack. For the long stacks SDK may not report every function in a call stack.")]

Просмотреть файл

@ -1,19 +1,19 @@
..\..\..\Schema\PublicSchema\AvailabilityData.bond
..\..\..\Schema\PublicSchema\Base.bond
..\..\..\Schema\PublicSchema\ContextTagKeys.bond
..\..\..\Schema\PublicSchema\Data.bond
..\..\..\Schema\PublicSchema\DataPoint.bond
..\..\..\Schema\PublicSchema\DataPointType.bond
..\..\..\Schema\PublicSchema\Domain.bond
..\..\..\Schema\PublicSchema\Envelope.bond
..\..\..\Schema\PublicSchema\EventData.bond
..\..\..\Schema\PublicSchema\ExceptionData.bond
..\..\..\Schema\PublicSchema\ExceptionDetails.bond
..\..\..\Schema\PublicSchema\MessageData.bond
..\..\..\Schema\PublicSchema\MetricData.bond
..\..\..\Schema\PublicSchema\PageViewData.bond
..\..\..\Schema\PublicSchema\PageViewPerfData.bond
..\..\..\Schema\PublicSchema\RemoteDependencyData.bond
..\..\..\Schema\PublicSchema\RequestData.bond
..\..\..\Schema\PublicSchema\SeverityLevel.bond
..\..\..\Schema\PublicSchema\StackFrame.bond
..\..\Schema\PublicSchema\AvailabilityData.bond
..\..\Schema\PublicSchema\Base.bond
..\..\Schema\PublicSchema\ContextTagKeys.bond
..\..\Schema\PublicSchema\Data.bond
..\..\Schema\PublicSchema\DataPoint.bond
..\..\Schema\PublicSchema\DataPointType.bond
..\..\Schema\PublicSchema\Domain.bond
..\..\Schema\PublicSchema\Envelope.bond
..\..\Schema\PublicSchema\EventData.bond
..\..\Schema\PublicSchema\ExceptionData.bond
..\..\Schema\PublicSchema\ExceptionDetails.bond
..\..\Schema\PublicSchema\MessageData.bond
..\..\Schema\PublicSchema\MetricData.bond
..\..\Schema\PublicSchema\PageViewData.bond
..\..\Schema\PublicSchema\PageViewPerfData.bond
..\..\Schema\PublicSchema\RemoteDependencyData.bond
..\..\Schema\PublicSchema\RequestData.bond
..\..\Schema\PublicSchema\SeverityLevel.bond
..\..\Schema\PublicSchema\StackFrame.bond

Просмотреть файл

@ -1,5 +1,6 @@
namespace EmptyApp20.FunctionalTests.FunctionalTest
{
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using AI;
@ -29,7 +30,13 @@
expectedRequestTelemetry.Success = true;
expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath);
this.ValidateBasicRequest(server, RequestPath, expectedRequestTelemetry);
Dictionary<string, string> requestHeaders = new Dictionary<string, string>()
{
{ "Request-Id", ""},
{ "Request-Context", "appId=value"},
};
this.ValidateRequestWithHeaders(server, RequestPath, requestHeaders, expectedRequestTelemetry, expectRequestContextInResponse: true);
}
}
@ -46,7 +53,13 @@
expectedRequestTelemetry.Success = false;
expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath);
this.ValidateBasicRequest(server, RequestPath, expectedRequestTelemetry);
Dictionary<string, string> requestHeaders = new Dictionary<string, string>()
{
{ "Request-Id", ""},
{ "Request-Context", "appId=value"},
};
this.ValidateRequestWithHeaders(server, RequestPath, requestHeaders, expectedRequestTelemetry, expectRequestContextInResponse: true);
}
}

Просмотреть файл

@ -1,5 +1,6 @@
namespace MVCFramework20.FunctionalTests.FunctionalTest
{
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
@ -30,7 +31,13 @@
expectedRequestTelemetry.Success = true;
expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath);
this.ValidateBasicRequest(server, RequestPath, expectedRequestTelemetry);
Dictionary<string, string> requestHeaders = new Dictionary<string, string>()
{
{ "Request-Id", ""},
{ "Request-Context", "appId=value"},
};
this.ValidateRequestWithHeaders(server, RequestPath, requestHeaders, expectedRequestTelemetry, expectRequestContextInResponse: true);
}
}
@ -47,7 +54,13 @@
expectedRequestTelemetry.Success = true;
expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath);
this.ValidateBasicRequest(server, RequestPath, expectedRequestTelemetry);
Dictionary<string, string> requestHeaders = new Dictionary<string, string>()
{
{ "Request-Id", ""},
{ "Request-Context", "appId=value"},
};
this.ValidateRequestWithHeaders(server, RequestPath, requestHeaders, expectedRequestTelemetry, expectRequestContextInResponse: true);
}
}
@ -64,7 +77,13 @@
expectedRequestTelemetry.Success = false;
expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath);
this.ValidateBasicRequest(server, RequestPath, expectedRequestTelemetry);
Dictionary<string, string> requestHeaders = new Dictionary<string, string>()
{
{ "Request-Id", ""},
{ "Request-Context", "appId=value"},
};
this.ValidateRequestWithHeaders(server, RequestPath, requestHeaders, expectedRequestTelemetry, expectRequestContextInResponse: true);
}
}

Просмотреть файл

@ -70,17 +70,32 @@
private ConcurrentQueue<ITelemetry> sentTelemetry = new ConcurrentQueue<ITelemetry>();
private ActiveSubsciptionManager subscriptionManager;
private HostingDiagnosticListener CreateHostingListener(bool aspNetCore2)
private HostingDiagnosticListener CreateHostingListener(bool aspNetCore2, TelemetryConfiguration config = null)
{
var hostingListener = new HostingDiagnosticListener(
CommonMocks.MockTelemetryClient(telemetry => this.sentTelemetry.Enqueue(telemetry)),
CommonMocks.GetMockApplicationIdProvider(),
injectResponseHeaders: true,
trackExceptions: true,
enableW3CHeaders: false,
enableNewDiagnosticEvents: aspNetCore2);
hostingListener.OnSubscribe();
HostingDiagnosticListener hostingListener;
if (config != null)
{
hostingListener = new HostingDiagnosticListener(
config,
CommonMocks.MockTelemetryClient(telemetry => this.sentTelemetry.Enqueue(telemetry)),
CommonMocks.GetMockApplicationIdProvider(),
injectResponseHeaders: true,
trackExceptions: true,
enableW3CHeaders: false,
enableNewDiagnosticEvents: aspNetCore2);
}
else
{
hostingListener = new HostingDiagnosticListener(
CommonMocks.MockTelemetryClient(telemetry => this.sentTelemetry.Enqueue(telemetry)),
CommonMocks.GetMockApplicationIdProvider(),
injectResponseHeaders: true,
trackExceptions: true,
enableW3CHeaders: false,
enableNewDiagnosticEvents: aspNetCore2);
}
hostingListener.OnSubscribe();
return hostingListener;
}
@ -90,15 +105,16 @@
public void TestSdkVersionIsPopulatedByMiddleware(bool isAspNetCore2)
{
HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost);
TelemetryConfiguration config = TelemetryConfiguration.CreateDefault();
config.ExperimentalFeatures.Add("conditionalAppId");
using (var hostingListener = CreateHostingListener(isAspNetCore2))
using (var hostingListener = CreateHostingListener(isAspNetCore2, config))
{
HandleRequestBegin(hostingListener, context, 0, isAspNetCore2);
Assert.NotNull(context.Features.Get<RequestTelemetry>());
Assert.Equal(CommonMocks.TestApplicationId,
HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers,
Assert.Null(HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers,
RequestResponseHeaders.RequestContextTargetKey));
HandleRequestEnd(hostingListener, context, 0, isAspNetCore2);
@ -130,8 +146,7 @@
Assert.NotNull(context.Features.Get<RequestTelemetry>());
Assert.Equal(CommonMocks.TestApplicationId,
HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers,
RequestResponseHeaders.RequestContextTargetKey));
HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers, RequestResponseHeaders.RequestContextTargetKey));
HandleRequestEnd(hostingListener, context, 0, isAspNetCore2);
}
@ -162,8 +177,7 @@
Assert.NotNull(context.Features.Get<RequestTelemetry>());
Assert.Equal(CommonMocks.TestApplicationId,
HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers,
RequestResponseHeaders.RequestContextTargetKey));
HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers, RequestResponseHeaders.RequestContextTargetKey));
hostingListener.OnDiagnosticsUnhandledException(context, null);
HandleRequestEnd(hostingListener, context, 0, isAspNetCore2);
@ -345,8 +359,7 @@
Assert.NotNull(context.Features.Get<RequestTelemetry>());
Assert.Equal(CommonMocks.TestApplicationId,
HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers,
RequestResponseHeaders.RequestContextTargetKey));
HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers, RequestResponseHeaders.RequestContextTargetKey));
HandleRequestEnd(hostingListener, context, 0, isAspNetCore2);
}
@ -370,13 +383,15 @@
public void OnEndRequestSetsRequestNameToMethodAndPath(bool isAspNetCore2)
{
HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "GET");
using (var hostingListener = CreateHostingListener(isAspNetCore2))
TelemetryConfiguration config = TelemetryConfiguration.CreateDefault();
config.ExperimentalFeatures.Add("conditionalAppId");
using (var hostingListener = CreateHostingListener(isAspNetCore2, config))
{
HandleRequestBegin(hostingListener, context, 0, isAspNetCore2);
Assert.NotNull(context.Features.Get<RequestTelemetry>());
Assert.Equal(CommonMocks.TestApplicationId,
HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers,
Assert.Null(HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers,
RequestResponseHeaders.RequestContextTargetKey));
HandleRequestEnd(hostingListener, context, 0, isAspNetCore2);
@ -401,17 +416,15 @@
public void OnEndRequestFromSameInstrumentationKey(bool isAspNetCore2)
{
HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "GET");
HttpHeadersUtilities.SetRequestContextKeyValue(context.Request.Headers, RequestResponseHeaders.RequestContextSourceKey, CommonMocks.TestApplicationId);
HttpHeadersUtilities.SetRequestContextKeyValue(context.Request.Headers, RequestResponseHeaders.RequestContextSourceKey, CommonMocks.TestApplicationId);
using (var hostingListener = CreateHostingListener(isAspNetCore2))
{
HandleRequestBegin(hostingListener, context, 0, isAspNetCore2);
Assert.NotNull(context.Features.Get<RequestTelemetry>());
Assert.Equal(CommonMocks.TestApplicationId,
HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers,
RequestResponseHeaders.RequestContextTargetKey));
HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers, RequestResponseHeaders.RequestContextTargetKey));
HandleRequestEnd(hostingListener, context, 0, isAspNetCore2);
}
@ -682,6 +695,7 @@
"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01";
context.Request.Headers[W3C.W3CConstants.TraceStateHeader] = "state=some";
context.Request.Headers[RequestResponseHeaders.CorrelationContextHeader] = "k=v";
context.Request.Headers[RequestResponseHeaders.RequestContextHeader] = "appId=something";
HandleRequestBegin(hostingListener, context, 0, isAspNetCore2);
@ -732,6 +746,7 @@
"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01";
context.Request.Headers[W3C.W3CConstants.TraceStateHeader] = "state=some";
context.Request.Headers[RequestResponseHeaders.CorrelationContextHeader] = "k=v";
context.Request.Headers[RequestResponseHeaders.RequestContextHeader] = "appId=something";
HandleRequestBegin(hostingListener, context, 0, isAspNetCore2);
@ -831,6 +846,7 @@
hostingListener.OnSubscribe();
var context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST");
context.Request.Headers[RequestResponseHeaders.RequestContextHeader] = "appId=something";
HandleRequestBegin(hostingListener, context, 0, isAspNetCore2);
@ -904,6 +920,57 @@
}
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public void RequestTelemetryIsProactivelySampledOutIfFeatureFlagIsOn(bool isAspNetCore2)
{
TelemetryConfiguration config = TelemetryConfiguration.CreateDefault();
config.ExperimentalFeatures.Add("proactiveSampling");
config.SetLastObservedSamplingPercentage(SamplingTelemetryItemTypes.Request, 0);
HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST");
using (var hostingListener = CreateHostingListener(isAspNetCore2, config))
{
HandleRequestBegin(hostingListener, context, 0, isAspNetCore2);
Assert.NotNull(Activity.Current);
var requestTelemetry = context.Features.Get<RequestTelemetry>();
Assert.NotNull(requestTelemetry);
Assert.Equal(requestTelemetry.Id, Activity.Current.Id);
Assert.Equal(requestTelemetry.Context.Operation.Id, Activity.Current.RootId);
Assert.Null(requestTelemetry.Context.Operation.ParentId);
Assert.True(requestTelemetry.IsSampledOutAtHead);
}
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public void RequestTelemetryIsNotProactivelySampledOutIfFeatureFlasIfOff(bool isAspNetCore2)
{
TelemetryConfiguration config = TelemetryConfiguration.CreateDefault();
config.SetLastObservedSamplingPercentage(SamplingTelemetryItemTypes.Request, 0);
HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST");
using (var hostingListener = CreateHostingListener(isAspNetCore2, config))
{
HandleRequestBegin(hostingListener, context, 0, isAspNetCore2);
Assert.NotNull(Activity.Current);
var requestTelemetry = context.Features.Get<RequestTelemetry>();
Assert.NotNull(requestTelemetry);
Assert.Equal(requestTelemetry.Id, Activity.Current.Id);
Assert.Equal(requestTelemetry.Context.Operation.Id, Activity.Current.RootId);
Assert.Null(requestTelemetry.Context.Operation.ParentId);
Assert.False(requestTelemetry.IsSampledOutAtHead);
}
}
private void HandleRequestBegin(HostingDiagnosticListener hostingListener, HttpContext context, long timestamp, bool isAspNetCore2)
{
if (isAspNetCore2)

Просмотреть файл

@ -4,21 +4,33 @@ namespace Microsoft.ApplicationInsights.AspNetCore.Tests.TelemetryInitializers
{
using System;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using Microsoft.ApplicationInsights.AspNetCore.TelemetryInitializers;
using Microsoft.ApplicationInsights.AspNetCore.Tests.Helpers;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http.Internal;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Routing;
using Xunit;
using Microsoft.AspNetCore.Routing.Tree;
using Microsoft.AspNetCore.Http;
public class OperationNameTelemetryInitializerTests
{
private const string TestListenerName = "TestListener";
private HostingDiagnosticListener CreateHostingListener(bool aspNetCore2)
{
var hostingListener = new HostingDiagnosticListener(
CommonMocks.MockTelemetryClient(telemetry => {}),
CommonMocks.GetMockApplicationIdProvider(),
injectResponseHeaders: true,
trackExceptions: true,
enableW3CHeaders: false,
enableNewDiagnosticEvents: aspNetCore2);
hostingListener.OnSubscribe();
return hostingListener;
}
[Fact]
public void InitializeThrowIfHttpContextAccessorIsNull()
{
@ -85,11 +97,12 @@ namespace Microsoft.ApplicationInsights.AspNetCore.Tests.TelemetryInitializers
var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(new RequestTelemetry(), actionContext);
var telemetryListener = new DiagnosticListener(TestListenerName);
var initializer = new MvcDiagnosticsListener();
telemetryListener.Subscribe(initializer);
telemetryListener.Write("Microsoft.AspNetCore.Mvc.BeforeAction",
new { httpContext = contextAccessor.HttpContext, routeData = actionContext.RouteData });
using (var listener = CreateHostingListener(false))
{
telemetryListener.Subscribe(listener);
telemetryListener.Write("Microsoft.AspNetCore.Mvc.BeforeAction",
new { httpContext = contextAccessor.HttpContext, routeData = actionContext.RouteData });
}
var telemetry = contextAccessor.HttpContext.Features.Get<RequestTelemetry>();
Assert.Equal("GET home", telemetry.Name);
@ -106,11 +119,12 @@ namespace Microsoft.ApplicationInsights.AspNetCore.Tests.TelemetryInitializers
var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(new RequestTelemetry(), actionContext);
var telemetryListener = new DiagnosticListener(TestListenerName);
var initializer = new MvcDiagnosticsListener();
telemetryListener.Subscribe(initializer);
telemetryListener.Write("Microsoft.AspNetCore.Mvc.BeforeAction",
new { httpContext = contextAccessor.HttpContext, routeData = actionContext.RouteData });
using (var listener = CreateHostingListener(false))
{
telemetryListener.Subscribe(listener);
telemetryListener.Write("Microsoft.AspNetCore.Mvc.BeforeAction",
new { httpContext = contextAccessor.HttpContext, routeData = actionContext.RouteData });
}
var telemetry = contextAccessor.HttpContext.Features.Get<RequestTelemetry>();
Assert.Equal("GET account/login", telemetry.Name);
@ -126,11 +140,12 @@ namespace Microsoft.ApplicationInsights.AspNetCore.Tests.TelemetryInitializers
var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(new RequestTelemetry(), actionContext);
var telemetryListener = new DiagnosticListener(TestListenerName);
var initializer = new MvcDiagnosticsListener();
telemetryListener.Subscribe(initializer);
telemetryListener.Write("Microsoft.AspNetCore.Mvc.BeforeAction",
new { httpContext = contextAccessor.HttpContext, routeData = actionContext.RouteData });
using (var listener = CreateHostingListener(false))
{
telemetryListener.Subscribe(listener);
telemetryListener.Write("Microsoft.AspNetCore.Mvc.BeforeAction",
new { httpContext = contextAccessor.HttpContext, routeData = actionContext.RouteData });
}
var telemetry = contextAccessor.HttpContext.Features.Get<RequestTelemetry>();
Assert.Equal("GET /Index", telemetry.Name);
@ -148,10 +163,12 @@ namespace Microsoft.ApplicationInsights.AspNetCore.Tests.TelemetryInitializers
var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(new RequestTelemetry(), actionContext);
var telemetryListener = new DiagnosticListener(TestListenerName);
var initializer = new MvcDiagnosticsListener();
telemetryListener.Subscribe(initializer);
telemetryListener.Write("Microsoft.AspNetCore.Mvc.BeforeAction",
new { httpContext = contextAccessor.HttpContext, routeData = actionContext.RouteData });
using (var listener = CreateHostingListener(false))
{
telemetryListener.Subscribe(listener);
telemetryListener.Write("Microsoft.AspNetCore.Mvc.BeforeAction",
new { httpContext = contextAccessor.HttpContext, routeData = actionContext.RouteData });
}
var telemetry = contextAccessor.HttpContext.Features.Get<RequestTelemetry>();
@ -172,11 +189,12 @@ namespace Microsoft.ApplicationInsights.AspNetCore.Tests.TelemetryInitializers
var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(new RequestTelemetry(), actionContext);
var telemetryListener = new DiagnosticListener(TestListenerName);
var initializer = new MvcDiagnosticsListener();
telemetryListener.Subscribe(initializer);
telemetryListener.Write("Microsoft.AspNetCore.Mvc.BeforeAction",
new { httpContext = contextAccessor.HttpContext, routeData = actionContext.RouteData });
using (var listener = CreateHostingListener(false))
{
telemetryListener.Subscribe(listener);
telemetryListener.Write("Microsoft.AspNetCore.Mvc.BeforeAction",
new { httpContext = contextAccessor.HttpContext, routeData = actionContext.RouteData });
}
var telemetry = contextAccessor.HttpContext.Features.Get<RequestTelemetry>();
Assert.Equal("GET account/login [parameterA/parameterN/parameterZ]", telemetry.Name);
@ -193,13 +211,14 @@ namespace Microsoft.ApplicationInsights.AspNetCore.Tests.TelemetryInitializers
var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(new RequestTelemetry(), actionContext);
var telemetryListener = new DiagnosticListener(TestListenerName);
var initializer = new MvcDiagnosticsListener();
telemetryListener.Subscribe(initializer);
telemetryListener.Write("Microsoft.AspNetCore.Mvc.BeforeAction",
new { httpContext = contextAccessor.HttpContext, routeData = actionContext.RouteData });
using (var listener = CreateHostingListener(false))
{
telemetryListener.Subscribe(listener);
telemetryListener.Write("Microsoft.AspNetCore.Mvc.BeforeAction",
new { httpContext = contextAccessor.HttpContext, routeData = actionContext.RouteData });
}
var telemetry = contextAccessor.HttpContext.Features.Get<RequestTelemetry>();
Assert.Equal("GET account/login", telemetry.Name);
}

Просмотреть файл

@ -34,7 +34,13 @@
expectedRequestTelemetry.Success = true;
expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath);
this.ValidateBasicRequest(server, RequestPath, expectedRequestTelemetry);
Dictionary<string, string> requestHeaders = new Dictionary<string, string>()
{
{ "Request-Id", ""},
{ "Request-Context", "appId=value"},
};
this.ValidateRequestWithHeaders(server, RequestPath, requestHeaders, expectedRequestTelemetry, expectRequestContextInResponse: true);
}
}
@ -51,7 +57,13 @@
expectedRequestTelemetry.Success = false;
expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath);
this.ValidateBasicRequest(server, RequestPath, expectedRequestTelemetry);
Dictionary<string, string> requestHeaders = new Dictionary<string, string>()
{
{ "Request-Id", ""},
{ "Request-Context", "appId=value"},
};
this.ValidateRequestWithHeaders(server, RequestPath, requestHeaders, expectedRequestTelemetry, expectRequestContextInResponse: true);
}
}
@ -68,7 +80,13 @@
expectedRequestTelemetry.Success = true;
expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath);
this.ValidateBasicRequest(server, RequestPath, expectedRequestTelemetry);
Dictionary<string, string> requestHeaders = new Dictionary<string, string>()
{
{ "Request-Id", ""},
{ "Request-Context", "appId=value"},
};
this.ValidateRequestWithHeaders(server, RequestPath, requestHeaders, expectedRequestTelemetry, expectRequestContextInResponse: true);
}
}
@ -121,7 +139,7 @@
expectedRequestTelemetry.Success = true;
expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath);
var item = this.ValidateBasicRequest(server, RequestPath, expectedRequestTelemetry, true);
var item = this.ValidateBasicRequest(server, RequestPath, expectedRequestTelemetry);
// W3C compatible-Id ( should go away when W3C is implemented in .NET https://github.com/dotnet/corefx/issues/30331)
Assert.Equal(32, item.tags["ai.operation.id"].Length);