* bug fix - add unload listener and initialize missing config items * remove unnecessary initializations and pass in config to getDefault method * add correlationHeaderExcludePatterns default value * fix test
This commit is contained in:
Родитель
1c39bf97fa
Коммит
ababc00b43
|
@ -485,6 +485,7 @@ export class Initialization implements IApplicationInsights {
|
||||||
// Hook the unload event for the document, window and body to ensure that the client events are flushed to the server
|
// Hook the unload event for the document, window and body to ensure that the client events are flushed to the server
|
||||||
// As just hooking the window does not always fire (on chrome) for page navigations.
|
// As just hooking the window does not always fire (on chrome) for page navigations.
|
||||||
let added = addEventHandler('beforeunload', performHousekeeping);
|
let added = addEventHandler('beforeunload', performHousekeeping);
|
||||||
|
added = addEventHandler('unload', performHousekeeping) || added;
|
||||||
added = addEventHandler('pagehide', performHousekeeping) || added;
|
added = addEventHandler('pagehide', performHousekeeping) || added;
|
||||||
|
|
||||||
// A reactNative app may not have a window and therefore the beforeunload/pagehide events -- so don't
|
// A reactNative app may not have a window and therefore the beforeunload/pagehide events -- so don't
|
||||||
|
|
|
@ -253,7 +253,7 @@ export class ApplicationInsightsTests extends AITestClass {
|
||||||
Assert.equal(12, appInsights.config.samplingPercentage);
|
Assert.equal(12, appInsights.config.samplingPercentage);
|
||||||
Assert.notEqual('aaa', appInsights.config.accountId);
|
Assert.notEqual('aaa', appInsights.config.accountId);
|
||||||
Assert.equal('def', appInsights.config.accountId);
|
Assert.equal('def', appInsights.config.accountId);
|
||||||
Assert.equal(undefined, (appInsights['config'] as IConfiguration).instrumentationKey);
|
Assert.equal('instrumentation_key', (appInsights['config'] as IConfiguration).instrumentationKey);
|
||||||
Assert.equal(30 * 60 * 1000, appInsights.config.sessionRenewalMs);
|
Assert.equal(30 * 60 * 1000, appInsights.config.sessionRenewalMs);
|
||||||
Assert.equal(24 * 60 * 60 * 1000, appInsights.config.sessionExpirationMs);
|
Assert.equal(24 * 60 * 60 * 1000, appInsights.config.sessionExpirationMs);
|
||||||
|
|
||||||
|
@ -262,7 +262,7 @@ export class ApplicationInsightsTests extends AITestClass {
|
||||||
Assert.equal(12, extConfig.samplingPercentage);
|
Assert.equal(12, extConfig.samplingPercentage);
|
||||||
Assert.notEqual('aaa', extConfig.accountId);
|
Assert.notEqual('aaa', extConfig.accountId);
|
||||||
Assert.equal('def', extConfig.accountId);
|
Assert.equal('def', extConfig.accountId);
|
||||||
Assert.equal(undefined, (extConfig as any).instrumentationKey);
|
Assert.equal('instrumentation_key', (extConfig as any).instrumentationKey);
|
||||||
Assert.equal(30 * 60 * 1000, extConfig.sessionRenewalMs);
|
Assert.equal(30 * 60 * 1000, extConfig.sessionRenewalMs);
|
||||||
Assert.equal(24 * 60 * 60 * 1000, extConfig.sessionExpirationMs);
|
Assert.equal(24 * 60 * 60 * 1000, extConfig.sessionExpirationMs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,10 @@ export class ApplicationInsights extends BaseTelemetryPlugin implements IAppInsi
|
||||||
config.enableAutoRouteTracking = stringToBoolOrDefault(config.enableAutoRouteTracking);
|
config.enableAutoRouteTracking = stringToBoolOrDefault(config.enableAutoRouteTracking);
|
||||||
config.namePrefix = config.namePrefix || "";
|
config.namePrefix = config.namePrefix || "";
|
||||||
|
|
||||||
|
config.enableDebug = stringToBoolOrDefault(config.enableDebug);
|
||||||
|
config.disableFlushOnBeforeUnload = stringToBoolOrDefault(config.disableFlushOnBeforeUnload);
|
||||||
|
config.disableFlushOnUnload = stringToBoolOrDefault(config.disableFlushOnUnload, config.disableFlushOnBeforeUnload);
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,7 +502,7 @@ export class ApplicationInsights extends BaseTelemetryPlugin implements IAppInsi
|
||||||
_self.config = ctx.getExtCfg<IConfig>(identifier);
|
_self.config = ctx.getExtCfg<IConfig>(identifier);
|
||||||
|
|
||||||
// load default values if specified
|
// load default values if specified
|
||||||
const defaults: IConfig = ApplicationInsights.getDefaultConfig();
|
const defaults: IConfig = ApplicationInsights.getDefaultConfig(config);
|
||||||
if (defaults !== undefined) {
|
if (defaults !== undefined) {
|
||||||
objForEachKey(defaults, (field, value) => {
|
objForEachKey(defaults, (field, value) => {
|
||||||
// for each unspecified field, set the default value
|
// for each unspecified field, set the default value
|
||||||
|
@ -915,7 +919,7 @@ class Timing {
|
||||||
if (typeof _events[name] !== "undefined") {
|
if (typeof _events[name] !== "undefined") {
|
||||||
logger.throwInternal(
|
logger.throwInternal(
|
||||||
LoggingSeverity.WARNING, _InternalMessageId.StartCalledMoreThanOnce, "start was called more than once for this event without calling stop.",
|
LoggingSeverity.WARNING, _InternalMessageId.StartCalledMoreThanOnce, "start was called more than once for this event without calling stop.",
|
||||||
{ name: name, key: name }, true);
|
{ name, key: name }, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_events[name] = +new Date;
|
_events[name] = +new Date;
|
||||||
|
@ -926,7 +930,7 @@ class Timing {
|
||||||
if (isNaN(start)) {
|
if (isNaN(start)) {
|
||||||
logger.throwInternal(
|
logger.throwInternal(
|
||||||
LoggingSeverity.WARNING, _InternalMessageId.StopCalledWithoutStart, "stop was called without a corresponding start.",
|
LoggingSeverity.WARNING, _InternalMessageId.StopCalledWithoutStart, "stop was called without a corresponding start.",
|
||||||
{ name: name, key: name }, true);
|
{ name, key: name }, true);
|
||||||
} else {
|
} else {
|
||||||
const end = +new Date;
|
const end = +new Date;
|
||||||
const duration = dateTimeUtilsDuration(start, end);
|
const duration = dateTimeUtilsDuration(start, end);
|
||||||
|
|
|
@ -1491,7 +1491,46 @@ export class AjaxTests extends TestClass {
|
||||||
Assert.equal("|", id[0]);
|
Assert.equal("|", id[0]);
|
||||||
Assert.equal(".", id[id.length - 1]);
|
Assert.equal(".", id[id.length - 1]);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
|
this.testCase({
|
||||||
|
name: "Ajax: should not create and pass a traceparent header if correlationHeaderExcludePatterns set to exclude all",
|
||||||
|
test: () => {
|
||||||
|
this._ajax = new AjaxMonitor();
|
||||||
|
let appInsightsCore = new AppInsightsCore();
|
||||||
|
let coreConfig = {
|
||||||
|
instrumentationKey: "instrumentationKey",
|
||||||
|
correlationHeaderExcludePatterns: [/.*/],
|
||||||
|
extensionConfig: {
|
||||||
|
"AjaxDependencyPlugin": {
|
||||||
|
appId: "appId",
|
||||||
|
distributedTracingMode: DistributedTracingModes.AI_AND_W3C
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
appInsightsCore.initialize(coreConfig, [this._ajax, new TestChannelPlugin()]);
|
||||||
|
var trackStub = this.sandbox.stub(appInsightsCore, "track");
|
||||||
|
|
||||||
|
// Use test hook to simulate the correct url location
|
||||||
|
this._ajax["_currentWindowHost"] = "www.example.com";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
var stub = this.sandbox.stub(xhr, "setRequestHeader");
|
||||||
|
xhr.open("GET", "http://www.example.com");
|
||||||
|
xhr.send();
|
||||||
|
|
||||||
|
// Assert that both headers are not sent
|
||||||
|
Assert.equal(false, stub.calledWith(RequestHeaders.requestIdHeader)); // AI
|
||||||
|
Assert.equal(false, stub.calledWith(RequestHeaders.traceParentHeader)); // W3C
|
||||||
|
|
||||||
|
// Emulate response so perf monitoring is cleaned up
|
||||||
|
(<any>xhr).respond(200, {"Content-Type": "application/json; charset=utf-8", "Access-Control-Allow-Origin": "*"}, "");
|
||||||
|
var id = trackStub.args[0][0].baseData.id;
|
||||||
|
Assert.equal("|", id[0]);
|
||||||
|
Assert.equal(".", id[id.length - 1]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.testCase({
|
this.testCase({
|
||||||
name: "Ajax: should create and only pass a traceparent header if w3c is enabled",
|
name: "Ajax: should create and only pass a traceparent header if w3c is enabled",
|
||||||
|
@ -2096,6 +2135,90 @@ export class AjaxPerfTests extends TestClass {
|
||||||
return false;
|
return false;
|
||||||
}, 'response received', 600, 1000) as any)
|
}, 'response received', 600, 1000) as any)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.testCaseAsync({
|
||||||
|
name: "Fetch: should not create and pass correlation header if correlationHeaderExcludePatterns set to exclude all.",
|
||||||
|
stepDelay: 10,
|
||||||
|
timeOut: 10000,
|
||||||
|
steps: [ (done) => {
|
||||||
|
let fetchCalls = hookFetch((resolve) => {
|
||||||
|
TestClass.orgSetTimeout(function() {
|
||||||
|
resolve({
|
||||||
|
headers: new Headers(),
|
||||||
|
ok: true,
|
||||||
|
body: null,
|
||||||
|
bodyUsed: false,
|
||||||
|
redirected: false,
|
||||||
|
status: 200,
|
||||||
|
statusText: "Hello",
|
||||||
|
trailer: null,
|
||||||
|
type: "basic",
|
||||||
|
url: "https://httpbin.org/status/200"
|
||||||
|
});
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
this._ajax = new AjaxMonitor();
|
||||||
|
let appInsightsCore = new AppInsightsCore();
|
||||||
|
let coreConfig = {
|
||||||
|
instrumentationKey: "instrumentationKey",
|
||||||
|
disableFetchTracking: false,
|
||||||
|
disableAjaxTracking: false,
|
||||||
|
correlationHeaderExcludePatterns: [/.*/],
|
||||||
|
extensionConfig: {
|
||||||
|
"AjaxDependencyPlugin": {
|
||||||
|
appId: "appId",
|
||||||
|
distributedTracingMode: DistributedTracingModes.AI_AND_W3C
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
appInsightsCore.initialize(coreConfig, [this._ajax, new TestChannelPlugin()]);
|
||||||
|
let trackSpy = this.sandbox.spy(appInsightsCore, "track")
|
||||||
|
this._context["trackStub"] = trackSpy;
|
||||||
|
|
||||||
|
// Use test hook to simulate the correct url location
|
||||||
|
this._ajax["_currentWindowHost"] = "httpbin.org";
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
let headers = new Headers();
|
||||||
|
headers.append('My-Header', 'Header field');
|
||||||
|
let init = {
|
||||||
|
method: 'get',
|
||||||
|
headers
|
||||||
|
};
|
||||||
|
const url = 'https://httpbin.org/status/200';
|
||||||
|
|
||||||
|
// Act
|
||||||
|
Assert.ok(trackSpy.notCalled, "No fetch called yet");
|
||||||
|
fetch(url, init).then(() => {
|
||||||
|
// Assert
|
||||||
|
Assert.ok(trackSpy.called, "The request was not tracked");
|
||||||
|
Assert.equal(1, fetchCalls.length);
|
||||||
|
Assert.notEqual(undefined, fetchCalls[0].init, "Has init param");
|
||||||
|
let headers:Headers = fetchCalls[0].init.headers as Headers;
|
||||||
|
Assert.equal(true, headers.has("My-Header"), "My-Header should be present");
|
||||||
|
Assert.equal(false, headers.has(RequestHeaders.requestIdHeader), "Correlation header - AI header should be excluded"); // AI
|
||||||
|
Assert.equal(false, headers.has(RequestHeaders.traceParentHeader), "Correlation header - W3c header should be excluded"); // W3C
|
||||||
|
}, () => {
|
||||||
|
Assert.ok(false, "fetch failed!");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}]
|
||||||
|
.concat(PollingAssert.createPollingAssert(() => {
|
||||||
|
let trackStub = this._context["trackStub"] as SinonStub;
|
||||||
|
if (trackStub.called) {
|
||||||
|
Assert.ok(trackStub.calledOnce, "track is called");
|
||||||
|
let data = trackStub.args[0][0].baseData;
|
||||||
|
Assert.equal("Fetch", data.type, "request is Fatch type");
|
||||||
|
var id = data.id;
|
||||||
|
Assert.equal("|", id[0]);
|
||||||
|
Assert.equal(".", id[id.length - 1]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}, 'response received', 60, 1000) as any)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -163,6 +163,7 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu
|
||||||
"*.blob.core.cloudapi.de",
|
"*.blob.core.cloudapi.de",
|
||||||
"*.blob.core.usgovcloudapi.net"],
|
"*.blob.core.usgovcloudapi.net"],
|
||||||
correlationHeaderDomains: undefined,
|
correlationHeaderDomains: undefined,
|
||||||
|
correlationHeaderExcludePatterns: undefined,
|
||||||
appId: undefined,
|
appId: undefined,
|
||||||
enableCorsCorrelation: false,
|
enableCorsCorrelation: false,
|
||||||
enableRequestHeaderTracking: false,
|
enableRequestHeaderTracking: false,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче