Skip to content
This repository was archived by the owner on Jul 5, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*.user
*.sln.docstates
.vs
.vscode
*.sln.dotsettings

# Build results
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
# Changelog


## Version 2.7.0-beta1
- [Add operation details for HTTP and SQL operation to the dependency telemetry.](https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/900)
- [Fix: Do not call base HandleErrorAttribute.OnException in MVC unhandled exception filter](https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/921)
- [Send UserActionable event about correlation issue with HTTP request with body when .NET 4.7.1 is not installed](https://github.com/Microsoft/ApplicationInsights-dotnet-server/pull/903)
- [Added support to collect Perf Counters for .NET Core Apps if running inside Azure WebApps](https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/889)
- [Opt-in legacy correlation headers (x-ms-request-id and x-ms-request-root-id) extraction and injection](https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/887)
- [Fix: Correlation is not working for POST requests](https://github.com/Microsoft/ApplicationInsights-dotnet-server/pull/898) when .NET 4.7.1 runtime is installed.
- [Fix: Tracking mixed HTTP responses with and without content](https://github.com/Microsoft/ApplicationInsights-dotnet-server/pull/919)


## Version 2.6.0-beta4
- [Remove CorrelationIdLookupHelper. Use TelemetryConfiguration.ApplicationIdProvider instead.](https://github.com/Microsoft/ApplicationInsights-dotnet-server/pull/880) With this change you can update URL to query application ID from which enables environments with reverse proxy configuration to access Application Insights ednpoints.
- [Update Microsoft.AspNet.TelemetryCorrelation package to 1.0.1: Fix endless loop when activity stack is broken](https://github.com/aspnet/Microsoft.AspNet.TelemetryCorrelation/issues/22)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,18 @@ public class DependencyTrackingTelemetryModuleHttpTest
private StubTelemetryChannel channel;
private TelemetryConfiguration config;
private List<DependencyTelemetry> sentTelemetry;
private object request;
private object response;
private object responseHeaders;

[TestInitialize]
public void Initialize()
{
ServicePointManager.DefaultConnectionLimit = 1000;
this.sentTelemetry = new List<DependencyTelemetry>();
this.request = null;
this.response = null;
this.responseHeaders = null;

this.channel = new StubTelemetryChannel
{
Expand All @@ -51,6 +57,9 @@ public void Initialize()
if (depTelemetry != null)
{
this.sentTelemetry.Add(depTelemetry);
depTelemetry.TryGetOperationDetail(RemoteDependencyConstants.HttpRequestOperationDetailName, out this.request);
depTelemetry.TryGetOperationDetail(RemoteDependencyConstants.HttpResponseOperationDetailName, out this.response);
depTelemetry.TryGetOperationDetail(RemoteDependencyConstants.HttpResponseOperationDetailName, out this.responseHeaders);
}
},
EndpointAddress = FakeProfileApiEndpoint
Expand Down Expand Up @@ -382,7 +391,7 @@ private void TestCollectionSuccessfulResponse(bool enableDiagnosticSource, strin
}
}

this.ValidateTelemetry(enableDiagnosticSource, this.sentTelemetry.Single(), new Uri(url), request, statusCode >= 200 && statusCode < 300, statusCode.ToString(CultureInfo.InvariantCulture), injectLegacyHeaders);
this.ValidateTelemetry(enableDiagnosticSource, this.sentTelemetry.Single(), new Uri(url), request, statusCode >= 200 && statusCode < 300, statusCode.ToString(CultureInfo.InvariantCulture), expectLegacyHeaders: injectLegacyHeaders);
}
}

Expand Down Expand Up @@ -412,7 +421,7 @@ private async Task TestCollectionHttpClientSuccessfulResponse(string url, int st
}
}

this.ValidateTelemetry(true, this.sentTelemetry.Single(), new Uri(url), null, statusCode >= 200 && statusCode < 300, statusCode.ToString(CultureInfo.InvariantCulture));
this.ValidateTelemetry(true, this.sentTelemetry.Single(), new Uri(url), null, statusCode >= 200 && statusCode < 300, statusCode.ToString(CultureInfo.InvariantCulture), responseExpected: contentLength != 0);
}
}

Expand Down Expand Up @@ -468,7 +477,7 @@ private async Task TestZeroContentResponseAfterNonZeroResponse(string url, int s
}

Assert.AreEqual(2, this.sentTelemetry.Count);
this.ValidateTelemetry(true, this.sentTelemetry.Last(), new Uri(url), null, statusCode >= 200 && statusCode < 300, statusCode.ToString(CultureInfo.InvariantCulture));
this.ValidateTelemetry(true, this.sentTelemetry.Last(), new Uri(url), null, statusCode >= 200 && statusCode < 300, statusCode.ToString(CultureInfo.InvariantCulture), responseExpected: false);
}
}

Expand Down Expand Up @@ -498,7 +507,7 @@ private async Task TestCollectionCanceledRequest(bool enableDiagnosticSource, st
await httpClient.GetAsync(url, cts.Token).ContinueWith(t => { });
}

this.ValidateTelemetry(enableDiagnosticSource, this.sentTelemetry.Single(), new Uri(url), null, false, string.Empty);
this.ValidateTelemetry(enableDiagnosticSource, this.sentTelemetry.Single(), new Uri(url), null, false, string.Empty, responseExpected: false);
}
}

Expand All @@ -515,7 +524,7 @@ private async Task TestCollectionDnsIssue(bool enableDiagnosticSource)
// here the start of dependency is tracked with HttpDesktopDiagnosticSourceListener,
// so the expected SDK version should have DiagnosticSource 'rdddsd' prefix.
// however the end is tracked by FrameworkHttpEventListener
this.ValidateTelemetry(true, this.sentTelemetry.Single(), url, null, false, string.Empty);
this.ValidateTelemetry(true, this.sentTelemetry.Single(), url, null, false, string.Empty, responseExpected: false);
}
else
{
Expand All @@ -526,7 +535,7 @@ private async Task TestCollectionDnsIssue(bool enableDiagnosticSource)
}
}

private void ValidateTelemetry(bool diagnosticSource, DependencyTelemetry item, Uri url, WebRequest request, bool success, string resultCode, bool expectLegacyHeaders = false)
private void ValidateTelemetry(bool diagnosticSource, DependencyTelemetry item, Uri url, WebRequest request, bool success, string resultCode, bool responseExpected = true, bool headersExpected = false, bool expectLegacyHeaders = false)
{
Assert.AreEqual(url, item.Data);

Expand Down Expand Up @@ -555,6 +564,30 @@ private void ValidateTelemetry(bool diagnosticSource, DependencyTelemetry item,
Assert.AreEqual(Activity.Current?.Id, item.Context.Operation.ParentId);
Assert.IsTrue(item.Id.StartsWith('|' + item.Context.Operation.Id + '.'));

// Validate the http request was captured
if (diagnosticSource)
{
Assert.IsNotNull(this.request, "Http request was not found within the operation details.");
var webRequest = this.request as WebRequest;
Assert.IsNotNull(webRequest, "Http request was not the expected type.");
}

// If expected -- validate the response was captured
if (diagnosticSource && responseExpected)
{
Assert.IsNotNull(this.response, "Http response was not found within the operation details.");
var webResponse = this.response as WebResponse;
Assert.IsNotNull(webResponse, "Http response was not the expected type.");
}

// If expected -- validate the headers were captured
if (diagnosticSource && headersExpected)
{
Assert.IsNotNull(this.responseHeaders, "Http response headers were not found within the operation details.");
var headers = this.responseHeaders as WebHeaderCollection;
Assert.IsNotNull(headers, "Http response headers were not the expected type.");
}

if (diagnosticSource)
{
this.ValidateTelemetryForDiagnosticSource(item, url, request, expectLegacyHeaders);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ public class DependencyTrackingTelemetryModuleTestNetCore
private StubTelemetryChannel channel;
private TelemetryConfiguration config;
private List<DependencyTelemetry> sentTelemetry;
private object request;
private object response;
private object responseHeaders;

/// <summary>
/// Initialize.
Expand All @@ -41,6 +44,9 @@ public class DependencyTrackingTelemetryModuleTestNetCore
public void Initialize()
{
this.sentTelemetry = new List<DependencyTelemetry>();
this.request = null;
this.response = null;
this.responseHeaders = null;

this.channel = new StubTelemetryChannel
{
Expand All @@ -51,6 +57,9 @@ public void Initialize()
if (depTelemetry != null)
{
this.sentTelemetry.Add(depTelemetry);
depTelemetry.TryGetOperationDetail(RemoteDependencyConstants.HttpRequestOperationDetailName, out this.request);
depTelemetry.TryGetOperationDetail(RemoteDependencyConstants.HttpResponseOperationDetailName, out this.response);
depTelemetry.TryGetOperationDetail(RemoteDependencyConstants.HttpResponseHeadersOperationDetailName, out this.responseHeaders);
}
},
EndpointAddress = FakeProfileApiEndpoint
Expand Down Expand Up @@ -220,6 +229,19 @@ private void ValidateTelemetryForDiagnosticSource(DependencyTelemetry item, Uri
Assert.IsFalse(request.Headers.Contains(RequestResponseHeaders.StandardParentIdHeader));
}
}

// Validate the http request was captured
Assert.IsNotNull(this.request, "Http request was not found within the operation details.");
var webRequest = this.request as HttpRequestMessage;
Assert.IsNotNull(webRequest, "Http request was not the expected type.");

// Validate the http response was captured
Assert.IsNotNull(this.response, "Http response was not found within the operation details.");
var webResponse = this.response as HttpResponseMessage;
Assert.IsNotNull(webResponse, "Http response was not the expected type.");

// Validate the http response headers were not captured
Assert.IsNull(this.responseHeaders, "Http response headers were not found within the operation details.");
}

private sealed class LocalServer : IDisposable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ public partial class DependencyCollectorDiagnosticListenerTests
private const string HttpOkResultCode = "200";
private const string NotFoundResultCode = "404";

private readonly List<ITelemetry> sentTelemetry = new List<ITelemetry>();
private List<ITelemetry> sentTelemetry;
private object request;
private object response;
private object responseHeaders;

private TelemetryConfiguration configuration;
private string testInstrumentationKey1 = nameof(testInstrumentationKey1);
Expand All @@ -44,10 +47,27 @@ public partial class DependencyCollectorDiagnosticListenerTests
[TestInitialize]
public void Initialize()
{
this.sentTelemetry = new List<ITelemetry>();
this.request = null;
this.response = null;
this.responseHeaders = null;

this.telemetryChannel = new StubTelemetryChannel()
{
EndpointAddress = "https://endpointaddress",
OnSend = this.sentTelemetry.Add
OnSend = telemetry =>
{
this.sentTelemetry.Add(telemetry);

// The correlation id lookup service also makes http call, just make sure we skip that
DependencyTelemetry depTelemetry = telemetry as DependencyTelemetry;
if (depTelemetry != null)
{
depTelemetry.TryGetOperationDetail(RemoteDependencyConstants.HttpRequestOperationDetailName, out this.request);
depTelemetry.TryGetOperationDetail(RemoteDependencyConstants.HttpResponseOperationDetailName, out this.response);
depTelemetry.TryGetOperationDetail(RemoteDependencyConstants.HttpResponseHeadersOperationDetailName, out this.responseHeaders);
}
},
};

this.testInstrumentationKey1 = Guid.NewGuid().ToString();
Expand Down Expand Up @@ -314,6 +334,9 @@ public void OnResponseWithSuccessfulResponseEventWithMatchingRequestAndNoTargetI
string expectedVersion =
SdkVersionHelper.GetExpectedSdkVersion(typeof(DependencyTrackingTelemetryModule), prefix: "rdddsc:");
Assert.AreEqual(expectedVersion, telemetry.Context.GetInternalContext().SdkVersion);

// Check the operation details
this.ValidateOperationDetails(telemetry);
}

/// <summary>
Expand Down Expand Up @@ -349,6 +372,9 @@ public void OnResponseWithNotFoundResponseEventWithMatchingRequestAndNoTargetIns
Assert.AreEqual(RequestUrl, telemetry.Target);
Assert.AreEqual(NotFoundResultCode, telemetry.ResultCode);
Assert.AreEqual(false, telemetry.Success);

// Check the operation details
this.ValidateOperationDetails(telemetry);
}

/// <summary>
Expand Down Expand Up @@ -385,6 +411,9 @@ public void OnResponseWithSuccessfulResponseEventWithMatchingRequestAndSameTarge
Assert.AreEqual(RequestUrl, telemetry.Target);
Assert.AreEqual(HttpOkResultCode, telemetry.ResultCode);
Assert.AreEqual(true, telemetry.Success, "response was not successful");

// Check the operation details
this.ValidateOperationDetails(telemetry);
}

/// <summary>
Expand Down Expand Up @@ -420,6 +449,9 @@ public void OnResponseWithFailedResponseEventWithMatchingRequestAndSameTargetIns
Assert.AreEqual(RequestUrl, telemetry.Target);
Assert.AreEqual(NotFoundResultCode, telemetry.ResultCode);
Assert.AreEqual(false, telemetry.Success);

// Check the operation details
this.ValidateOperationDetails(telemetry);
}

/// <summary>
Expand Down Expand Up @@ -456,6 +488,9 @@ public void OnResponseWithSuccessfulResponseEventWithMatchingRequestAndDifferent
Assert.AreEqual(GetApplicationInsightsTarget(targetApplicationId), telemetry.Target);
Assert.AreEqual(HttpOkResultCode, telemetry.ResultCode);
Assert.AreEqual(true, telemetry.Success);

// Check the operation details
this.ValidateOperationDetails(telemetry);
}

/// <summary>
Expand Down Expand Up @@ -492,6 +527,9 @@ public void OnResponseWithFailedResponseEventWithMatchingRequestAndDifferentTarg
Assert.AreEqual(GetApplicationInsightsTarget(targetApplicationId), telemetry.Target);
Assert.AreEqual(NotFoundResultCode, telemetry.ResultCode);
Assert.AreEqual(false, telemetry.Success);

// Check the operation details
this.ValidateOperationDetails(telemetry);
}

/// <summary>
Expand Down Expand Up @@ -534,6 +572,9 @@ public void OnResponseWithParentActivity()
Assert.AreEqual(parentActivity.RootId, telemetry.Context.Operation.Id);
Assert.AreEqual(parentActivity.Id, telemetry.Context.Operation.ParentId);

// Check the operation details
this.ValidateOperationDetails(telemetry);

parentActivity.Stop();
}

Expand All @@ -551,5 +592,21 @@ private static string GetRequestContextKeyValue(HttpRequestMessage request, stri
{
return HttpHeadersUtilities.GetRequestContextKeyValue(request.Headers, keyName);
}

private void ValidateOperationDetails(DependencyTelemetry telemetry, bool responseExpected = true)
{
Assert.IsNotNull(this.request, "Request was not present and expected.");
Assert.IsNotNull(this.request as HttpRequestMessage, "Request was not the expected type.");
Assert.IsNull(this.responseHeaders, "Response headers were present and not expected.");
if (responseExpected)
{
Assert.IsNotNull(this.response, "Response was not present and expected.");
Assert.IsNotNull(this.response as HttpResponseMessage, "Response was not the expected type.");
}
else
{
Assert.IsNull(this.response, "Response was present and not expected.");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ public void OnActivityStopTracksTelemetry()
string expectedVersion =
SdkVersionHelper.GetExpectedSdkVersion(typeof(DependencyTrackingTelemetryModule), prefix: "rdddsc:");
Assert.AreEqual(expectedVersion, telemetry.Context.GetInternalContext().SdkVersion);

// Check the operation details
this.ValidateOperationDetails(telemetry);
}

/// <summary>
Expand All @@ -126,6 +129,9 @@ public void OnActivityStopTracksTelemetryForCanceledRequest()

Assert.AreEqual("Canceled", telemetry.ResultCode);
Assert.AreEqual(false, telemetry.Success);

// Check the operation details
this.ValidateOperationDetails(telemetry, responseExpected: false);
}

/// <summary>
Expand All @@ -146,6 +152,9 @@ public void OnActivityStopTracksTelemetryForFaultedRequest()

Assert.AreEqual("Faulted", telemetry.ResultCode);
Assert.AreEqual(false, telemetry.Success);

// Check the operation details
this.ValidateOperationDetails(telemetry, responseExpected: false);
}

/// <summary>
Expand All @@ -172,6 +181,9 @@ public void OnExceptionTracksException()
Assert.AreEqual(exceptionTelemetry.Context.Operation.Id, dependencyTelemetry.Context.Operation.Id);
Assert.AreEqual(exceptionTelemetry.Context.Operation.ParentId, dependencyTelemetry.Id);
Assert.AreEqual("The server name or address could not be resolved", dependencyTelemetry.Context.Properties["Error"]);

// Check the operation details
this.ValidateOperationDetails(dependencyTelemetry, responseExpected: false);
}

/// <summary>
Expand Down
Loading