Skip to content
This repository has been archived by the owner on Jun 10, 2020. It is now read-only.

Commit

Permalink
Merge pull request #872 from Microsoft/develop
Browse files Browse the repository at this point in the history
Dev to master
  • Loading branch information
cijothomas committed May 2, 2019
2 parents c9b04f5 + 8b8c48c commit cc33596
Show file tree
Hide file tree
Showing 19 changed files with 409 additions and 380 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
# Changelog

## Version 2.7.0-beta4
- [RequestTrackingTelemetryModule is modified to stop tracking exceptions by default, as exceptions are captured by ApplicationInsightsLoggerProvider.](https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/861)
- Updated Web/Base SDK version dependency to 2.10.0-beta4
- Updated Microsoft.Extensions.Logging.ApplicationInsights to 2.10.0-beta4
- Reliability improvements with additional exception handling.

## Version 2.7.0-beta3
- [Enables Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider by default. If ApplicationInsightsLoggerProvider was enabled previously using ILoggerFactory extension method, please remove it to prevent duplicate logs.](https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/854)
- [Remove reference to Microsoft.Extensions.DiagnosticAdapter and use DiagnosticSource subscription APIs directly](https://github.com/Microsoft/ApplicationInsights-aspnetcore/pull/852)
- [Fix: NullReferenceException in ApplicationInsightsLogger.Log when exception contains a Data entry with a null value](https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/848)
- [Performance fixes for GetUri, SetKeyHeaderValue, ConcurrentDictionary use and Telemetry Initializers](https://github.com/Microsoft/ApplicationInsights-aspnetcore/pull/864)

## Version 2.7.0-beta2
- Added NetStandard2.0 target.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace Microsoft.ApplicationInsights.AspNetCore.DiagnosticListeners
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.ApplicationInsights.Common;
using Microsoft.Extensions.Primitives;

/// <summary>
/// Generic functions that can be used to get and set Http headers.
Expand All @@ -20,7 +21,7 @@ internal static class HeadersUtilities
public static string GetHeaderKeyValue(IEnumerable<string> headerValues, string keyName)
{
if (headerValues != null)
{
{
foreach (string keyNameValue in headerValues)
{
string[] keyNameValueParts = keyNameValue.Trim().Split('=');
Expand All @@ -38,22 +39,33 @@ public static string GetHeaderKeyValue(IEnumerable<string> headerValues, string
/// <summary>
/// Given the provided list of header value strings, return a comma-separated list of key
/// name/value pairs with the provided keyName and keyValue. If the initial header value
/// strings contains the key name, then the original key value should be replaced with the
/// string contains the key name, then the original key value should be replaced with the
/// provided key value. If the initial header value strings don't contain the key name,
/// then the key name/value pair should be added to the comma-separated list and returned.
/// </summary>
/// <param name="headerValues">The existing header values that the key/value pair should be added to.</param>
/// <param name="keyName">The name of the key to add.</param>
/// <param name="keyValue">The value of the key to add.</param>
/// <returns>The result of setting the provided key name/value pair into the provided headerValues.</returns>
public static IEnumerable<string> SetHeaderKeyValue(IEnumerable<string> headerValues, string keyName, string keyValue)
public static StringValues SetHeaderKeyValue(string[] currentHeaders, string key, string value)
{
string[] newHeaderKeyValue = new[] { string.Format(CultureInfo.InvariantCulture, "{0}={1}", keyName.Trim(), keyValue.Trim()) };
return headerValues == null || !headerValues.Any()
? newHeaderKeyValue
: headerValues
.Where(headerValue => !HeaderMatchesKey(headerValue, keyName))
.Concat(newHeaderKeyValue);
if (currentHeaders != null)
{
for (int index = 0; index < currentHeaders.Length; index++)
{
if (HeaderMatchesKey(currentHeaders[index], key))
{
currentHeaders[index] = string.Concat(key, "=", value);
return currentHeaders;
}
}

return StringValues.Concat(currentHeaders, string.Concat(key, "=", value));
}
else
{
return string.Concat(key, "=", value);
}
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,15 @@ public void OnHttpRequestInStart(HttpContext httpContext)
// with W3C support on .NET https://github.com/dotnet/corefx/issues/30331

newActivity = new Activity(ActivityCreatedByHostingDiagnosticListener);
newActivity.SetParentId(StringUtilities.GenerateTraceId());
if (this.enableW3CHeaders)
{
newActivity.GenerateW3CContext();
newActivity.SetParentId(newActivity.GetTraceId());
}
else
{
newActivity.SetParentId(W3CUtilities.GenerateTraceId());
}
// end of workaround
}

Expand Down Expand Up @@ -257,7 +265,9 @@ public void OnBeginRequest(HttpContext httpContext, long timestamp)
InjectionGuardConstants.RequestHeaderMaxLength);
}
}
else if(!activity.IsW3CActivity())

// no headers
else if (originalParentId == null)
{
// As a first step in supporting W3C protocol in ApplicationInsights,
// we want to generate Activity Ids in the W3C compatible format.
Expand All @@ -266,8 +276,16 @@ public void OnBeginRequest(HttpContext httpContext, long timestamp)
// So if there is no current Activity (i.e. there were no Request-Id header in the incoming request), we'll override ParentId on
// the current Activity by the properly formatted one. This workaround should go away
// with W3C support on .NET https://github.com/dotnet/corefx/issues/30331

activity.SetParentId(StringUtilities.GenerateTraceId());

if (this.enableW3CHeaders)
{
activity.GenerateW3CContext();
activity.SetParentId(activity.GetTraceId());
}
else
{
activity.SetParentId(W3CUtilities.GenerateTraceId());
}

// end of workaround
}
Expand Down Expand Up @@ -337,6 +355,10 @@ private RequestTelemetry InitializeRequestTelemetry(HttpContext httpContext, Act
requestTelemetry.Context.Operation.Id = activity.RootId;
requestTelemetry.Id = activity.Id;
}
else
{
activity.UpdateTelemetry(requestTelemetry, false);
}

foreach (var prop in activity.Baggage)
{
Expand All @@ -346,7 +368,7 @@ private RequestTelemetry InitializeRequestTelemetry(HttpContext httpContext, Act
}
}

this.client.Initialize(requestTelemetry);
this.client.InitializeInstrumentationKey(requestTelemetry);

requestTelemetry.Source = GetAppIdFromRequestHeader(httpContext.Request.Headers, requestTelemetry.Context.InstrumentationKey);

Expand Down Expand Up @@ -490,10 +512,6 @@ private void SetW3CContext(IHeaderDictionary requestHeaders, Activity activity,
InjectionGuardConstants.TraceParentHeaderMaxLength);
activity.SetTraceparent(parentTraceParent);
}
else
{
activity.GenerateW3CContext();
}

string[] traceStateValues = HttpHeadersUtilities.SafeGetCommaSeparatedHeaderValues(requestHeaders, W3C.W3CConstants.TraceStateHeader,
InjectionGuardConstants.TraceStateHeaderMaxLength, InjectionGuardConstants.TraceStateMaxPairs);
Expand Down Expand Up @@ -568,63 +586,69 @@ public void OnNext(KeyValuePair<string, object> value)
HttpContext httpContext = null;
Exception exception = null;
long? timestamp = null;

switch (value.Key)
try
{
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;
switch (value.Key)
{
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;
}
}
catch (Exception ex)
{
AspNetCoreEventSource.Instance.DiagnosticListenerWarning("HostingDiagnosticListener", value.Key, ex.Message);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,36 +65,19 @@ internal static bool ContainsRequestContextKeyValue(IHeaderDictionary headers, s
return !string.IsNullOrEmpty(GetHeaderKeyValue(headers, RequestResponseHeaders.RequestContextHeader, keyName));
}

internal static void SetRequestContextKeyValue(HttpHeaders headers, string keyName, string keyValue)
{
SetHeaderKeyValue(headers, RequestResponseHeaders.RequestContextHeader, keyName, keyValue);
}

internal static void SetRequestContextKeyValue(IHeaderDictionary headers, string keyName, string keyValue)
{
SetHeaderKeyValue(headers, RequestResponseHeaders.RequestContextHeader, keyName, keyValue);
}

internal static void SetHeaderKeyValue(HttpHeaders headers, string headerName, string keyName, string keyValue)
{
if (headers == null)
{
throw new ArgumentNullException(nameof(headers));
}

IEnumerable<string> headerValues = GetHeaderValues(headers, headerName);
headers.Remove(headerName);
headers.Add(headerName, HeadersUtilities.SetHeaderKeyValue(headerValues, keyName, keyValue));
}

internal static void SetHeaderKeyValue(IHeaderDictionary headers, string headerName, string keyName, string keyValue)
{
if (headers == null)
{
throw new ArgumentNullException(nameof(headers));
}

headers[headerName] = new StringValues(HeadersUtilities.SetHeaderKeyValue(headers[headerName].AsEnumerable(), keyName, keyValue).ToArray());
headers[headerName] = HeadersUtilities.SetHeaderKeyValue(headers[headerName], keyName, keyValue);
}

internal static string[] SafeGetCommaSeparatedHeaderValues(IHeaderDictionary headers, string headerName, int maxLength, int maxItems)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace Microsoft.ApplicationInsights.AspNetCore.DiagnosticListeners
using System.Collections.Generic;
using System.Linq;
using Microsoft.ApplicationInsights.AspNetCore.DiagnosticListeners.Implementation;
using Microsoft.ApplicationInsights.AspNetCore.Extensibility.Implementation.Tracing;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.AspNetCore.Http;

Expand Down Expand Up @@ -102,17 +103,24 @@ public void OnSubscribe()
/// <inheritdoc />
public void OnNext(KeyValuePair<string, object> value)
{
if (value.Key == "Microsoft.AspNetCore.Mvc.BeforeAction")
try
{
var context = httpContextFetcher.Fetch(value.Value) as HttpContext;
var routeData = routeDataFetcher.Fetch(value.Value);
var routeValues = routeValuesFetcher.Fetch(routeData) as IDictionary<string, object>;

if (context != null && routeValues != null)
if (value.Key == "Microsoft.AspNetCore.Mvc.BeforeAction")
{
this.OnBeforeAction(context, routeValues);
var context = httpContextFetcher.Fetch(value.Value) as HttpContext;
var routeData = routeDataFetcher.Fetch(value.Value);
var routeValues = routeValuesFetcher.Fetch(routeData) as IDictionary<string, object>;

if (context != null && routeValues != null)
{
this.OnBeforeAction(context, routeValues);
}
}
}
catch (Exception ex)
{
AspNetCoreEventSource.Instance.DiagnosticListenerWarning("MvcDiagnosticsListener", value.Key, ex.Message);
}
}

/// <inheritdoc />
Expand Down

0 comments on commit cc33596

Please sign in to comment.