Merge pull request #961 from microsoft/develop
Dev to Master for 2.8.0-beta2
This commit is contained in:
Коммит
f05e6140a0
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -1,10 +1,21 @@
|
|||
# Changelog
|
||||
|
||||
## Version 2.8.0-beta2
|
||||
- [Fix MVCBeforeAction property fetcher to work with .NET Core 3.0 changes.](https://github.com/microsoft/ApplicationInsights-aspnetcore/issues/936)
|
||||
- [Catch generic exception from DiagnosticSourceListeners and log instead of failing user request.](https://github.com/microsoft/ApplicationInsights-aspnetcore/issues/957)
|
||||
- [Correct names for Asp.Net Core EventCounters.](https://github.com/microsoft/ApplicationInsights-aspnetcore/issues/945)
|
||||
- [Obsolete extension methods on IWebHostBuilder in favor of AddApplicationInsights extension method on IServiceCollection.](https://github.com/microsoft/ApplicationInsights-aspnetcore/issues/919)
|
||||
- [Remove support for deprecated x-ms based correlation headers.](https://github.com/microsoft/ApplicationInsights-aspnetcore/issues/939)
|
||||
- [Uri for multiple hosts headers is set to "Multiple-Host".](https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/862)
|
||||
- [LogLevel changed to Error and stack trace added for generic unknown exception within SDK.](https://github.com/microsoft/ApplicationInsights-aspnetcore/pull/946)
|
||||
|
||||
## 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)
|
||||
- Updated Web/Base SDK version dependency to 2.10.0-beta4
|
||||
- Updated Microsoft.Extensions.Logging.ApplicationInsights to 2.10.0-beta4
|
||||
|
||||
## Version 2.7.1
|
||||
- [Fix - ApplicationInsights StartupFilter should not swallow exceptions from downstream ApplicationBuilder.](https://github.com/microsoft/ApplicationInsights-aspnetcore/issues/897)
|
||||
|
|
|
@ -70,7 +70,7 @@ struct ContextTagKeys
|
|||
[MaxStringLength("1024")]
|
||||
505: string UserAccountId = "ai.user.accountId";
|
||||
|
||||
[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.")]
|
||||
[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.")]
|
||||
[MaxStringLength("2048")]
|
||||
510: string UserAgent = "ai.user.userAgent";
|
||||
|
||||
|
@ -86,7 +86,7 @@ struct ContextTagKeys
|
|||
[MaxStringLength("256")]
|
||||
705: string CloudRole = "ai.cloud.role";
|
||||
|
||||
[Description("Name of the instance where the application is running. Computer name for on-premisis, instance name for Azure.")]
|
||||
[Description("Name of the instance where the application is running. Computer name for on-premises, instance name for Azure.")]
|
||||
[MaxStringLength("256")]
|
||||
715: string CloudRoleInstance = "ai.cloud.roleInstance";
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import "SeverityLevel.bond"
|
|||
|
||||
namespace AI
|
||||
|
||||
[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.")]
|
||||
[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.")]
|
||||
struct MessageData
|
||||
: Domain
|
||||
{
|
||||
|
|
|
@ -26,7 +26,7 @@ struct RemoteDependencyData
|
|||
[ActAsRequired("Renaming value to duration.")]
|
||||
61: required string duration;
|
||||
|
||||
[Description("Indication of successfull or unsuccessfull call.")]
|
||||
[Description("Indication of successful or unsuccessful call.")]
|
||||
120: bool success = true;
|
||||
|
||||
[MaxStringLength("8192")]
|
||||
|
|
|
@ -21,7 +21,7 @@ struct RequestData
|
|||
[Description("Result of a request execution. HTTP status code for HTTP requests.")]
|
||||
60: required string responseCode;
|
||||
|
||||
[Description("Indication of successfull or unsuccessfull call.")]
|
||||
[Description("Indication of successful or unsuccessful call.")]
|
||||
70: required bool success;
|
||||
|
||||
[MaxStringLength("1024")]
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
<ItemGroup>
|
||||
<!-- Automatically sign binary generated by the project that imports Signing.props and all ps1 files -->
|
||||
<FilesToSign Include="$(TargetPath)" >
|
||||
<Authenticode>Microsoft</Authenticode>
|
||||
<Authenticode>Microsoft400</Authenticode>
|
||||
<StrongName>MsSharedLib72</StrongName>
|
||||
</FilesToSign>
|
||||
<FilesToSign Include="$(OutputPath)*.ps1">
|
||||
<Authenticode>MicrosoftSHA1</Authenticode>
|
||||
<Authenticode>Microsoft400</Authenticode>
|
||||
<StrongName>10006</StrongName>
|
||||
</FilesToSign>
|
||||
</ItemGroup>
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
using Microsoft.ApplicationInsights.Extensibility;
|
||||
using Microsoft.ApplicationInsights.Extensibility.Implementation;
|
||||
using Microsoft.ApplicationInsights.Extensibility.Implementation.Experimental;
|
||||
using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing;
|
||||
using Microsoft.ApplicationInsights.Extensibility.W3C;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
@ -51,7 +52,8 @@
|
|||
|
||||
// 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 routeDataFetcher = new PropertyFetcher("routeData");
|
||||
private readonly PropertyFetcher routeDataFetcher30 = new PropertyFetcher("RouteData");
|
||||
private readonly PropertyFetcher routeValuesFetcher = new PropertyFetcher("Values");
|
||||
private readonly PropertyFetcher httpContextFetcherStart = new PropertyFetcher("HttpContext");
|
||||
private readonly PropertyFetcher httpContextFetcherStop = new PropertyFetcher("HttpContext");
|
||||
|
@ -202,7 +204,7 @@
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Diagnostic event handler method for 'Microsoft.AspNetCore.Hosting.HttpRequestIn.Start' event.
|
||||
/// Diagnostic event handler method for 'Microsoft.AspNetCore.Hosting.HttpRequestIn.Start' event. This is from 2.XX runtime.
|
||||
/// </summary>
|
||||
public void OnHttpRequestInStart(HttpContext httpContext)
|
||||
{
|
||||
|
@ -241,26 +243,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
// x-ms-*
|
||||
if (originalParentId == null &&
|
||||
httpContext.Request.Headers.TryGetValue(RequestResponseHeaders.StandardRootIdHeader, out StringValues alternativeRootIdValues) &&
|
||||
alternativeRootIdValues != StringValues.Empty)
|
||||
{
|
||||
newActivity = new Activity(ActivityCreatedByHostingDiagnosticListener)
|
||||
.SetParentId(StringUtilities.EnforceMaxLength(
|
||||
alternativeRootIdValues.First(),
|
||||
InjectionGuardConstants.RequestHeaderMaxLength));
|
||||
|
||||
if (httpContext.Request.Headers.TryGetValue(RequestResponseHeaders.StandardParentIdHeader, out StringValues parentId))
|
||||
{
|
||||
originalParentId = StringUtilities.EnforceMaxLength(
|
||||
parentId.First(),
|
||||
InjectionGuardConstants.RequestHeaderMaxLength);
|
||||
}
|
||||
}
|
||||
|
||||
// no headers
|
||||
else if (originalParentId == null)
|
||||
if (originalParentId == null)
|
||||
{
|
||||
// As a first step in supporting W3C protocol in ApplicationInsights,
|
||||
// we want to generate Activity Ids in the W3C compatible format.
|
||||
|
@ -302,7 +286,7 @@
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Diagnostic event handler method for 'Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop' event.
|
||||
/// Diagnostic event handler method for 'Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop' event. This is from 2.XX runtime.
|
||||
/// </summary>
|
||||
public void OnHttpRequestInStop(HttpContext httpContext)
|
||||
{
|
||||
|
@ -310,7 +294,7 @@
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Diagnostic event handler method for 'Microsoft.AspNetCore.Hosting.BeginRequest' event.
|
||||
/// Diagnostic event handler method for 'Microsoft.AspNetCore.Hosting.BeginRequest' event. This is from 1.XX runtime.
|
||||
/// </summary>
|
||||
public void OnBeginRequest(HttpContext httpContext, long timestamp)
|
||||
{
|
||||
|
@ -361,22 +345,6 @@
|
|||
originalParentId = requestId;
|
||||
}
|
||||
}
|
||||
|
||||
// x-ms-request-id
|
||||
else if (requestHeaders.TryGetValue(RequestResponseHeaders.StandardRootIdHeader, out StringValues alternativeRootIdValues) &&
|
||||
alternativeRootIdValues != StringValues.Empty)
|
||||
{
|
||||
string alternativeRootId = StringUtilities.EnforceMaxLength(alternativeRootIdValues.First(), InjectionGuardConstants.RequestHeaderMaxLength);
|
||||
activity.SetParentId(alternativeRootId);
|
||||
|
||||
if (originalParentId == null && requestHeaders.TryGetValue(RequestResponseHeaders.StandardParentIdHeader, out StringValues parentId))
|
||||
{
|
||||
originalParentId = StringUtilities.EnforceMaxLength(
|
||||
parentId.First(),
|
||||
InjectionGuardConstants.RequestHeaderMaxLength);
|
||||
}
|
||||
}
|
||||
|
||||
// no headers
|
||||
else if (originalParentId == null)
|
||||
{
|
||||
|
@ -416,7 +384,7 @@
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Diagnostic event handler method for 'Microsoft.AspNetCore.Hosting.EndRequest' event.
|
||||
/// Diagnostic event handler method for 'Microsoft.AspNetCore.Hosting.EndRequest' event. This is from 1.XX runtime.
|
||||
/// </summary>
|
||||
public void OnEndRequest(HttpContext httpContext, long timestamp)
|
||||
{
|
||||
|
@ -586,6 +554,7 @@
|
|||
|
||||
if (telemetry == null)
|
||||
{
|
||||
// Log we are not tracking this request as it cannot be found in context.
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -615,7 +584,8 @@
|
|||
|
||||
this.client.TrackRequest(telemetry);
|
||||
|
||||
var activity = httpContext?.Features.Get<Activity>();
|
||||
// Stop what we started.
|
||||
var activity = Activity.Current;
|
||||
if (activity != null && activity.OperationName == ActivityCreatedByHostingDiagnosticListener)
|
||||
{
|
||||
activity.Stop();
|
||||
|
@ -739,81 +709,94 @@
|
|||
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")
|
||||
try
|
||||
{
|
||||
httpContext = this.httpContextFetcherStart.Fetch(value.Value) as HttpContext;
|
||||
if (httpContext != 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")
|
||||
{
|
||||
this.OnHttpRequestInStart(httpContext);
|
||||
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)
|
||||
else if (value.Key == "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop")
|
||||
{
|
||||
this.OnHttpRequestInStop(httpContext);
|
||||
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>;
|
||||
else if (value.Key == "Microsoft.AspNetCore.Mvc.BeforeAction")
|
||||
{
|
||||
var context = this.httpContextFetcherOnBeforeAction.Fetch(value.Value) as HttpContext;
|
||||
|
||||
// Asp.Net Core 3.0 changed the field name to "RouteData" from "routeData
|
||||
var routeData = this.routeDataFetcher.Fetch(value.Value);
|
||||
if (routeData == null)
|
||||
{
|
||||
routeData = this.routeDataFetcher30.Fetch(value.Value);
|
||||
}
|
||||
|
||||
if (context != null && routeValues != null)
|
||||
{
|
||||
this.OnBeforeAction(context, routeValues);
|
||||
}
|
||||
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)
|
||||
else if (value.Key == "Microsoft.AspNetCore.Hosting.BeginRequest")
|
||||
{
|
||||
this.OnEndRequest(httpContext, timestamp.Value);
|
||||
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.Diagnostics.UnhandledException")
|
||||
{
|
||||
httpContext = this.httpContextFetcherDiagExceptionUnhandled.Fetch(value.Value) as HttpContext;
|
||||
exception = this.exceptionFetcherDiagExceptionUnhandled.Fetch(value.Value) as Exception;
|
||||
if (httpContext != null && exception != null)
|
||||
else if (value.Key == "Microsoft.AspNetCore.Hosting.EndRequest")
|
||||
{
|
||||
this.OnDiagnosticsUnhandledException(httpContext, exception);
|
||||
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.HandledException")
|
||||
{
|
||||
httpContext = this.httpContextFetcherDiagExceptionHandled.Fetch(value.Value) as HttpContext;
|
||||
exception = this.exceptionFetcherDiagExceptionHandled.Fetch(value.Value) as Exception;
|
||||
if (httpContext != null && exception != null)
|
||||
else if (value.Key == "Microsoft.AspNetCore.Diagnostics.UnhandledException")
|
||||
{
|
||||
this.OnDiagnosticsHandledException(httpContext, exception);
|
||||
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.Hosting.UnhandledException")
|
||||
{
|
||||
httpContext = this.httpContextFetcherHostingExceptionUnhandled.Fetch(value.Value) as HttpContext;
|
||||
exception = this.exceptionFetcherHostingExceptionUnhandled.Fetch(value.Value) as Exception;
|
||||
if (httpContext != null && exception != null)
|
||||
else if (value.Key == "Microsoft.AspNetCore.Diagnostics.HandledException")
|
||||
{
|
||||
this.OnHostingException(httpContext, exception);
|
||||
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);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex)
|
||||
{
|
||||
AspNetCoreEventSource.Instance.DiagnosticListenerWarning(value.Key, ex.ToInvariantString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,16 +20,6 @@
|
|||
/// </summary>
|
||||
public const string RequestContextTargetKey = "appId"; // Although the name of Source and Target key is the same - appId. Conceptually they are different and hence, we intentionally have two constants here. Makes for better reading of the code.
|
||||
|
||||
/// <summary>
|
||||
/// Standard parent Id header.
|
||||
/// </summary>
|
||||
public const string StandardParentIdHeader = "x-ms-request-id";
|
||||
|
||||
/// <summary>
|
||||
/// Standard root id header.
|
||||
/// </summary>
|
||||
public const string StandardRootIdHeader = "x-ms-request-root-id";
|
||||
|
||||
/// <summary>
|
||||
/// Request-Id header.
|
||||
/// </summary>
|
||||
|
|
|
@ -137,8 +137,8 @@ namespace Microsoft.ApplicationInsights.AspNetCore.Extensibility.Implementation.
|
|||
14,
|
||||
Keywords = Keywords.Diagnostics,
|
||||
Message = "An error has occured which may prevent application insights from functioning. Error message: '{0}' ",
|
||||
Level = EventLevel.Warning)]
|
||||
public void LogWarning(string errorMessage, string appDomainName = "Incorrect")
|
||||
Level = EventLevel.Error)]
|
||||
public void LogError(string errorMessage, string appDomainName = "Incorrect")
|
||||
{
|
||||
this.WriteEvent(14, errorMessage, this.ApplicationName);
|
||||
}
|
||||
|
@ -156,11 +156,11 @@ namespace Microsoft.ApplicationInsights.AspNetCore.Extensibility.Implementation.
|
|||
[Event(
|
||||
16,
|
||||
Keywords = Keywords.Diagnostics,
|
||||
Message = "An error has occured in DiagnosticSource listener. Listener: '{0}' Callback: '{1}'. Error message: '{2}' ",
|
||||
Message = "An error has occured in DiagnosticSource listener. Callback: '{0}'. Error message: '{1}' ",
|
||||
Level = EventLevel.Warning)]
|
||||
public void DiagnosticListenerWarning(string listener, string callback, string errorMessage, string appDomainName = "Incorrect")
|
||||
public void DiagnosticListenerWarning(string callback, string errorMessage, string appDomainName = "Incorrect")
|
||||
{
|
||||
this.WriteEvent(16, listener, callback, errorMessage, this.ApplicationName);
|
||||
this.WriteEvent(16, callback, errorMessage, this.ApplicationName);
|
||||
}
|
||||
|
||||
[Event(
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
using Microsoft.ApplicationInsights.Extensibility.EventCounterCollector;
|
||||
#endif
|
||||
using Microsoft.ApplicationInsights.Extensibility.Implementation.ApplicationId;
|
||||
using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing;
|
||||
using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector;
|
||||
using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.QuickPulse;
|
||||
using Microsoft.ApplicationInsights.WindowsServer;
|
||||
|
@ -201,6 +202,7 @@
|
|||
services.AddSingleton<ITelemetryModule, EventCounterCollectionModule>();
|
||||
services.ConfigureTelemetryModule<EventCounterCollectionModule>((eventCounterModule, options) =>
|
||||
{
|
||||
// Ref this code for actual names. https://github.com/dotnet/coreclr/blob/dbc5b56c48ce30635ee8192c9814c7de998043d5/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/RuntimeEventSource.cs
|
||||
eventCounterModule.Counters.Add(new EventCounterCollectionRequest("System.Runtime", "cpu-usage"));
|
||||
eventCounterModule.Counters.Add(new EventCounterCollectionRequest("System.Runtime", "working-set"));
|
||||
eventCounterModule.Counters.Add(new EventCounterCollectionRequest("System.Runtime", "gc-heap-size"));
|
||||
|
@ -221,10 +223,11 @@
|
|||
eventCounterModule.Counters.Add(new EventCounterCollectionRequest("System.Runtime", "threadpool-completed-items-count"));
|
||||
eventCounterModule.Counters.Add(new EventCounterCollectionRequest("System.Runtime", "active-timer-count"));
|
||||
|
||||
eventCounterModule.Counters.Add(new EventCounterCollectionRequest("Microsoft.AspNetCore", "requests-per-second"));
|
||||
eventCounterModule.Counters.Add(new EventCounterCollectionRequest("Microsoft.AspNetCore", "total-requests"));
|
||||
eventCounterModule.Counters.Add(new EventCounterCollectionRequest("Microsoft.AspNetCore", "current-requests"));
|
||||
eventCounterModule.Counters.Add(new EventCounterCollectionRequest("Microsoft.AspNetCore", "failed-requests"));
|
||||
// Ref this code for actual names. https://github.com/aspnet/AspNetCore/blob/f3f9a1cdbcd06b298035b523732b9f45b1408461/src/Hosting/Hosting/src/Internal/HostingEventSource.cs
|
||||
eventCounterModule.Counters.Add(new EventCounterCollectionRequest("Microsoft.AspNetCore.Hosting", "requests-per-second"));
|
||||
eventCounterModule.Counters.Add(new EventCounterCollectionRequest("Microsoft.AspNetCore.Hosting", "total-requests"));
|
||||
eventCounterModule.Counters.Add(new EventCounterCollectionRequest("Microsoft.AspNetCore.Hosting", "current-requests"));
|
||||
eventCounterModule.Counters.Add(new EventCounterCollectionRequest("Microsoft.AspNetCore.Hosting", "failed-requests"));
|
||||
});
|
||||
#endif
|
||||
services.AddSingleton<TelemetryConfiguration>(provider =>
|
||||
|
@ -287,7 +290,7 @@
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
AspNetCoreEventSource.Instance.LogWarning(e.Message);
|
||||
AspNetCoreEventSource.Instance.LogError(e.ToInvariantString());
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for <see cref="IWebHostBuilder"/> that allow adding Application Insights services to application.
|
||||
|
@ -15,6 +16,7 @@
|
|||
/// </summary>
|
||||
/// <param name="webHostBuilder">The <see cref="IWebHostBuilder"/> instance.</param>
|
||||
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
|
||||
[Obsolete("This method is deprecated in favor of AddApplicationInsightsTelemetry() extension method on IServiceCollection.")]
|
||||
public static IWebHostBuilder UseApplicationInsights(this IWebHostBuilder webHostBuilder)
|
||||
{
|
||||
webHostBuilder.ConfigureServices(collection =>
|
||||
|
@ -31,6 +33,7 @@
|
|||
/// <param name="webHostBuilder">The <see cref="IWebHostBuilder"/> instance.</param>
|
||||
/// <param name="instrumentationKey">Instrumentation key to use for telemetry.</param>
|
||||
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
|
||||
[Obsolete("This method is deprecated in favor of AddApplicationInsightsTelemetry(string instrumentationKey) extension method on IServiceCollection.")]
|
||||
public static IWebHostBuilder UseApplicationInsights(this IWebHostBuilder webHostBuilder, string instrumentationKey)
|
||||
{
|
||||
webHostBuilder.ConfigureServices(collection => collection.AddApplicationInsightsTelemetry(instrumentationKey));
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
namespace Microsoft.ApplicationInsights.AspNetCore.Extensions
|
||||
{
|
||||
using System;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
/// <summary>
|
||||
|
@ -10,6 +9,8 @@
|
|||
public static class HttpRequestExtensions
|
||||
{
|
||||
private const string UnknownHostName = "UNKNOWN-HOST";
|
||||
private const string MultipleHostName = "MULTIPLE-HOST";
|
||||
private const string Comma = ",";
|
||||
|
||||
/// <summary>
|
||||
/// Gets http request Uri from request object.
|
||||
|
@ -31,7 +32,7 @@
|
|||
return new Uri(string.Concat(
|
||||
request.Scheme,
|
||||
"://",
|
||||
request.Host.HasValue ? request.Host.Value : UnknownHostName,
|
||||
request.Host.HasValue ? (request.Host.Value.IndexOf(Comma) > 0 ? MultipleHostName : request.Host.Value) : UnknownHostName,
|
||||
request.Path.HasValue ? request.Path.Value : string.Empty,
|
||||
request.QueryString.HasValue ? request.QueryString.Value : string.Empty));
|
||||
}
|
||||
|
|
|
@ -3,15 +3,24 @@
|
|||
using System;
|
||||
using Microsoft.ApplicationInsights.AspNetCore.Extensibility.Implementation.Tracing;
|
||||
using Microsoft.ApplicationInsights.Extensibility;
|
||||
using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="IStartupFilter"/> implementation that initialized ApplicationInsights services on application startup
|
||||
/// </summary>
|
||||
internal class ApplicationInsightsStartupFilter : IStartupFilter
|
||||
{
|
||||
private readonly ILogger<ApplicationInsightsStartupFilter> logger;
|
||||
|
||||
public ApplicationInsightsStartupFilter(ILogger<ApplicationInsightsStartupFilter> logger)
|
||||
{
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
|
||||
{
|
||||
|
@ -26,7 +35,8 @@
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AspNetCoreEventSource.Instance.LogWarning(ex.Message);
|
||||
this.logger.LogWarning(0, ex, "Failed to resolve TelemetryConfiguration.");
|
||||
AspNetCoreEventSource.Instance.LogError(ex.ToInvariantString());
|
||||
}
|
||||
|
||||
// Invoking next builder is not wrapped in try catch to ensure any exceptions gets propogated up.
|
||||
|
@ -34,4 +44,4 @@
|
|||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AspNetCoreEventSource.Instance.TelemetryConfigurationSetupFailure(ex.Message);
|
||||
AspNetCoreEventSource.Instance.TelemetryConfigurationSetupFailure(ex.ToInvariantString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<AssemblyName>Microsoft.ApplicationInsights.AspNetCore</AssemblyName>
|
||||
<VersionPrefix>2.8.0-beta1</VersionPrefix>
|
||||
<Authors>Microsoft</Authors>
|
||||
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
|
||||
<AssemblyTitle>Application Insights for ASP.NET Core Web Applications</AssemblyTitle>
|
||||
<Description>Application Insights for ASP.NET Core web applications. See https://azure.microsoft.com/documentation/articles/app-insights-asp-net-five/ for more information. Privacy statement: https://go.microsoft.com/fwlink/?LinkId=512156</Description>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/Microsoft/ApplicationInsights-aspnetcore.git</RepositoryUrl>
|
||||
<VersionPrefix>2.8.0-beta2</VersionPrefix>
|
||||
|
||||
<TargetFrameworks>net451;net46;netstandard1.6;netstandard2.0</TargetFrameworks>
|
||||
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netstandard1.6;netstandard2.0</TargetFrameworks>
|
||||
|
||||
|
@ -17,17 +12,33 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!--Package Settings-->
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<!--Nupkg properties-->
|
||||
<PackageId>Microsoft.ApplicationInsights.AspNetCore</PackageId>
|
||||
<AssemblyTitle>Application Insights for ASP.NET Core Web Applications</AssemblyTitle>
|
||||
<Title>Application Insights for ASP.NET Core Web Applications</Title>
|
||||
<Description>Application Insights for ASP.NET Core web applications. See https://azure.microsoft.com/documentation/articles/app-insights-asp-net-five/ for more information. Privacy statement: https://go.microsoft.com/fwlink/?LinkId=512156</Description>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!--Normalized Nupkg properties. I will remove this PropertyGroup in a follow up PR.-->
|
||||
<Authors>Microsoft</Authors>
|
||||
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/Microsoft/ApplicationInsights-aspnetcore.git</RepositoryUrl>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<IncludeSymbols>True</IncludeSymbols>
|
||||
<PackageId>Microsoft.ApplicationInsights.AspNetCore</PackageId>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<PackageTags>Azure;Monitoring;Analytics;ApplicationInsights;Telemetry;AppInsights;aspnetcore;</PackageTags>
|
||||
<PackageIconUrl>https://appanacdn.blob.core.windows.net/cdn/icons/aic.png</PackageIconUrl>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://go.microsoft.com/fwlink/?LinkId=392727</PackageProjectUrl>
|
||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!--Package Settings-->
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<!--Symbols Settings-->
|
||||
|
@ -36,23 +47,31 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(Configuration)' == 'Release' And $(OS) == 'Windows_NT'">
|
||||
<!--Analyzers-->
|
||||
<PackageReference Include="Desktop.Analyzers" Version="1.1.0">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="2.9.2">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Roslyn.Diagnostics.Analyzers" Version="2.9.2">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.2">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="2.9.2">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Roslyn.Diagnostics.Analyzers" Version="2.9.2">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<!--Build Infrastructure-->
|
||||
<PackageReference Include="MicroBuild.Core" Version="0.3.0">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.11.0-beta1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.11.0-beta1" />
|
||||
|
@ -62,9 +81,6 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="1.0.2" />
|
||||
<PackageReference Include="System.Text.Encodings.Web" Version="4.3.1" />
|
||||
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="4.5.0" />
|
||||
<PackageReference Include="MicroBuild.Core" Version="0.3.0">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' != 'netstandard2.0' ">
|
||||
|
|
|
@ -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 informaiton 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 information 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-premisis, instance name for Azure.")]
|
||||
[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("MaxStringLength", "256")]
|
||||
[global::Bond.Id(715)]
|
||||
public string CloudRoleInstance { get; set; }
|
||||
|
|
|
@ -28,7 +28,7 @@ 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 intances 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 instances of this type. The message does not have measurements.")]
|
||||
[global::Bond.Schema]
|
||||
[System.CodeDom.Compiler.GeneratedCode("gbc", "0.10.1.0")]
|
||||
public partial class MessageData
|
||||
|
|
|
@ -59,7 +59,7 @@ namespace AI
|
|||
[global::Bond.Id(61), global::Bond.Required]
|
||||
public string duration { get; set; }
|
||||
|
||||
[global::Bond.Attribute("Description", "Indication of successfull or unsuccessfull call.")]
|
||||
[global::Bond.Attribute("Description", "Indication of successful or unsuccessful call.")]
|
||||
[global::Bond.Id(120)]
|
||||
public bool success { get; set; }
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace AI
|
|||
[global::Bond.Id(60), global::Bond.Required]
|
||||
public string responseCode { get; set; }
|
||||
|
||||
[global::Bond.Attribute("Description", "Indication of successfull or unsuccessfull call.")]
|
||||
[global::Bond.Attribute("Description", "Indication of successful or unsuccessful call.")]
|
||||
[global::Bond.Id(70), global::Bond.Required]
|
||||
public bool success { get; set; }
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
{
|
||||
using Microsoft.ApplicationInsights.AspNetCore.Extensions;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Internal;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Xunit;
|
||||
|
@ -12,6 +11,7 @@
|
|||
const string ExpectedSchema = "http";
|
||||
const string ExpectedHostName = "randomhost";
|
||||
const string ExpectedDefaultHostName = "unknown-host";
|
||||
const string ExpectedMulltipleHostName = "multiple-host";
|
||||
const string ExpectedPath = "/path/path/";
|
||||
const string ExpectedQueryString = "?queryType=1";
|
||||
|
||||
|
@ -51,6 +51,20 @@
|
|||
uri);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestGetUriUsesMultipleHostNameOnRequestWithManyHostsSpecified()
|
||||
{
|
||||
var request = new DefaultHttpContext().Request;
|
||||
request.Scheme = ExpectedSchema;
|
||||
request.Host = new HostString("host1,host2");
|
||||
|
||||
var uri = HttpRequestExtensions.GetUri(request);
|
||||
|
||||
Assert.Equal(
|
||||
new Uri(string.Format(CultureInfo.InvariantCulture, "{0}://{1}", ExpectedSchema, ExpectedMulltipleHostName)),
|
||||
uri);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestGetUriReturnsCorrectUriIfRequestObjectSchemeAndHostAreSpecified()
|
||||
{
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
{
|
||||
private const string HttpRequestScheme = "http";
|
||||
private const string ExpectedAppId = "cid-v1:some-app-id";
|
||||
private const string ActivityCreatedByHostingDiagnosticListener = "ActivityCreatedByHostingDiagnosticListener";
|
||||
|
||||
private static readonly HostString HttpRequestHost = new HostString("testHost");
|
||||
private static readonly PathString HttpRequestPath = new PathString("/path/path");
|
||||
|
@ -102,10 +103,12 @@
|
|||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void TestSdkVersionIsPopulatedByMiddleware(bool isAspNetCore2)
|
||||
public void TestConditionalAppIdFlagIsRespected(bool isAspNetCore2)
|
||||
{
|
||||
HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost);
|
||||
TelemetryConfiguration config = TelemetryConfiguration.CreateDefault();
|
||||
// This flag tells sdk to not add app id in response header, unless its received in incoming headers.
|
||||
// For tests, no incoming headers is add, so the response should not have app id as well.
|
||||
config.ExperimentalFeatures.Add("conditionalAppId");
|
||||
|
||||
using (var hostingListener = CreateHostingListener(isAspNetCore2, config))
|
||||
|
@ -114,6 +117,7 @@
|
|||
|
||||
Assert.NotNull(context.Features.Get<RequestTelemetry>());
|
||||
|
||||
// VALIDATE
|
||||
Assert.Null(HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers,
|
||||
RequestResponseHeaders.RequestContextTargetKey));
|
||||
|
||||
|
@ -133,6 +137,35 @@
|
|||
Assert.Contains(SdkVersionTestUtils.VersionPrefix, requestTelemetry.Context.GetInternalContext().SdkVersion);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void TestSdkVersionIsPopulatedByMiddleware(bool isAspNetCore2)
|
||||
{
|
||||
HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost);
|
||||
TelemetryConfiguration config = TelemetryConfiguration.CreateDefault();
|
||||
|
||||
using (var hostingListener = CreateHostingListener(isAspNetCore2, config))
|
||||
{
|
||||
HandleRequestBegin(hostingListener, context, 0, isAspNetCore2);
|
||||
|
||||
Assert.NotNull(context.Features.Get<RequestTelemetry>());
|
||||
HandleRequestEnd(hostingListener, context, 0, isAspNetCore2);
|
||||
}
|
||||
|
||||
Assert.Single(sentTelemetry);
|
||||
Assert.IsType<RequestTelemetry>(this.sentTelemetry.First());
|
||||
|
||||
RequestTelemetry requestTelemetry = this.sentTelemetry.First() as RequestTelemetry;
|
||||
Assert.True(requestTelemetry.Duration.TotalMilliseconds >= 0);
|
||||
Assert.True(requestTelemetry.Success);
|
||||
Assert.Equal(CommonMocks.InstrumentationKey, requestTelemetry.Context.InstrumentationKey);
|
||||
Assert.True(string.IsNullOrEmpty(requestTelemetry.Source));
|
||||
Assert.Equal(CreateUri(HttpRequestScheme, HttpRequestHost), requestTelemetry.Url);
|
||||
Assert.NotEmpty(requestTelemetry.Context.GetInternalContext().SdkVersion);
|
||||
Assert.Contains(SdkVersionTestUtils.VersionPrefix, requestTelemetry.Context.GetInternalContext().SdkVersion);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
|
@ -186,7 +219,7 @@
|
|||
var telemetries = sentTelemetry.ToArray();
|
||||
Assert.Equal(2, sentTelemetry.Count);
|
||||
Assert.IsType<ExceptionTelemetry>(telemetries[0]);
|
||||
|
||||
|
||||
Assert.IsType<RequestTelemetry>(telemetries[1]);
|
||||
RequestTelemetry requestTelemetry = telemetries[1] as RequestTelemetry;
|
||||
Assert.True(requestTelemetry.Duration.TotalMilliseconds >= 0);
|
||||
|
@ -210,6 +243,7 @@
|
|||
HandleRequestBegin(hostingListener, context, 0, isAspNetCore2);
|
||||
|
||||
Assert.NotNull(Activity.Current);
|
||||
Assert.Equal(ActivityCreatedByHostingDiagnosticListener, Activity.Current.OperationName);
|
||||
|
||||
var requestTelemetry = context.Features.Get<RequestTelemetry>();
|
||||
Assert.NotNull(requestTelemetry);
|
||||
|
@ -224,41 +258,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void OnBeginRequestCreateNewActivityAndInitializeRequestTelemetryFromStandardHeader(bool isAspNetCore2)
|
||||
{
|
||||
HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST");
|
||||
var standardRequestId = Guid.NewGuid().ToString();
|
||||
var standardRequestRootId = Guid.NewGuid().ToString();
|
||||
context.Request.Headers[RequestResponseHeaders.StandardParentIdHeader] = standardRequestId;
|
||||
context.Request.Headers[RequestResponseHeaders.StandardRootIdHeader] = standardRequestRootId;
|
||||
|
||||
using (var hostingListener = CreateHostingListener(isAspNetCore2))
|
||||
{
|
||||
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, standardRequestRootId);
|
||||
Assert.Equal(requestTelemetry.Context.Operation.ParentId, standardRequestId);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OnBeginRequestCreateNewActivityAndInitializeRequestTelemetryFromRequestIdHeader()
|
||||
{
|
||||
// This tests 1.XX scenario where SDK is responsible for reading Correlation-Context and populate Activity.Baggage
|
||||
HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST");
|
||||
var requestId = Guid.NewGuid().ToString();
|
||||
var standardRequestId = Guid.NewGuid().ToString();
|
||||
var standardRequestRootId = Guid.NewGuid().ToString();
|
||||
context.Request.Headers[RequestResponseHeaders.RequestIdHeader] = requestId;
|
||||
context.Request.Headers[RequestResponseHeaders.StandardParentIdHeader] = standardRequestId;
|
||||
context.Request.Headers[RequestResponseHeaders.StandardRootIdHeader] = standardRequestRootId;
|
||||
context.Request.Headers[RequestResponseHeaders.CorrelationContextHeader] = "prop1=value1, prop2=value2";
|
||||
|
||||
using (var hostingListener = CreateHostingListener(false))
|
||||
|
@ -273,11 +279,9 @@
|
|||
Assert.NotNull(requestTelemetry);
|
||||
Assert.Equal(requestTelemetry.Id, Activity.Current.Id);
|
||||
Assert.Equal(requestTelemetry.Context.Operation.Id, Activity.Current.RootId);
|
||||
Assert.NotEqual(requestTelemetry.Context.Operation.Id, standardRequestRootId);
|
||||
Assert.Equal(requestTelemetry.Context.Operation.ParentId, requestId);
|
||||
Assert.NotEqual(requestTelemetry.Context.Operation.ParentId, standardRequestId);
|
||||
Assert.Equal("value1", requestTelemetry.Context.Properties["prop1"]);
|
||||
Assert.Equal("value2", requestTelemetry.Context.Properties["prop2"]);
|
||||
Assert.Equal("value1", requestTelemetry.Properties["prop1"]);
|
||||
Assert.Equal("value2", requestTelemetry.Properties["prop2"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -313,39 +317,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void OnHttpRequestInStartCreateNewActivityIfParentIdIsNullAndHasStandardHeader(bool isAspNetCore2)
|
||||
{
|
||||
var context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST");
|
||||
var standardRequestId = Guid.NewGuid().ToString();
|
||||
var standardRequestRootId = Guid.NewGuid().ToString();
|
||||
context.Request.Headers[RequestResponseHeaders.StandardParentIdHeader] = standardRequestId;
|
||||
context.Request.Headers[RequestResponseHeaders.StandardRootIdHeader] = standardRequestRootId;
|
||||
|
||||
var activity = new Activity("operation");
|
||||
activity.Start();
|
||||
|
||||
using (var hostingListener = CreateHostingListener(isAspNetCore2))
|
||||
{
|
||||
HandleRequestBegin(hostingListener, context, 0, isAspNetCore2);
|
||||
|
||||
var activityInitializedByStandardHeader = Activity.Current;
|
||||
Assert.NotEqual(activityInitializedByStandardHeader, activity);
|
||||
Assert.Equal(activityInitializedByStandardHeader.ParentId, standardRequestRootId);
|
||||
|
||||
HandleRequestEnd(hostingListener, context, 0, isAspNetCore2);
|
||||
|
||||
Assert.Single(sentTelemetry);
|
||||
var requestTelemetry = this.sentTelemetry.First() as RequestTelemetry;
|
||||
|
||||
Assert.Equal(requestTelemetry.Id, activityInitializedByStandardHeader.Id);
|
||||
Assert.Equal(requestTelemetry.Context.Operation.Id, standardRequestRootId);
|
||||
Assert.Equal(requestTelemetry.Context.Operation.ParentId, standardRequestId);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
|
@ -384,15 +355,12 @@
|
|||
{
|
||||
HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "GET");
|
||||
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.Null(HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers,
|
||||
RequestResponseHeaders.RequestContextTargetKey));
|
||||
|
||||
HandleRequestEnd(hostingListener, context, 0, isAspNetCore2);
|
||||
}
|
||||
|
@ -979,6 +947,8 @@
|
|||
{
|
||||
var activity = new Activity("operation");
|
||||
|
||||
// Simulating the behaviour of Hosting layer in 2.xx, which parses Request-Id Header and
|
||||
// set Activity parent.
|
||||
if (context.Request.Headers.TryGetValue("Request-Id", out var requestId))
|
||||
{
|
||||
activity.SetParentId(requestId);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>2.0.0</VersionPrefix>
|
||||
<TargetFrameworks>net46;netcoreapp1.0;netcoreapp2.0</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp2.0;net46;netcoreapp1.0</TargetFrameworks>
|
||||
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp1.0</TargetFrameworks>
|
||||
<DelaySign Condition=" '$(OS)' == 'Windows_NT' ">true</DelaySign>
|
||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||
|
|
Загрузка…
Ссылка в новой задаче