1
0
Форкнуть 0

Merge pull request #961 from microsoft/develop

Dev to Master for 2.8.0-beta2
This commit is contained in:
Cijo Thomas 2019-08-27 11:41:08 -07:00 коммит произвёл GitHub
Родитель 15476deae3 c2929a9f77
Коммит f05e6140a0
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
22 изменённых файлов: 235 добавлений и 234 удалений

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

@ -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>