Merge pull request #656 from Microsoft/removeFetchSupport
Remove fetch support, older browser versions does not accept allow any browser promise syntax
This commit is contained in:
Коммит
27f4f30ff0
|
@ -280,10 +280,6 @@ interface IConfig {
|
|||
// If true, ajax calls are not monitored.
|
||||
disableAjaxTracking: boolean;
|
||||
|
||||
// If true, fetch API calls are not monitored.
|
||||
// Default true
|
||||
disableFetchTracking: boolean;
|
||||
|
||||
// If true, default behavior of trackPageView is changed to record end of page view duration interval when
|
||||
// trackPageView is called. If false and no custom duration is provided to trackPageView, the page view
|
||||
// performance is calculated using the navigation timing API.
|
||||
|
|
|
@ -90,12 +90,12 @@
|
|||
-->
|
||||
<SemanticVersionMajor>1</SemanticVersionMajor>
|
||||
<SemanticVersionMinor>0</SemanticVersionMinor>
|
||||
<SemanticVersionPatch>19</SemanticVersionPatch>
|
||||
<SemanticVersionPatch>20</SemanticVersionPatch>
|
||||
<!--
|
||||
Date when Semantic Version was changed.
|
||||
Update for every public release.
|
||||
-->
|
||||
<SemanticVersionDate>2018-08-20</SemanticVersionDate>
|
||||
<SemanticVersionDate>2018-08-25</SemanticVersionDate>
|
||||
<!--
|
||||
Pre-release version is used to distinguish internally built NuGet packages.
|
||||
Pre-release version = Minutes since semantic version was set, divided by 5 (to make it fit in a UInt16).
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
samplingPercentage?: number;
|
||||
autoTrackPageVisitTime?: boolean;
|
||||
disableAjaxTracking?: boolean;
|
||||
disableFetchTracking?: boolean;
|
||||
overridePageViewDuration?: boolean;
|
||||
maxAjaxCallsPerView?: number;
|
||||
disableDataLossAnalysis?: boolean;
|
||||
|
|
|
@ -26,7 +26,6 @@ class InitializationTests extends TestClass {
|
|||
autoTrackPageVisitTime: false,
|
||||
samplingPercentage: 33,
|
||||
disableAjaxTracking: true,
|
||||
disableFetchTracking: false,
|
||||
overridePageViewDuration: false,
|
||||
maxAjaxCallsPerView: 44,
|
||||
disableDataLossAnalysis: true,
|
||||
|
@ -97,7 +96,6 @@ class InitializationTests extends TestClass {
|
|||
Assert.equal(10000, init.config.diagnosticLogInterval);
|
||||
Assert.equal(100, init.config.samplingPercentage);
|
||||
Assert.equal(500, init.config.maxAjaxCallsPerView);
|
||||
Assert.equal(true, init.config.disableFetchTracking);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -125,7 +123,6 @@ class InitializationTests extends TestClass {
|
|||
Assert.equal(1, init.config.diagnosticLogInterval);
|
||||
Assert.equal(33, init.config.samplingPercentage);
|
||||
Assert.equal(44, init.config.maxAjaxCallsPerView);
|
||||
Assert.equal(false, init.config.disableFetchTracking);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -208,7 +205,6 @@ class InitializationTests extends TestClass {
|
|||
disableTelemetry: "false",
|
||||
verboseLogging: "false",
|
||||
emitLineDelimitedJson: "false",
|
||||
disableFetchTracking: "false",
|
||||
};
|
||||
|
||||
var config = Microsoft.ApplicationInsights.Initialization.getDefaultConfig(<any>userConfig);
|
||||
|
@ -218,7 +214,6 @@ class InitializationTests extends TestClass {
|
|||
Assert.ok(!config.disableTelemetry);
|
||||
Assert.ok(!config.verboseLogging);
|
||||
Assert.ok(!config.emitLineDelimitedJson);
|
||||
Assert.ok(!config.disableFetchTracking);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -232,7 +227,6 @@ class InitializationTests extends TestClass {
|
|||
disableTelemetry: "true",
|
||||
verboseLogging: "true",
|
||||
emitLineDelimitedJson: "true",
|
||||
disableFetchTracking: "true",
|
||||
};
|
||||
|
||||
var config = Microsoft.ApplicationInsights.Initialization.getDefaultConfig(<any>userConfig);
|
||||
|
@ -242,7 +236,6 @@ class InitializationTests extends TestClass {
|
|||
Assert.ok(config.disableTelemetry);
|
||||
Assert.ok(config.verboseLogging);
|
||||
Assert.ok(config.emitLineDelimitedJson);
|
||||
Assert.ok(config.disableFetchTracking);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/// <reference path="./fetch.tests.ts"/>
|
||||
/// <reference path="../TestFramework/Common.ts" />
|
||||
/// <reference path="../TestFramework/Common.ts" />
|
||||
/// <reference path="../../JavaScriptSDK/AppInsights.ts" />
|
||||
/// <reference path="../../JavaScriptSDK/Util.ts"/>
|
||||
|
||||
|
@ -1925,200 +1924,6 @@ class AppInsightsTests extends TestClass {
|
|||
Assert.equal(null, (<any>xhr).requestHeaders['Request-Context'], "Request-Context header is not set.");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
let trackStub: SinonSpy;
|
||||
let expectedAjaxId: string;
|
||||
this.testCaseAsync({
|
||||
name: "Fetch - Request-Context is not set if appId was not set",
|
||||
steps: [
|
||||
() => {
|
||||
window.fetch = FetchTests.createFetchStub(200);
|
||||
var snippet = this.getAppInsightsSnippet();
|
||||
snippet.disableFetchTracking = false;
|
||||
snippet.disableCorrelationHeaders = false;
|
||||
snippet.enableCorsCorrelation = true;
|
||||
snippet.maxBatchInterval = 0;
|
||||
|
||||
var appInsights = new Microsoft.ApplicationInsights.AppInsights(snippet);
|
||||
trackStub = this.sandbox.spy(appInsights, "trackDependencyData");
|
||||
|
||||
var expectedRootId = appInsights.context.operation.id;
|
||||
Assert.ok(expectedRootId.length > 0, "root id was initialized to non empty string");
|
||||
|
||||
let request = new Request("bla");
|
||||
// init is needed to check headers - they won't be added to the original request
|
||||
let init: RequestInit = { headers: new Headers() };
|
||||
fetch(request, init);
|
||||
expectedAjaxId = (request as any).ajaxData.id;
|
||||
Assert.equal(expectedAjaxId, (init.headers as Headers).get(Microsoft.ApplicationInsights.RequestHeaders.requestIdHeader), "Request-Id is set correctly");
|
||||
Assert.equal(null, (init.headers as Headers).get(Microsoft.ApplicationInsights.RequestHeaders.requestContextHeader), "Request-Context is not set");
|
||||
},
|
||||
<() => void>PollingAssert.createPollingAssert(() => trackStub.args[0][0].id === expectedAjaxId, "ajax id passed to trackDependencyData correctly", 1)
|
||||
],
|
||||
stepDelay: 0
|
||||
});
|
||||
|
||||
this.testCaseAsync({
|
||||
name: "Fetch - Request-Id and Request-Context are set and passed correctly",
|
||||
steps: [
|
||||
() => {
|
||||
window.fetch = FetchTests.createFetchStub(200);
|
||||
var snippet = this.getAppInsightsSnippet();
|
||||
snippet.disableAjaxTracking = false;
|
||||
snippet.disableCorrelationHeaders = false;
|
||||
snippet.enableCorsCorrelation = false;
|
||||
snippet.maxBatchInterval = 0;
|
||||
|
||||
var appInsights = new Microsoft.ApplicationInsights.AppInsights(snippet);
|
||||
appInsights.context.appId = () => "C16FBA4D-ECE9-472E-8125-4FF5BEFAF8C1";
|
||||
trackStub = this.sandbox.spy(appInsights, "trackDependencyData");
|
||||
|
||||
var expectedRootId = appInsights.context.operation.id;
|
||||
Assert.ok(expectedRootId.length > 0, "root id was initialized to non empty string");
|
||||
|
||||
let request = new Request("bla");
|
||||
// init is needed to check headers - they won't be added to the original request
|
||||
let init: RequestInit = { headers: new Headers() };
|
||||
fetch(request, init);
|
||||
expectedAjaxId = (request as any).ajaxData.id;
|
||||
Assert.ok(expectedAjaxId.length > 0, "ajax id was initialized");
|
||||
Assert.equal(expectedAjaxId, (init.headers as Headers).get(Microsoft.ApplicationInsights.RequestHeaders.requestIdHeader), "Request-Id is set correctly");
|
||||
Assert.equal("appId=cid-v1:C16FBA4D-ECE9-472E-8125-4FF5BEFAF8C1", (init.headers as Headers).get(Microsoft.ApplicationInsights.RequestHeaders.requestContextHeader), "Request-Context is set correctly");
|
||||
},
|
||||
<() => void>PollingAssert.createPollingAssert(() => trackStub.args[0][0].id === expectedAjaxId, "ajax id passed to trackDependencyData correctly", 1)
|
||||
],
|
||||
stepDelay: 0
|
||||
});
|
||||
|
||||
this.testCaseAsync({
|
||||
name: "Fetch - Request-Id is not set for dependency calls with different port number if CORS correlation turned off",
|
||||
steps: [
|
||||
() => {
|
||||
window.fetch = FetchTests.createFetchStub(200);
|
||||
var snippet = this.getAppInsightsSnippet();
|
||||
snippet.disableAjaxTracking = false;
|
||||
snippet.disableCorrelationHeaders = false;
|
||||
snippet.enableCorsCorrelation = false;
|
||||
snippet.maxBatchInterval = 0;
|
||||
|
||||
var appInsights = new Microsoft.ApplicationInsights.AppInsights(snippet);
|
||||
trackStub = this.sandbox.spy(appInsights, "trackDependencyData");
|
||||
|
||||
var expectedRootId = appInsights.context.operation.id;
|
||||
Assert.ok(expectedRootId.length > 0, "root id was initialized to non empty string");
|
||||
|
||||
// override currentWindowHost
|
||||
var sampleHost = "api.applicationinsights.io";
|
||||
(<any>appInsights)._ajaxMonitor.currentWindowHost = sampleHost;
|
||||
|
||||
let request = new Request(`https://${sampleHost}:888/test`);
|
||||
// init is needed to check headers - they won't be added to the original request
|
||||
let init: RequestInit = { headers: new Headers() };
|
||||
fetch(request, init);
|
||||
expectedAjaxId = (request as any).ajaxData.id;
|
||||
Assert.ok(expectedAjaxId.length > 0, "ajax id was initialized");
|
||||
Assert.equal(null, (init.headers as Headers).get(Microsoft.ApplicationInsights.RequestHeaders.requestIdHeader), "Request-Id is not set");
|
||||
},
|
||||
<() => void>PollingAssert.createPollingAssert(() => trackStub.called, "trackDependencyData is called", 0.1)
|
||||
],
|
||||
stepDelay: 0
|
||||
});
|
||||
|
||||
this.testCaseAsync({
|
||||
name: "Fetch - Request-Id is set for dependency calls with different port number if CORS correlation turned on",
|
||||
steps: [
|
||||
() => {
|
||||
window.fetch = FetchTests.createFetchStub(200);
|
||||
var snippet = this.getAppInsightsSnippet();
|
||||
snippet.disableAjaxTracking = false;
|
||||
snippet.disableCorrelationHeaders = false;
|
||||
snippet.enableCorsCorrelation = true;
|
||||
snippet.maxBatchInterval = 0;
|
||||
|
||||
var appInsights = new Microsoft.ApplicationInsights.AppInsights(snippet);
|
||||
trackStub = this.sandbox.spy(appInsights, "trackDependencyData");
|
||||
|
||||
var expectedRootId = appInsights.context.operation.id;
|
||||
Assert.ok(expectedRootId.length > 0, "root id was initialized to non empty string");
|
||||
|
||||
// override currentWindowHost
|
||||
var sampleHost = "api.applicationinsights.io";
|
||||
(<any>appInsights)._ajaxMonitor.currentWindowHost = sampleHost;
|
||||
|
||||
let request = new Request(`https://${sampleHost}:888/test`);
|
||||
// init is needed to check headers - they won't be added to the original request
|
||||
let init: RequestInit = { headers: new Headers() };
|
||||
fetch(request, init);
|
||||
expectedAjaxId = (request as any).ajaxData.id;
|
||||
Assert.ok(expectedAjaxId.length > 0, "ajax id was initialized");
|
||||
Assert.equal(expectedAjaxId, (init.headers as Headers).get(Microsoft.ApplicationInsights.RequestHeaders.requestIdHeader), "Request-Id is set correctly");
|
||||
},
|
||||
<() => void>PollingAssert.createPollingAssert(() => trackStub.args[0][0].id === expectedAjaxId, "ajax id passed to trackDependencyData correctly", 1)
|
||||
],
|
||||
stepDelay: 0
|
||||
});
|
||||
|
||||
this.testCaseAsync({
|
||||
name: "Fetch - disableCorrelationHeaders disables Request-Id and Request-Context headers",
|
||||
steps: [
|
||||
() => {
|
||||
window.fetch = FetchTests.createFetchStub(200);
|
||||
var snippet = this.getAppInsightsSnippet();
|
||||
snippet.disableAjaxTracking = false;
|
||||
snippet.disableCorrelationHeaders = true;
|
||||
snippet.enableCorsCorrelation = true;
|
||||
snippet.maxBatchInterval = 0;
|
||||
|
||||
var appInsights = new Microsoft.ApplicationInsights.AppInsights(snippet);
|
||||
appInsights.context.appId = () => "C16FBA4D-ECE9-472E-8125-4FF5BEFAF8C1";
|
||||
trackStub = this.sandbox.spy(appInsights, "trackDependencyData");
|
||||
|
||||
var expectedRootId = appInsights.context.operation.id;
|
||||
Assert.ok(expectedRootId.length > 0, "root id was initialized to non empty string");
|
||||
|
||||
let request = new Request("bla");
|
||||
// init is needed to check headers - they won't be added to the original request
|
||||
let init: RequestInit = { headers: new Headers() };
|
||||
fetch(request, init);
|
||||
Assert.equal(null, (init.headers as Headers).get(Microsoft.ApplicationInsights.RequestHeaders.requestIdHeader), "Request-Id is not set");
|
||||
Assert.equal(null, (init.headers as Headers).get(Microsoft.ApplicationInsights.RequestHeaders.requestContextHeader), "Request-Context is not set");
|
||||
},
|
||||
<() => void>PollingAssert.createPollingAssert(() => trackStub.called, "trackDependencyData is called", 0.1)
|
||||
],
|
||||
stepDelay: 0
|
||||
});
|
||||
|
||||
this.testCaseAsync({
|
||||
name: "Ajax - Request-Id and Request-Context headers are disabled for excluded domain",
|
||||
steps: [
|
||||
() => {
|
||||
window.fetch = FetchTests.createFetchStub(200);
|
||||
var snippet = this.getAppInsightsSnippet();
|
||||
snippet.disableAjaxTracking = false;
|
||||
snippet.disableCorrelationHeaders = false;
|
||||
snippet.enableCorsCorrelation = true;
|
||||
snippet.correlationHeaderExcludedDomains = ["some.excluded.domain"];
|
||||
snippet.maxBatchInterval = 0;
|
||||
|
||||
var appInsights = new Microsoft.ApplicationInsights.AppInsights(snippet);
|
||||
appInsights.context.appId = () => "C16FBA4D-ECE9-472E-8125-4FF5BEFAF8C1";
|
||||
trackStub = this.sandbox.spy(appInsights, "trackDependencyData");
|
||||
|
||||
var expectedRootId = appInsights.context.operation.id;
|
||||
Assert.ok(expectedRootId.length > 0, "root id was initialized to non empty string");
|
||||
|
||||
let request = new Request("http://some.excluded.domain/test");
|
||||
// init is needed to check headers - they won't be added to the original request
|
||||
let init: RequestInit = { headers: new Headers() };
|
||||
fetch(request, init);
|
||||
Assert.equal(null, (init.headers as Headers).get(Microsoft.ApplicationInsights.RequestHeaders.requestIdHeader), "Request-Id is not set");
|
||||
Assert.equal(null, (init.headers as Headers).get(Microsoft.ApplicationInsights.RequestHeaders.requestContextHeader), "Request-Context is not set");
|
||||
},
|
||||
<() => void>PollingAssert.createPollingAssert(() => trackStub.called, "trackDependencyData is called", 0.1)
|
||||
],
|
||||
stepDelay: 0
|
||||
});
|
||||
}
|
||||
|
||||
private getFirstResult(action: string, trackStub: SinonStub, skipSessionState?: boolean) {
|
||||
|
|
|
@ -1,127 +0,0 @@
|
|||
/// <reference path="../TestFramework/Common.ts" />
|
||||
/// <reference path="../../JavaScriptSDK/ajax/ajax.ts" />
|
||||
/// <reference path="../../JavaScriptSDK/ajax/fetch.ts" />
|
||||
/// <reference path="../../JavaScriptSDK/Util.ts"/>
|
||||
/// <reference path="../../JavaScriptSDK/Telemetry/RemoteDependencyData.ts"/>
|
||||
|
||||
class FetchTests extends TestClass {
|
||||
|
||||
private appInsightsMock = {
|
||||
trackDependency: (id: string, method: string, absoluteUrl: string, isAsync: boolean, totalTime: number, success: boolean) => { },
|
||||
trackDependencyData: (dependency: Microsoft.ApplicationInsights.Telemetry.RemoteDependencyData) => { },
|
||||
context: {
|
||||
operation: {
|
||||
id: "asdf"
|
||||
},
|
||||
appId: () => "someid"
|
||||
},
|
||||
config: {
|
||||
disableCorrelationHeaders: false,
|
||||
enableCorsCorrelation: false
|
||||
}
|
||||
}
|
||||
private trackDependencySpy: SinonSpy;
|
||||
|
||||
public testInitialize() {
|
||||
this.trackDependencySpy = this.sandbox.spy(this.appInsightsMock, "trackDependencyData");
|
||||
this.trackDependencySpy.reset();
|
||||
}
|
||||
|
||||
public testCleanup() {
|
||||
}
|
||||
|
||||
public registerTests() {
|
||||
this.testCase({
|
||||
name: "Fetch: window.fetch gets instrumented",
|
||||
test: () => {
|
||||
window.fetch = FetchTests.createFetchStub(200);
|
||||
let fm = new Microsoft.ApplicationInsights.FetchMonitor(<any>this.appInsightsMock);
|
||||
|
||||
// assert
|
||||
let isInstrumented = window.fetch[Microsoft.ApplicationInsights.FetchMonitor.instrumentedByAppInsightsName];
|
||||
Assert.equal(true, isInstrumented, "window.fetch is instrumented");
|
||||
}
|
||||
});
|
||||
|
||||
this.testCaseAsync({
|
||||
name: "Fetch: successful request, fetch monitor doesn't change payload",
|
||||
steps: [
|
||||
() => {
|
||||
window.fetch = FetchTests.createFetchStub(200);
|
||||
let fm = new Microsoft.ApplicationInsights.FetchMonitor(<any>this.appInsightsMock);
|
||||
fetch("bla").then(r => {
|
||||
this["response"] = r;
|
||||
r.text().then(t => this["text"] = t);
|
||||
});
|
||||
},
|
||||
<() => void>PollingAssert.createPollingAssert(() => this.trackDependencySpy.called, "trackDependencyData is called", 0.1),
|
||||
<() => void>PollingAssert.createPollingAssert(() => this["text"] === "bla", "Expected result mismatch", 0.1),
|
||||
<() => void>PollingAssert.createPollingAssert(() => this["response"].status === 200, "Expected 200 response code", 0.1)
|
||||
],
|
||||
stepDelay: 0
|
||||
});
|
||||
|
||||
this.testCaseAsync({
|
||||
name: "Fetch: 200 means success",
|
||||
steps: [
|
||||
() => {
|
||||
window.fetch = FetchTests.createFetchStub(200);
|
||||
let fm = new Microsoft.ApplicationInsights.FetchMonitor(<any>this.appInsightsMock);
|
||||
fetch("bla");
|
||||
},
|
||||
<() => void>PollingAssert.createPollingAssert(() => this.trackDependencySpy.called, "trackDependencyData is called", 0.1),
|
||||
<() => void>PollingAssert.createPollingAssert(() => this.trackDependencySpy.args[0][0].success, "trackDependencyData should receive true as a 'success' argument", 0.1)
|
||||
],
|
||||
stepDelay: 0
|
||||
});
|
||||
|
||||
this.testCaseAsync({
|
||||
name: "Fetch: non 200 means failure",
|
||||
steps: [
|
||||
() => {
|
||||
window.fetch = FetchTests.createFetchStub(400);
|
||||
let fm = new Microsoft.ApplicationInsights.FetchMonitor(<any>this.appInsightsMock);
|
||||
fetch("bla");
|
||||
},
|
||||
<() => void>PollingAssert.createPollingAssert(() => this.trackDependencySpy.called, "trackDependencyData is called", 0.1),
|
||||
<() => void>PollingAssert.createPollingAssert(() => !this.trackDependencySpy.args[0][0].success, "trackDependencyData should receive false as a 'success' argument", 0.1)
|
||||
],
|
||||
stepDelay: 0
|
||||
});
|
||||
|
||||
[200, 201, 202, 203, 204, 301, 302, 303, 304].forEach((responseCode) => {
|
||||
this.testCaseAsync({
|
||||
name: "Fetch: test success http response code: " + responseCode,
|
||||
steps: this.testFetchSuccess(responseCode, true),
|
||||
stepDelay: 0
|
||||
})
|
||||
});
|
||||
|
||||
[400, 401, 402, 403, 404, 500, 501].forEach((responseCode) => {
|
||||
this.testCaseAsync({
|
||||
name: "Fetch: test failure http response code: " + responseCode,
|
||||
steps: this.testFetchSuccess(responseCode, false),
|
||||
stepDelay: 0
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
private testFetchSuccess(responseCode: number, success: boolean): Array<() => void> {
|
||||
return [
|
||||
() => {
|
||||
window.fetch = FetchTests.createFetchStub(responseCode, responseCode === 204 || responseCode === 304 ? null : "bla");
|
||||
let fm = new Microsoft.ApplicationInsights.FetchMonitor(<any>this.appInsightsMock);
|
||||
fetch("bla");
|
||||
},
|
||||
<() => void>PollingAssert.createPollingAssert(() => this.trackDependencySpy.args[0][0].success === success, `trackDependencyData should receive ${success} as a 'success' argument`, 0.1)
|
||||
];
|
||||
}
|
||||
|
||||
static createFetchStub(responseCode: number, body: string = "bla", timeout: number = 0): (input?: Request | string, init?: RequestInit) => Promise<Response> {
|
||||
return (input, init) => new (window as any).Promise(resolve => {
|
||||
PollingAssert.setTimeout(() => resolve(new Response(body, { status: responseCode, headers: { "Content-Type": "application/json" } })), timeout);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
new FetchTests().registerTests();
|
|
@ -22,7 +22,6 @@ const config: Microsoft.ApplicationInsights.IConfig = {
|
|||
autoTrackPageVisitTime: true,
|
||||
disableExceptionTracking: false,
|
||||
disableAjaxTracking: false,
|
||||
disableFetchTracking: false,
|
||||
overridePageViewDuration: false,
|
||||
maxAjaxCallsPerView: -1,
|
||||
disableDataLossAnalysis: true,
|
||||
|
|
|
@ -80,18 +80,12 @@ class SenderE2ETests extends TestClass {
|
|||
}
|
||||
let beaconConfig = Microsoft.ApplicationInsights.Initialization.getDefaultConfig();
|
||||
beaconConfig.isBeaconApiDisabled = false;
|
||||
beaconConfig.disableFetchTracking = true;
|
||||
beaconConfig.disableAjaxTracking = true;
|
||||
this.beaconClient = this.getAiClient(beaconConfig);
|
||||
|
||||
let aiConfig = Microsoft.ApplicationInsights.Initialization.getDefaultConfig();
|
||||
aiConfig.disableAjaxTracking = false;
|
||||
aiConfig.disableFetchTracking = false;
|
||||
this.aiClient = this.getAiClient(aiConfig);
|
||||
|
||||
let vortexConfig = Microsoft.ApplicationInsights.Initialization.getDefaultConfig();
|
||||
vortexConfig.disableFetchTracking = true;
|
||||
vortexConfig.disableAjaxTracking = true;
|
||||
this.vortexAiClient = this.getVortexAiClient(vortexConfig);
|
||||
|
||||
this.testCaseAsync({
|
||||
|
@ -149,48 +143,6 @@ class SenderE2ETests extends TestClass {
|
|||
}
|
||||
]
|
||||
});
|
||||
|
||||
this.testCaseAsync({
|
||||
name: "Ajax/Fetch: Network request telemetry is successfully recorded",
|
||||
stepDelay: 0,
|
||||
steps: [
|
||||
// Act: Ajax
|
||||
() => {
|
||||
let xhr: XMLHttpRequest;
|
||||
|
||||
this["xhrStatus"] = 0;
|
||||
for (let i = 0; i < 7; i++) {
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.onloadend = () => { this["xhrStatus"]++; }
|
||||
xhr.open("GET", `https://httpbin.org/status/${i + 200}`, true);
|
||||
xhr.send();
|
||||
}
|
||||
},
|
||||
() => {
|
||||
this["fetchStatus"] = 0;
|
||||
for (let i = 0; i < 9; i++) {
|
||||
fetch(`https://httpbin.org/status/${i + 200}`, { method: "POST" }).then(r => {
|
||||
this["fetchStatus"] += (r.status === 200 + i);
|
||||
});
|
||||
}
|
||||
},
|
||||
// Assert
|
||||
<() => void>PollingAssert.createPollingAssert(() => this.aiSpy.called, "trackDependencyData is called", 5),
|
||||
<() => void>PollingAssert.createPollingAssert(() => this["xhrStatus"] === 7, "XHR expects 200 response code 7 times", 5),
|
||||
<() => void>PollingAssert.createPollingAssert(() => this["fetchStatus"] === 9, "Fetch expects 200 response code 9 times", 5),
|
||||
<() => void>PollingAssert.createPollingAssert(() => {
|
||||
let itemsAccepted: number = 0;
|
||||
|
||||
for (let payload of this.aiSpy.args) {
|
||||
let count: number = payload[1];
|
||||
itemsAccepted += count;
|
||||
}
|
||||
|
||||
return (itemsAccepted === 7 + 9);
|
||||
}, "Backend accepts 7 XHR items and 9 Fetch items, or 16 XHR items for browsers requiring a fetch-polyfill", 5)
|
||||
]
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
new SenderE2ETests().registerTests();
|
|
@ -192,6 +192,16 @@ declare class PollingAssert {
|
|||
*/
|
||||
static createPollingAssert(assertionFunctionReturnsBoolean: () => boolean, assertDescription: string, timeoutSeconds?: number, pollIntervalMs?: number): (nextTestStep) => void;
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights {
|
||||
interface ISerializable {
|
||||
/**
|
||||
* The set of fields for a serializable object.
|
||||
* This defines the serialization order and a value of true/false
|
||||
* for each field defines whether the field is required or not.
|
||||
*/
|
||||
aiDataContract: any;
|
||||
}
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights {
|
||||
enum LoggingSeverity {
|
||||
/**
|
||||
|
@ -555,225 +565,6 @@ declare module Microsoft.ApplicationInsights {
|
|||
static getCorrelationContextValue(responseHeader: string, key: string): string;
|
||||
}
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights {
|
||||
class extensions {
|
||||
static IsNullOrUndefined(obj: any): boolean;
|
||||
}
|
||||
class stringUtils {
|
||||
static GetLength(strObject: any): number;
|
||||
}
|
||||
class dateTime {
|
||||
static Now: () => number;
|
||||
static GetDuration: (start: number, end: number) => number;
|
||||
}
|
||||
class EventHelper {
|
||||
static AttachEvent(obj: any, eventNameWithoutOn: any, handlerRef: any): boolean;
|
||||
static DetachEvent(obj: any, eventNameWithoutOn: any, handlerRef: any): void;
|
||||
}
|
||||
class AjaxHelper {
|
||||
static ParseDependencyPath(absoluteUrl: string, method: string, pathName: string): {
|
||||
target: any;
|
||||
name: any;
|
||||
};
|
||||
}
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights {
|
||||
class XHRMonitoringState {
|
||||
openDone: boolean;
|
||||
setRequestHeaderDone: boolean;
|
||||
sendDone: boolean;
|
||||
abortDone: boolean;
|
||||
onreadystatechangeCallbackAttached: boolean;
|
||||
}
|
||||
class ajaxRecord {
|
||||
completed: boolean;
|
||||
requestHeadersSize: any;
|
||||
ttfb: any;
|
||||
responseReceivingDuration: any;
|
||||
callbackDuration: any;
|
||||
ajaxTotalDuration: any;
|
||||
aborted: any;
|
||||
pageUrl: any;
|
||||
requestUrl: any;
|
||||
requestSize: number;
|
||||
method: any;
|
||||
status: any;
|
||||
requestSentTime: any;
|
||||
responseStartedTime: any;
|
||||
responseFinishedTime: any;
|
||||
callbackFinishedTime: any;
|
||||
endTime: any;
|
||||
originalOnreadystatechage: any;
|
||||
xhrMonitoringState: XHRMonitoringState;
|
||||
clientFailure: number;
|
||||
id: string;
|
||||
constructor(id: string);
|
||||
getAbsoluteUrl(): string;
|
||||
getPathName(): any;
|
||||
CalculateMetrics: () => void;
|
||||
}
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights {
|
||||
class RequestHeaders {
|
||||
/**
|
||||
* Request-Context header
|
||||
*/
|
||||
static requestContextHeader: string;
|
||||
/**
|
||||
* Target instrumentation header that is added to the response and retrieved by the
|
||||
* calling application when processing incoming responses.
|
||||
*/
|
||||
static requestContextTargetKey: string;
|
||||
/**
|
||||
* Request-Context appId format
|
||||
*/
|
||||
static requestContextAppIdFormat: string;
|
||||
/**
|
||||
* Request-Id header
|
||||
*/
|
||||
static requestIdHeader: string;
|
||||
/**
|
||||
* Sdk-Context header
|
||||
* If this header passed with appId in content then appId will be returned back by the backend.
|
||||
*/
|
||||
static sdkContextHeader: string;
|
||||
/**
|
||||
* String to pass in header for requesting appId back from the backend.
|
||||
*/
|
||||
static sdkContextHeaderAppIdRequest: string;
|
||||
static requestContextHeaderLowerCase: string;
|
||||
}
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights {
|
||||
interface ISerializable {
|
||||
/**
|
||||
* The set of fields for a serializable object.
|
||||
* This defines the serialization order and a value of true/false
|
||||
* for each field defines whether the field is required or not.
|
||||
*/
|
||||
aiDataContract: any;
|
||||
}
|
||||
}
|
||||
declare module Microsoft.Telemetry {
|
||||
/**
|
||||
* The abstract common base of all domains.
|
||||
*/
|
||||
class Domain {
|
||||
constructor();
|
||||
}
|
||||
}
|
||||
declare module AI {
|
||||
/**
|
||||
* Instances of Event represent structured event records that can be grouped and searched by their properties. Event data item also creates a metric of event count by name.
|
||||
*/
|
||||
class EventData extends Microsoft.Telemetry.Domain {
|
||||
/**
|
||||
* Schema version
|
||||
*/
|
||||
ver: number;
|
||||
/**
|
||||
* Event name. Keep it low cardinality to allow proper grouping and useful metrics.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Collection of custom properties.
|
||||
*/
|
||||
properties: any;
|
||||
/**
|
||||
* Collection of custom measurements.
|
||||
*/
|
||||
measurements: any;
|
||||
constructor();
|
||||
}
|
||||
}
|
||||
declare module AI {
|
||||
/**
|
||||
* An instance of PageView represents a generic action on a page like a button click. It is also the base type for PageView.
|
||||
*/
|
||||
class PageViewData extends AI.EventData {
|
||||
/**
|
||||
* Schema version
|
||||
*/
|
||||
ver: number;
|
||||
/**
|
||||
* Request URL with all query string parameters
|
||||
*/
|
||||
url: string;
|
||||
/**
|
||||
* Event name. Keep it low cardinality to allow proper grouping and useful metrics.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Request duration in format: DD.HH:MM:SS.MMMMMM. For a page view (PageViewData), this is the duration. For a page view with performance information (PageViewPerfData), this is the page load time. Must be less than 1000 days.
|
||||
*/
|
||||
duration: string;
|
||||
/**
|
||||
* Identifier of a page view instance. Used for correlation between page view and other telemetry items.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Collection of custom properties.
|
||||
*/
|
||||
properties: any;
|
||||
/**
|
||||
* Collection of custom measurements.
|
||||
*/
|
||||
measurements: any;
|
||||
constructor();
|
||||
}
|
||||
}
|
||||
declare module AI {
|
||||
/**
|
||||
* An instance of Remote Dependency represents an interaction of the monitored component with a remote component/service like SQL or an HTTP endpoint.
|
||||
*/
|
||||
class RemoteDependencyData extends Microsoft.Telemetry.Domain {
|
||||
/**
|
||||
* Schema version
|
||||
*/
|
||||
ver: number;
|
||||
/**
|
||||
* Name of the command initiated with this dependency call. Low cardinality value. Examples are stored procedure name and URL path template.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Identifier of a dependency call instance. Used for correlation with the request telemetry item corresponding to this dependency call.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Result code of a dependency call. Examples are SQL error code and HTTP status code.
|
||||
*/
|
||||
resultCode: string;
|
||||
/**
|
||||
* Request duration in format: DD.HH:MM:SS.MMMMMM. Must be less than 1000 days.
|
||||
*/
|
||||
duration: string;
|
||||
/**
|
||||
* Indication of successfull or unsuccessfull call.
|
||||
*/
|
||||
success: boolean;
|
||||
/**
|
||||
* Command initiated by this dependency call. Examples are SQL statement and HTTP URL's with all query parameters.
|
||||
*/
|
||||
data: string;
|
||||
/**
|
||||
* Target site of a dependency call. Examples are server name, host address.
|
||||
*/
|
||||
target: string;
|
||||
/**
|
||||
* Dependency type name. Very low cardinality value for logical grouping of dependencies and interpretation of other fields like commandName and resultCode. Examples are SQL, Azure table, and HTTP.
|
||||
*/
|
||||
type: string;
|
||||
/**
|
||||
* Collection of custom properties.
|
||||
*/
|
||||
properties: any;
|
||||
/**
|
||||
* Collection of custom measurements.
|
||||
*/
|
||||
measurements: any;
|
||||
constructor();
|
||||
}
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights {
|
||||
/**
|
||||
* Enum is used in aiDataContract to describe how fields are serialized.
|
||||
|
@ -795,82 +586,6 @@ declare module Microsoft.ApplicationInsights {
|
|||
private static _serializeStringMap(map, expectedType, name);
|
||||
}
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights.Telemetry.Common {
|
||||
class DataSanitizer {
|
||||
/**
|
||||
* Max length allowed for custom names.
|
||||
*/
|
||||
private static MAX_NAME_LENGTH;
|
||||
/**
|
||||
* Max length allowed for Id field in page views.
|
||||
*/
|
||||
private static MAX_ID_LENGTH;
|
||||
/**
|
||||
* Max length allowed for custom values.
|
||||
*/
|
||||
private static MAX_PROPERTY_LENGTH;
|
||||
/**
|
||||
* Max length allowed for names
|
||||
*/
|
||||
private static MAX_STRING_LENGTH;
|
||||
/**
|
||||
* Max length allowed for url.
|
||||
*/
|
||||
private static MAX_URL_LENGTH;
|
||||
/**
|
||||
* Max length allowed for messages.
|
||||
*/
|
||||
private static MAX_MESSAGE_LENGTH;
|
||||
/**
|
||||
* Max length allowed for exceptions.
|
||||
*/
|
||||
private static MAX_EXCEPTION_LENGTH;
|
||||
static sanitizeKeyAndAddUniqueness(key: any, map: any): any;
|
||||
static sanitizeKey(name: any): any;
|
||||
static sanitizeString(value: any, maxLength?: number): any;
|
||||
static sanitizeUrl(url: any): any;
|
||||
static sanitizeMessage(message: any): any;
|
||||
static sanitizeException(exception: any): any;
|
||||
static sanitizeProperties(properties: any): any;
|
||||
static sanitizeMeasurements(measurements: any): any;
|
||||
static sanitizeId(id: string): string;
|
||||
static sanitizeInput(input: any, maxLength: number, _msgId: _InternalMessageId): any;
|
||||
static padNumber(num: any): string;
|
||||
}
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights.Telemetry {
|
||||
class RemoteDependencyData extends AI.RemoteDependencyData implements ISerializable {
|
||||
static envelopeType: string;
|
||||
static dataType: string;
|
||||
aiDataContract: {
|
||||
id: FieldType;
|
||||
ver: FieldType;
|
||||
name: FieldType;
|
||||
resultCode: FieldType;
|
||||
duration: FieldType;
|
||||
success: FieldType;
|
||||
data: FieldType;
|
||||
target: FieldType;
|
||||
type: FieldType;
|
||||
properties: FieldType;
|
||||
measurements: FieldType;
|
||||
kind: FieldType;
|
||||
value: FieldType;
|
||||
count: FieldType;
|
||||
min: FieldType;
|
||||
max: FieldType;
|
||||
stdDev: FieldType;
|
||||
dependencyKind: FieldType;
|
||||
dependencySource: FieldType;
|
||||
commandName: FieldType;
|
||||
dependencyTypeName: FieldType;
|
||||
};
|
||||
/**
|
||||
* Constructs a new instance of the RemoteDependencyData object
|
||||
*/
|
||||
constructor(id: string, absoluteUrl: string, commandName: string, value: number, success: boolean, resultCode: number, method?: string, properties?: Object, measurements?: Object);
|
||||
}
|
||||
}
|
||||
declare module Microsoft.Telemetry {
|
||||
/**
|
||||
* Data struct to contain only C section with custom fields.
|
||||
|
@ -1508,6 +1223,316 @@ declare module Microsoft.ApplicationInsights.Context {
|
|||
private validateUserInput(id);
|
||||
}
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights {
|
||||
class extensions {
|
||||
static IsNullOrUndefined(obj: any): boolean;
|
||||
}
|
||||
class stringUtils {
|
||||
static GetLength(strObject: any): number;
|
||||
}
|
||||
class dateTime {
|
||||
static Now: () => number;
|
||||
static GetDuration: (start: number, end: number) => number;
|
||||
}
|
||||
class EventHelper {
|
||||
static AttachEvent(obj: any, eventNameWithoutOn: any, handlerRef: any): boolean;
|
||||
static DetachEvent(obj: any, eventNameWithoutOn: any, handlerRef: any): void;
|
||||
}
|
||||
class AjaxHelper {
|
||||
static ParseDependencyPath(absoluteUrl: string, method: string, pathName: string): {
|
||||
target: any;
|
||||
name: any;
|
||||
};
|
||||
}
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights {
|
||||
class XHRMonitoringState {
|
||||
openDone: boolean;
|
||||
setRequestHeaderDone: boolean;
|
||||
sendDone: boolean;
|
||||
abortDone: boolean;
|
||||
onreadystatechangeCallbackAttached: boolean;
|
||||
}
|
||||
class ajaxRecord {
|
||||
completed: boolean;
|
||||
requestHeadersSize: any;
|
||||
ttfb: any;
|
||||
responseReceivingDuration: any;
|
||||
callbackDuration: any;
|
||||
ajaxTotalDuration: any;
|
||||
aborted: any;
|
||||
pageUrl: any;
|
||||
requestUrl: any;
|
||||
requestSize: number;
|
||||
method: any;
|
||||
status: any;
|
||||
requestSentTime: any;
|
||||
responseStartedTime: any;
|
||||
responseFinishedTime: any;
|
||||
callbackFinishedTime: any;
|
||||
endTime: any;
|
||||
originalOnreadystatechage: any;
|
||||
xhrMonitoringState: XHRMonitoringState;
|
||||
clientFailure: number;
|
||||
id: string;
|
||||
constructor(id: string);
|
||||
getAbsoluteUrl(): string;
|
||||
getPathName(): any;
|
||||
CalculateMetrics: () => void;
|
||||
}
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights {
|
||||
class RequestHeaders {
|
||||
/**
|
||||
* Request-Context header
|
||||
*/
|
||||
static requestContextHeader: string;
|
||||
/**
|
||||
* Target instrumentation header that is added to the response and retrieved by the
|
||||
* calling application when processing incoming responses.
|
||||
*/
|
||||
static requestContextTargetKey: string;
|
||||
/**
|
||||
* Request-Context appId format
|
||||
*/
|
||||
static requestContextAppIdFormat: string;
|
||||
/**
|
||||
* Request-Id header
|
||||
*/
|
||||
static requestIdHeader: string;
|
||||
/**
|
||||
* Sdk-Context header
|
||||
* If this header passed with appId in content then appId will be returned back by the backend.
|
||||
*/
|
||||
static sdkContextHeader: string;
|
||||
/**
|
||||
* String to pass in header for requesting appId back from the backend.
|
||||
*/
|
||||
static sdkContextHeaderAppIdRequest: string;
|
||||
static requestContextHeaderLowerCase: string;
|
||||
}
|
||||
}
|
||||
declare module Microsoft.Telemetry {
|
||||
/**
|
||||
* The abstract common base of all domains.
|
||||
*/
|
||||
class Domain {
|
||||
constructor();
|
||||
}
|
||||
}
|
||||
declare module AI {
|
||||
/**
|
||||
* Instances of Event represent structured event records that can be grouped and searched by their properties. Event data item also creates a metric of event count by name.
|
||||
*/
|
||||
class EventData extends Microsoft.Telemetry.Domain {
|
||||
/**
|
||||
* Schema version
|
||||
*/
|
||||
ver: number;
|
||||
/**
|
||||
* Event name. Keep it low cardinality to allow proper grouping and useful metrics.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Collection of custom properties.
|
||||
*/
|
||||
properties: any;
|
||||
/**
|
||||
* Collection of custom measurements.
|
||||
*/
|
||||
measurements: any;
|
||||
constructor();
|
||||
}
|
||||
}
|
||||
declare module AI {
|
||||
/**
|
||||
* An instance of PageView represents a generic action on a page like a button click. It is also the base type for PageView.
|
||||
*/
|
||||
class PageViewData extends AI.EventData {
|
||||
/**
|
||||
* Schema version
|
||||
*/
|
||||
ver: number;
|
||||
/**
|
||||
* Request URL with all query string parameters
|
||||
*/
|
||||
url: string;
|
||||
/**
|
||||
* Event name. Keep it low cardinality to allow proper grouping and useful metrics.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Request duration in format: DD.HH:MM:SS.MMMMMM. For a page view (PageViewData), this is the duration. For a page view with performance information (PageViewPerfData), this is the page load time. Must be less than 1000 days.
|
||||
*/
|
||||
duration: string;
|
||||
/**
|
||||
* Identifier of a page view instance. Used for correlation between page view and other telemetry items.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Collection of custom properties.
|
||||
*/
|
||||
properties: any;
|
||||
/**
|
||||
* Collection of custom measurements.
|
||||
*/
|
||||
measurements: any;
|
||||
constructor();
|
||||
}
|
||||
}
|
||||
declare module AI {
|
||||
/**
|
||||
* An instance of Remote Dependency represents an interaction of the monitored component with a remote component/service like SQL or an HTTP endpoint.
|
||||
*/
|
||||
class RemoteDependencyData extends Microsoft.Telemetry.Domain {
|
||||
/**
|
||||
* Schema version
|
||||
*/
|
||||
ver: number;
|
||||
/**
|
||||
* Name of the command initiated with this dependency call. Low cardinality value. Examples are stored procedure name and URL path template.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Identifier of a dependency call instance. Used for correlation with the request telemetry item corresponding to this dependency call.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Result code of a dependency call. Examples are SQL error code and HTTP status code.
|
||||
*/
|
||||
resultCode: string;
|
||||
/**
|
||||
* Request duration in format: DD.HH:MM:SS.MMMMMM. Must be less than 1000 days.
|
||||
*/
|
||||
duration: string;
|
||||
/**
|
||||
* Indication of successfull or unsuccessfull call.
|
||||
*/
|
||||
success: boolean;
|
||||
/**
|
||||
* Command initiated by this dependency call. Examples are SQL statement and HTTP URL's with all query parameters.
|
||||
*/
|
||||
data: string;
|
||||
/**
|
||||
* Target site of a dependency call. Examples are server name, host address.
|
||||
*/
|
||||
target: string;
|
||||
/**
|
||||
* Dependency type name. Very low cardinality value for logical grouping of dependencies and interpretation of other fields like commandName and resultCode. Examples are SQL, Azure table, and HTTP.
|
||||
*/
|
||||
type: string;
|
||||
/**
|
||||
* Collection of custom properties.
|
||||
*/
|
||||
properties: any;
|
||||
/**
|
||||
* Collection of custom measurements.
|
||||
*/
|
||||
measurements: any;
|
||||
constructor();
|
||||
}
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights.Telemetry.Common {
|
||||
class DataSanitizer {
|
||||
/**
|
||||
* Max length allowed for custom names.
|
||||
*/
|
||||
private static MAX_NAME_LENGTH;
|
||||
/**
|
||||
* Max length allowed for Id field in page views.
|
||||
*/
|
||||
private static MAX_ID_LENGTH;
|
||||
/**
|
||||
* Max length allowed for custom values.
|
||||
*/
|
||||
private static MAX_PROPERTY_LENGTH;
|
||||
/**
|
||||
* Max length allowed for names
|
||||
*/
|
||||
private static MAX_STRING_LENGTH;
|
||||
/**
|
||||
* Max length allowed for url.
|
||||
*/
|
||||
private static MAX_URL_LENGTH;
|
||||
/**
|
||||
* Max length allowed for messages.
|
||||
*/
|
||||
private static MAX_MESSAGE_LENGTH;
|
||||
/**
|
||||
* Max length allowed for exceptions.
|
||||
*/
|
||||
private static MAX_EXCEPTION_LENGTH;
|
||||
static sanitizeKeyAndAddUniqueness(key: any, map: any): any;
|
||||
static sanitizeKey(name: any): any;
|
||||
static sanitizeString(value: any, maxLength?: number): any;
|
||||
static sanitizeUrl(url: any): any;
|
||||
static sanitizeMessage(message: any): any;
|
||||
static sanitizeException(exception: any): any;
|
||||
static sanitizeProperties(properties: any): any;
|
||||
static sanitizeMeasurements(measurements: any): any;
|
||||
static sanitizeId(id: string): string;
|
||||
static sanitizeInput(input: any, maxLength: number, _msgId: _InternalMessageId): any;
|
||||
static padNumber(num: any): string;
|
||||
}
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights.Telemetry {
|
||||
class RemoteDependencyData extends AI.RemoteDependencyData implements ISerializable {
|
||||
static envelopeType: string;
|
||||
static dataType: string;
|
||||
aiDataContract: {
|
||||
id: FieldType;
|
||||
ver: FieldType;
|
||||
name: FieldType;
|
||||
resultCode: FieldType;
|
||||
duration: FieldType;
|
||||
success: FieldType;
|
||||
data: FieldType;
|
||||
target: FieldType;
|
||||
type: FieldType;
|
||||
properties: FieldType;
|
||||
measurements: FieldType;
|
||||
kind: FieldType;
|
||||
value: FieldType;
|
||||
count: FieldType;
|
||||
min: FieldType;
|
||||
max: FieldType;
|
||||
stdDev: FieldType;
|
||||
dependencyKind: FieldType;
|
||||
dependencySource: FieldType;
|
||||
commandName: FieldType;
|
||||
dependencyTypeName: FieldType;
|
||||
};
|
||||
/**
|
||||
* Constructs a new instance of the RemoteDependencyData object
|
||||
*/
|
||||
constructor(id: string, absoluteUrl: string, commandName: string, value: number, success: boolean, resultCode: number, method?: string, properties?: Object, measurements?: Object);
|
||||
}
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights {
|
||||
interface XMLHttpRequestInstrumented extends XMLHttpRequest {
|
||||
ajaxData: ajaxRecord;
|
||||
}
|
||||
class AjaxMonitor {
|
||||
private appInsights;
|
||||
private initialized;
|
||||
private static instrumentedByAppInsightsName;
|
||||
private currentWindowHost;
|
||||
constructor(appInsights: Microsoft.ApplicationInsights.AppInsights);
|
||||
private Init();
|
||||
static DisabledPropertyName: string;
|
||||
private isMonitoredInstance(xhr, excludeAjaxDataValidation?);
|
||||
private supportsMonitoring();
|
||||
private instrumentOpen();
|
||||
private openHandler(xhr, method, url, async);
|
||||
private static getFailedAjaxDiagnosticsMessage(xhr);
|
||||
private instrumentSend();
|
||||
private sendHandler(xhr, content);
|
||||
private instrumentAbort();
|
||||
private attachToOnReadyStateChange(xhr);
|
||||
private onAjaxComplete(xhr);
|
||||
private getCorrelationContext(xhr);
|
||||
}
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights {
|
||||
interface ISendBuffer {
|
||||
/**
|
||||
|
@ -2423,26 +2448,6 @@ declare module Microsoft.ApplicationInsights.Telemetry {
|
|||
constructor(pageName: any, pageUrl: any);
|
||||
}
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights {
|
||||
class FetchMonitor {
|
||||
private appInsights;
|
||||
private initialized;
|
||||
static instrumentedByAppInsightsName: string;
|
||||
private currentWindowHost;
|
||||
constructor(appInsights: Microsoft.ApplicationInsights.AppInsights);
|
||||
private Init();
|
||||
static DisabledPropertyName: string;
|
||||
private isMonitoredInstance(input);
|
||||
private supportsMonitoring();
|
||||
private instrumentFetch();
|
||||
private createAjaxRecord(input?, init?);
|
||||
private includeCorrelationHeaders(ajaxData, input?, init?);
|
||||
private static getFailedFetchDiagnosticsMessage(input);
|
||||
private onFetchComplete(response, ajaxData);
|
||||
private onFetchFailed(input, ajaxData, reason);
|
||||
private getCorrelationContext(response);
|
||||
}
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights {
|
||||
class SplitTest {
|
||||
private hashCodeGeneragor;
|
||||
|
@ -2467,7 +2472,6 @@ declare module Microsoft.ApplicationInsights {
|
|||
samplingPercentage?: number;
|
||||
autoTrackPageVisitTime?: boolean;
|
||||
disableAjaxTracking?: boolean;
|
||||
disableFetchTracking?: boolean;
|
||||
overridePageViewDuration?: boolean;
|
||||
maxAjaxCallsPerView?: number;
|
||||
disableDataLossAnalysis?: boolean;
|
||||
|
@ -2646,7 +2650,6 @@ declare module Microsoft.ApplicationInsights {
|
|||
private _pageViewManager;
|
||||
private _pageVisitTimeManager;
|
||||
private _ajaxMonitor;
|
||||
private _fetchMonitor;
|
||||
config: IConfig;
|
||||
context: TelemetryContext;
|
||||
queue: (() => void)[];
|
||||
|
@ -2788,40 +2791,6 @@ declare module Microsoft.ApplicationInsights {
|
|||
_onerror(message: string, url: string, lineNumber: number, columnNumber: number, error: Error): void;
|
||||
}
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights {
|
||||
interface XMLHttpRequestInstrumented extends XMLHttpRequest {
|
||||
ajaxData: ajaxRecord;
|
||||
}
|
||||
class AjaxMonitor {
|
||||
private appInsights;
|
||||
private initialized;
|
||||
private static instrumentedByAppInsightsName;
|
||||
private currentWindowHost;
|
||||
constructor(appInsights: Microsoft.ApplicationInsights.AppInsights);
|
||||
private Init();
|
||||
static DisabledPropertyName: string;
|
||||
private isMonitoredInstance(xhr, excludeAjaxDataValidation?);
|
||||
private supportsMonitoring();
|
||||
private instrumentOpen();
|
||||
private openHandler(xhr, method, url, async);
|
||||
private static getFailedAjaxDiagnosticsMessage(xhr);
|
||||
private instrumentSend();
|
||||
private sendHandler(xhr, content);
|
||||
private instrumentAbort();
|
||||
private attachToOnReadyStateChange(xhr);
|
||||
private onAjaxComplete(xhr);
|
||||
private getCorrelationContext(xhr);
|
||||
}
|
||||
}
|
||||
declare class FetchTests extends TestClass {
|
||||
private appInsightsMock;
|
||||
private trackDependencySpy;
|
||||
testInitialize(): void;
|
||||
testCleanup(): void;
|
||||
registerTests(): void;
|
||||
private testFetchSuccess(responseCode, success);
|
||||
static createFetchStub(responseCode: number, body?: string, timeout?: number): (input?: Request | string, init?: RequestInit) => Promise<Response>;
|
||||
}
|
||||
declare class AppInsightsTests extends TestClass {
|
||||
private getAppInsightsSnippet();
|
||||
testInitialize(): void;
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
/// <reference path="../CheckinTests/Util.tests.ts" />
|
||||
/// <reference path="../CheckinTests/Initialization.tests.ts" />
|
||||
/// <reference path="../CheckinTests/ajax.tests.ts" />
|
||||
/// <reference path="../CheckinTests/fetch.tests.ts" />
|
||||
/// <reference path="../CheckinTests/SplitTest.tests.ts" />
|
||||
/// <reference path="../CheckinTests/CorrelationIdHelper.tests.ts" />
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
/// <reference path="./Telemetry/PageVisitTimeManager.ts"/>
|
||||
/// <reference path="./Telemetry/RemoteDependencyData.ts"/>
|
||||
/// <reference path="./ajax/ajax.ts"/>
|
||||
/// <reference path="./ajax/fetch.ts"/>
|
||||
/// <reference path="./SplitTest.ts"/>
|
||||
/// <reference path="../JavaScriptSDK.Interfaces/IAppInsights.ts"/>
|
||||
|
||||
|
@ -13,7 +12,7 @@ module Microsoft.ApplicationInsights {
|
|||
|
||||
"use strict";
|
||||
|
||||
export var Version = "1.0.19";
|
||||
export var Version = "1.0.20";
|
||||
|
||||
/**
|
||||
* Internal interface to pass appInsights object to subcomponents without coupling
|
||||
|
@ -41,7 +40,6 @@ module Microsoft.ApplicationInsights {
|
|||
private _pageViewManager: Microsoft.ApplicationInsights.Telemetry.PageViewManager;
|
||||
private _pageVisitTimeManager: Microsoft.ApplicationInsights.Telemetry.PageVisitTimeManager;
|
||||
private _ajaxMonitor: Microsoft.ApplicationInsights.AjaxMonitor;
|
||||
private _fetchMonitor: Microsoft.ApplicationInsights.FetchMonitor;
|
||||
|
||||
public config: IConfig;
|
||||
public context: TelemetryContext;
|
||||
|
@ -134,10 +132,6 @@ module Microsoft.ApplicationInsights {
|
|||
if (!this.config.disableAjaxTracking) {
|
||||
this._ajaxMonitor = new Microsoft.ApplicationInsights.AjaxMonitor(this);
|
||||
}
|
||||
|
||||
if (!this.config.disableFetchTracking) {
|
||||
this._fetchMonitor = new Microsoft.ApplicationInsights.FetchMonitor(this);
|
||||
}
|
||||
}
|
||||
|
||||
public sendPageViewInternal(name?: string, url?: string, duration?: number, properties?: Object, measurements?: Object) {
|
||||
|
|
|
@ -163,7 +163,6 @@ module Microsoft.ApplicationInsights {
|
|||
}
|
||||
|
||||
config.disableAjaxTracking = Util.stringToBoolOrDefault(config.disableAjaxTracking);
|
||||
config.disableFetchTracking = Util.stringToBoolOrDefault(config.disableFetchTracking, true);
|
||||
config.maxAjaxCallsPerView = !isNaN(config.maxAjaxCallsPerView) ? config.maxAjaxCallsPerView : 500;
|
||||
|
||||
config.isBeaconApiDisabled = Util.stringToBoolOrDefault(config.isBeaconApiDisabled, true);
|
||||
|
|
|
@ -1,253 +0,0 @@
|
|||
/// <reference path="../Logging.ts" />
|
||||
/// <reference path="../Util.ts" />
|
||||
/// <reference path="./ajaxUtils.ts" />
|
||||
/// <reference path="./ajaxRecord.ts" />
|
||||
/// <reference path="../RequestResponseHeaders.ts" />
|
||||
/// <reference path="../Telemetry/RemoteDependencyData.ts" />
|
||||
/// <reference path="../AppInsights.ts" />
|
||||
|
||||
module Microsoft.ApplicationInsights {
|
||||
"use strict";
|
||||
|
||||
export class FetchMonitor {
|
||||
private appInsights: AppInsights;
|
||||
private initialized: boolean;
|
||||
public static instrumentedByAppInsightsName = "InstrumentedByAppInsights";
|
||||
private currentWindowHost: string;
|
||||
|
||||
constructor(appInsights: Microsoft.ApplicationInsights.AppInsights) {
|
||||
this.currentWindowHost = window.location.host && window.location.host.toLowerCase();
|
||||
this.appInsights = appInsights;
|
||||
this.initialized = false;
|
||||
this.Init();
|
||||
}
|
||||
|
||||
private Init(): void {
|
||||
if (this.supportsMonitoring()) {
|
||||
this.instrumentFetch();
|
||||
this.initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static DisabledPropertyName: string = "Microsoft_ApplicationInsights_BypassFetchInstrumentation";
|
||||
|
||||
private isMonitoredInstance(input: Request | string): boolean {
|
||||
return this.initialized && input[FetchMonitor.DisabledPropertyName] !== true;
|
||||
}
|
||||
|
||||
private supportsMonitoring(): boolean {
|
||||
let result: boolean = true;
|
||||
|
||||
// polyfilled fetch on old browsers (IE) will try to use XMLHttpRequest instead
|
||||
const fetchPolyfill: string = "new XMLHttpRequest";
|
||||
|
||||
if (extensions.IsNullOrUndefined((window as any).Request) ||
|
||||
extensions.IsNullOrUndefined((window as any).Request.prototype) ||
|
||||
extensions.IsNullOrUndefined(window.fetch) ||
|
||||
window.fetch.toString().indexOf(fetchPolyfill) !== -1) {
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private instrumentFetch(): void {
|
||||
let originalFetch: (input?: Request | string, init?: RequestInit) => Promise<Response> = window.fetch;
|
||||
let fetchMonitorInstance: FetchMonitor = this;
|
||||
window.fetch = function fetch(input?: Request | string, init?: RequestInit): Promise<Response> {
|
||||
let ajaxData: ajaxRecord;
|
||||
if (fetchMonitorInstance.isMonitoredInstance(input)) {
|
||||
try {
|
||||
ajaxData = fetchMonitorInstance.createAjaxRecord(input, init);
|
||||
init = fetchMonitorInstance.includeCorrelationHeaders(ajaxData, input, init);
|
||||
} catch (e) {
|
||||
_InternalLogging.throwInternal(
|
||||
LoggingSeverity.CRITICAL,
|
||||
_InternalMessageId.FailedMonitorAjaxOpen,
|
||||
"Failed to monitor Window.fetch, monitoring data for this fetch call may be incorrect.",
|
||||
{
|
||||
ajaxDiagnosticsMessage: FetchMonitor.getFailedFetchDiagnosticsMessage(input),
|
||||
exception: Microsoft.ApplicationInsights.Util.dump(e)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let promise = originalFetch(input, init);
|
||||
if (promise !== null && promise !== undefined) {
|
||||
promise.then(response => {
|
||||
fetchMonitorInstance.onFetchComplete(response, ajaxData);
|
||||
return response;
|
||||
},
|
||||
reason => {
|
||||
fetchMonitorInstance.onFetchFailed(input, ajaxData, reason);
|
||||
throw reason;
|
||||
});
|
||||
}
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
window.fetch[FetchMonitor.instrumentedByAppInsightsName] = true;
|
||||
}
|
||||
|
||||
private createAjaxRecord(input?: Request | string, init?: RequestInit): ajaxRecord {
|
||||
// this format corresponds with activity logic on server-side and is required for the correct correlation
|
||||
let id: string = `|${this.appInsights.context.operation.id}.${Util.newId()}`;
|
||||
let ajaxData: ajaxRecord = new ajaxRecord(id);
|
||||
ajaxData.requestSentTime = dateTime.Now();
|
||||
if (input instanceof Request) {
|
||||
(input as any).ajaxData = ajaxData;
|
||||
ajaxData.requestUrl = input ? input.url : "";
|
||||
} else {
|
||||
ajaxData.requestUrl = input;
|
||||
}
|
||||
if (init && init.method) {
|
||||
ajaxData.method = init.method;
|
||||
} else if (input && input instanceof Request) {
|
||||
ajaxData.method = input.method;
|
||||
} else {
|
||||
ajaxData.method = "GET";
|
||||
}
|
||||
return ajaxData;
|
||||
}
|
||||
|
||||
private includeCorrelationHeaders(ajaxData: ajaxRecord, input?: Request | string, init?: RequestInit) {
|
||||
if (CorrelationIdHelper.canIncludeCorrelationHeader(this.appInsights.config, ajaxData.getAbsoluteUrl(), this.currentWindowHost)) {
|
||||
if (!init) {
|
||||
init = {};
|
||||
}
|
||||
// init headers override original request headers
|
||||
// so, if they exist use only them, otherwise use request's because they should have been applied in the first place
|
||||
// not using original request headers will result in them being lost
|
||||
init.headers = new Headers(init.headers || (input instanceof Request ? (input.headers || {}) : {}));
|
||||
init.headers.set(RequestHeaders.requestIdHeader, ajaxData.id);
|
||||
let appId: string = this.appInsights.context ? this.appInsights.context.appId() : null;
|
||||
if (appId) {
|
||||
init.headers.set(RequestHeaders.requestContextHeader, RequestHeaders.requestContextAppIdFormat + appId);
|
||||
}
|
||||
}
|
||||
return init;
|
||||
}
|
||||
|
||||
private static getFailedFetchDiagnosticsMessage(input: Request | Response | string): string {
|
||||
let result: string = "";
|
||||
try {
|
||||
if (!extensions.IsNullOrUndefined(input)) {
|
||||
if (typeof (input) === "string") {
|
||||
result += `(url: '${input}')`;
|
||||
} else {
|
||||
result += `(url: '${input.url}')`;
|
||||
}
|
||||
}
|
||||
// tslint:disable-next-line:no-empty
|
||||
} catch (e) { }
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private onFetchComplete(response: Response, ajaxData: ajaxRecord): void {
|
||||
if (!ajaxData) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
ajaxData.responseFinishedTime = dateTime.Now();
|
||||
ajaxData.CalculateMetrics();
|
||||
|
||||
if (ajaxData.ajaxTotalDuration < 0) {
|
||||
_InternalLogging.throwInternal(
|
||||
LoggingSeverity.WARNING,
|
||||
_InternalMessageId.FailedMonitorAjaxDur,
|
||||
"Failed to calculate the duration of the fetch call, monitoring data for this fetch call won't be sent.",
|
||||
{
|
||||
fetchDiagnosticsMessage: FetchMonitor.getFailedFetchDiagnosticsMessage(response),
|
||||
requestSentTime: ajaxData.requestSentTime,
|
||||
responseFinishedTime: ajaxData.responseFinishedTime
|
||||
});
|
||||
} else {
|
||||
let dependency: Telemetry.RemoteDependencyData = new Telemetry.RemoteDependencyData(
|
||||
ajaxData.id,
|
||||
ajaxData.getAbsoluteUrl(),
|
||||
ajaxData.getPathName(),
|
||||
ajaxData.ajaxTotalDuration,
|
||||
response.status >= 200 && response.status < 400,
|
||||
response.status,
|
||||
ajaxData.method);
|
||||
|
||||
// enrich dependency target with correlation context from the server
|
||||
let correlationContext: string = this.getCorrelationContext(response);
|
||||
if (correlationContext) {
|
||||
dependency.target = dependency.target + " | " + correlationContext;
|
||||
}
|
||||
|
||||
this.appInsights.trackDependencyData(dependency);
|
||||
}
|
||||
} catch (e) {
|
||||
_InternalLogging.throwInternal(
|
||||
LoggingSeverity.WARNING,
|
||||
_InternalMessageId.FailedMonitorAjaxGetCorrelationHeader,
|
||||
"Failed to calculate the duration of the fetch call, monitoring data for this fetch call won't be sent.",
|
||||
{
|
||||
fetchDiagnosticsMessage: FetchMonitor.getFailedFetchDiagnosticsMessage(response),
|
||||
exception: Microsoft.ApplicationInsights.Util.dump(e)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private onFetchFailed(input: Request | string, ajaxData: ajaxRecord, reason: any): void {
|
||||
if (!ajaxData) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
ajaxData.responseFinishedTime = dateTime.Now();
|
||||
ajaxData.CalculateMetrics();
|
||||
|
||||
if (ajaxData.ajaxTotalDuration < 0) {
|
||||
_InternalLogging.throwInternal(
|
||||
LoggingSeverity.WARNING,
|
||||
_InternalMessageId.FailedMonitorAjaxDur,
|
||||
"Failed to calculate the duration of the failed fetch call, monitoring data for this fetch call won't be sent.",
|
||||
{
|
||||
fetchDiagnosticsMessage: FetchMonitor.getFailedFetchDiagnosticsMessage(input),
|
||||
requestSentTime: ajaxData.requestSentTime,
|
||||
responseFinishedTime: ajaxData.responseFinishedTime
|
||||
});
|
||||
} else {
|
||||
let dependency: Telemetry.RemoteDependencyData = new Telemetry.RemoteDependencyData(
|
||||
ajaxData.id,
|
||||
ajaxData.getAbsoluteUrl(),
|
||||
ajaxData.getPathName(),
|
||||
ajaxData.ajaxTotalDuration,
|
||||
false,
|
||||
0,
|
||||
ajaxData.method);
|
||||
dependency.properties = { error: reason.message };
|
||||
this.appInsights.trackDependencyData(dependency);
|
||||
}
|
||||
} catch (e) {
|
||||
_InternalLogging.throwInternal(
|
||||
LoggingSeverity.WARNING,
|
||||
_InternalMessageId.FailedMonitorAjaxGetCorrelationHeader,
|
||||
"Failed to calculate the duration of the failed fetch call, monitoring data for this fetch call won't be sent.",
|
||||
{
|
||||
fetchDiagnosticsMessage: FetchMonitor.getFailedFetchDiagnosticsMessage(input),
|
||||
exception: Microsoft.ApplicationInsights.Util.dump(e)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private getCorrelationContext(response: Response): string {
|
||||
try {
|
||||
let responseHeader: string = response.headers.get(RequestHeaders.requestContextHeader);
|
||||
return CorrelationIdHelper.getCorrelationContext(responseHeader);
|
||||
} catch (e) {
|
||||
_InternalLogging.throwInternal(
|
||||
LoggingSeverity.WARNING,
|
||||
_InternalMessageId.FailedMonitorAjaxGetCorrelationHeader,
|
||||
"Failed to get Request-Context correlation header as it may be not included in the response or not accessible.",
|
||||
{
|
||||
fetchDiagnosticsMessage: FetchMonitor.getFailedFetchDiagnosticsMessage(response),
|
||||
exception: Microsoft.ApplicationInsights.Util.dump(e)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "applicationinsights-js",
|
||||
"main": "dist/ai.0.js",
|
||||
"version": "1.0.19",
|
||||
"version": "1.0.20",
|
||||
"homepage": "https://github.com/Microsoft/ApplicationInsights-JS",
|
||||
"authors": [
|
||||
"Application Insights <appinsights@microsoft.com>"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "applicationinsights-js",
|
||||
"version": "1.0.19",
|
||||
"version": "1.0.20",
|
||||
"description": "Microsoft Application Insights JavaScript SDK",
|
||||
"main": "bundle/ai.module.js",
|
||||
"keywords": [
|
||||
|
|
Загрузка…
Ссылка в новой задаче