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

Request tracking improvements #716

Merged
merged 6 commits into from
Jul 11, 2018
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## Version 2.4.0-beta3
- [Allow configuring exception tracking in RequestTrackingTelemetryModule and merge OperationCorrelationTelemetryInitializer with RequestTrackingTelemetryModule](https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/709)
- [Allow disabling response headers injection](https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/613)

## Version 2.4.0-beta2
- Updated Web/Base SDK version dependency to 2.7.0-beta2

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,23 @@ internal class HostingDiagnosticListener : IApplicationInsightDiagnosticListener
private readonly TelemetryClient client;
private readonly IApplicationIdProvider applicationIdProvider;
private readonly string sdkVersion = SdkVersionUtils.GetVersion();
private readonly bool injectResponseHeaders;
private readonly bool trackExceptions;
private const string ActivityCreatedByHostingDiagnosticListener = "ActivityCreatedByHostingDiagnosticListener";

/// <summary>
/// Initializes a new instance of the <see cref="T:HostingDiagnosticListener"/> class.
/// </summary>
/// <param name="client"><see cref="TelemetryClient"/> to post traces to.</param>
/// <param name="applicationIdProvider">Nullable Provider for resolving application Id to be used by Correlation.</param>
public HostingDiagnosticListener(TelemetryClient client, IApplicationIdProvider applicationIdProvider = null)
/// <param name="applicationIdProvider">Provider for resolving application Id to be used in multiple instruemntation keys scenarios.</param>
/// <param name="injectResponseHeaders">Flag that indicates that response headers should be injected.</param>
/// <param name="trackExceptions">Flag that indicates that exceptions should be tracked.</param>
public HostingDiagnosticListener(TelemetryClient client, IApplicationIdProvider applicationIdProvider, bool injectResponseHeaders, bool trackExceptions)
{
this.client = client ?? throw new ArgumentNullException(nameof(client));
this.applicationIdProvider = applicationIdProvider;
this.injectResponseHeaders = injectResponseHeaders;
this.trackExceptions = trackExceptions;
}

/// <inheritdoc/>
Expand Down Expand Up @@ -87,7 +93,7 @@ public void OnHttpRequestInStart(HttpContext httpContext)
httpContext.Features.Set(activity);
}

var requestTelemetry = InitializeRequestTelemetryFromActivity(httpContext, Activity.Current, isActivityCreatedFromRequestIdHeader, Stopwatch.GetTimestamp());
var requestTelemetry = InitializeRequestTelemetry(httpContext, currentActivity, isActivityCreatedFromRequestIdHeader, Stopwatch.GetTimestamp());
SetAppIdInResponseHeader(httpContext, requestTelemetry);
}
}
Expand Down Expand Up @@ -145,7 +151,7 @@ public void OnBeginRequest(HttpContext httpContext, long timestamp)
activity.Start();
httpContext.Features.Set(activity);

var requestTelemetry = InitializeRequestTelemetryFromActivity(httpContext, activity, isActivityCreatedFromRequestIdHeader, timestamp);
var requestTelemetry = InitializeRequestTelemetry(httpContext, activity, isActivityCreatedFromRequestIdHeader, timestamp);
SetAppIdInResponseHeader(httpContext, requestTelemetry);
}
}
Expand Down Expand Up @@ -196,7 +202,7 @@ public void OnDiagnosticsUnhandledException(HttpContext httpContext, Exception e
this.OnException(httpContext, exception);
}

private RequestTelemetry InitializeRequestTelemetryFromActivity(HttpContext httpContext, Activity activity, bool isActivityCreatedFromRequestIdHeader, long timestamp)
private RequestTelemetry InitializeRequestTelemetry(HttpContext httpContext, Activity activity, bool isActivityCreatedFromRequestIdHeader, long timestamp)
{
var requestTelemetry = new RequestTelemetry();

Expand All @@ -223,6 +229,27 @@ private RequestTelemetry InitializeRequestTelemetryFromActivity(HttpContext http
requestTelemetry.Context.Operation.Id = activity.RootId;

this.client.Initialize(requestTelemetry);

// set Source
string headerCorrelationId = HttpHeadersUtilities.GetRequestContextKeyValue(httpContext.Request.Headers, RequestResponseHeaders.RequestContextSourceKey);

string applicationId = null;
// If the source header is present on the incoming request, and it is an external component (not the same ikey as the one used by the current component), populate the source field.
if (!string.IsNullOrEmpty(headerCorrelationId))
{
headerCorrelationId = StringUtilities.EnforceMaxLength(headerCorrelationId, InjectionGuardConstants.AppIdMaxLengeth);
if (string.IsNullOrEmpty(requestTelemetry.Context.InstrumentationKey))
{
requestTelemetry.Source = headerCorrelationId;
}

else if ((this.applicationIdProvider?.TryGetApplicationId(requestTelemetry.Context.InstrumentationKey, out applicationId) ?? false)
&& applicationId != headerCorrelationId)
{
requestTelemetry.Source = headerCorrelationId;
}
}

requestTelemetry.Start(timestamp);
httpContext.Features.Set(requestTelemetry);

Expand All @@ -231,15 +258,22 @@ private RequestTelemetry InitializeRequestTelemetryFromActivity(HttpContext http

private void SetAppIdInResponseHeader(HttpContext httpContext, RequestTelemetry requestTelemetry)
{
IHeaderDictionary responseHeaders = httpContext.Response?.Headers;
if (responseHeaders != null &&
!string.IsNullOrEmpty(requestTelemetry.Context.InstrumentationKey) &&
(!responseHeaders.ContainsKey(RequestResponseHeaders.RequestContextHeader) || HttpHeadersUtilities.ContainsRequestContextKeyValue(responseHeaders, RequestResponseHeaders.RequestContextTargetKey)))
if (this.injectResponseHeaders)
{
string applicationId = null;
if (this.applicationIdProvider?.TryGetApplicationId(requestTelemetry.Context.InstrumentationKey, out applicationId) ?? false)
IHeaderDictionary responseHeaders = httpContext.Response?.Headers;
if (responseHeaders != null &&
!string.IsNullOrEmpty(requestTelemetry.Context.InstrumentationKey) &&
(!responseHeaders.ContainsKey(RequestResponseHeaders.RequestContextHeader) ||
HttpHeadersUtilities.ContainsRequestContextKeyValue(responseHeaders,
RequestResponseHeaders.RequestContextTargetKey)))
{
HttpHeadersUtilities.SetRequestContextKeyValue(responseHeaders, RequestResponseHeaders.RequestContextTargetKey, applicationId);
string applicationId = null;
if (this.applicationIdProvider?.TryGetApplicationId(requestTelemetry.Context.InstrumentationKey,
out applicationId) ?? false)
{
HttpHeadersUtilities.SetRequestContextKeyValue(responseHeaders,
RequestResponseHeaders.RequestContextTargetKey, applicationId);
}
}
}
}
Expand Down Expand Up @@ -287,7 +321,7 @@ private void EndRequest(HttpContext httpContext, long timestamp)

private void OnException(HttpContext httpContext, Exception exception)
{
if (this.client.IsEnabled())
if (this.trackExceptions && this.client.IsEnabled())
{
var telemetry = httpContext?.Features.Get<RequestTelemetry>();
if (telemetry != null)
Expand Down
Loading