Parse appId from Breeze reponse and pass it as Request-Context (#575)
* Parse appId from Breeze reponse and pass it as Request-Context * Fix unit tests * Exposing appId in the config
This commit is contained in:
Родитель
f43350b03a
Коммит
0c1baa3ea8
|
@ -315,8 +315,9 @@ interface IConfig {
|
|||
// Default: false
|
||||
isStorageUseDisabled: boolean;
|
||||
|
||||
// Default true. If false, the SDK will add two headers ('x-ms-request-root-id' and 'x-ms-request-id)
|
||||
// to all dependency requests (within the same domain) to correlate them with corresponding requests on the server side.
|
||||
// If false, the SDK will add two headers ('Request-Id' and 'Request-Context') to all
|
||||
// dependency requests to correlate them with corresponding requests on the server side.
|
||||
// Default false.
|
||||
disableCorrelationHeaders: boolean;
|
||||
|
||||
// If true, the SDK will send all telemetry using [Beacon API](https://www.w3.org/TR/beacon/)
|
||||
|
@ -332,6 +333,11 @@ interface IConfig {
|
|||
// If true, the SDK will track all [Browser Link](https://docs.microsoft.com/en-us/aspnet/core/client-side/using-browserlink) requests.
|
||||
// Default: false
|
||||
isBrowserLinkTrackingEnabled: boolean;
|
||||
|
||||
// AppId is used for the correlation between AJAX dependencies happening on the client-side with the server-side requests.
|
||||
// When Beacon API is enabled it can not be used automatically, but can be set manually in the configuration.
|
||||
// Default: null
|
||||
appId: string;
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -34,5 +34,6 @@
|
|||
isBeaconApiDisabled?: boolean;
|
||||
sdkExtension?: string;
|
||||
isBrowserLinkTrackingEnabled?: boolean;
|
||||
appId?: string;
|
||||
}
|
||||
}
|
|
@ -516,7 +516,8 @@ class SessionContextTests extends TestClass {
|
|||
isRetryDisabled: () => null,
|
||||
isBeaconApiDisabled: () => null,
|
||||
sdkExtension: () => null,
|
||||
isBrowserLinkTrackingEnabled: () => null
|
||||
isBrowserLinkTrackingEnabled: () => null,
|
||||
appId: () => null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -413,7 +413,8 @@ class UserContextTests extends TestClass {
|
|||
isRetryDisabled: () => null,
|
||||
isBeaconApiDisabled: () => null,
|
||||
sdkExtension: () => null,
|
||||
isBrowserLinkTrackingEnabled: () => null
|
||||
isBrowserLinkTrackingEnabled: () => null,
|
||||
appId: () => null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -162,7 +162,7 @@ class SenderTests extends TestClass {
|
|||
|
||||
// verify
|
||||
this.requestAsserts();
|
||||
this.fakeServer.requests.pop().respond(200, { "Content-Type": "application/json" }, '{"test":"success"}');
|
||||
this.fakeServer.requests.pop().respond(200, { "Content-Type": "application/json" }, '{"itemsReceived": 1, "itemsAccepted": 1, "errors": []}');
|
||||
this.successAsserts(sender);
|
||||
this.logAsserts(0);
|
||||
sender.successSpy.reset();
|
||||
|
@ -175,9 +175,9 @@ class SenderTests extends TestClass {
|
|||
|
||||
// verify
|
||||
this.requestAsserts();
|
||||
this.fakeServer.requests.pop().respond(404, { "Content-Type": "application/json" }, 'some_error');
|
||||
this.fakeServer.requests[0].respond(404, { "Content-Type": "application/json" }, '{"itemsReceived": 1, "itemsAccepted": 0, "errors": [{ "index": 0, "statusCode": 404, "message": "Not found" }]}');
|
||||
this.errorAsserts(sender);
|
||||
this.logAsserts(1, "message:XMLHttpRequest,Status:404,Response:some_error");
|
||||
this.logAsserts(1, "message:XMLHttpRequest,Status:404");
|
||||
sender.successSpy.reset();
|
||||
sender.errorSpy.reset();
|
||||
}
|
||||
|
@ -228,9 +228,9 @@ class SenderTests extends TestClass {
|
|||
|
||||
// verify
|
||||
this.requestAsserts();
|
||||
this.fakeServer.requests[0].respond(404, { "Content-Type": "application/json" }, '400');
|
||||
this.fakeServer.requests[0].respond(404, { "Content-Type": "application/json" }, '{ "itemsReceived": 1, "itemsAccepted": 0, "errors": [{ "index": 0, "statusCode": 404, "message": "Not found" }]}');
|
||||
this.errorAsserts(sender);
|
||||
this.logAsserts(1, "message:XDomainRequest,Response:400");
|
||||
this.logAsserts(1, "message:partial success 0 of 1");
|
||||
sender.successSpy.reset();
|
||||
sender.errorSpy.reset();
|
||||
}
|
||||
|
@ -725,6 +725,84 @@ class SenderTests extends TestClass {
|
|||
}
|
||||
});
|
||||
|
||||
this.testCase({
|
||||
name: "SenderTests: XMLHttpRequest sender successfully parses appId from the response.",
|
||||
test: () => {
|
||||
// setup
|
||||
XMLHttpRequest = <any>(() => {
|
||||
var xhr = new this.xhr;
|
||||
xhr.withCredentials = false;
|
||||
return xhr;
|
||||
});
|
||||
|
||||
var sender = this.getSender();
|
||||
Assert.ok(sender, "sender was constructed. Testing response code: 200");
|
||||
|
||||
this.fakeServer.requests.pop();
|
||||
sender.send(this.testTelemetry);
|
||||
|
||||
Assert.equal(1, sender._buffer.count(), "Buffer has one item");
|
||||
|
||||
// trigger send
|
||||
this.clock.tick(sender._config.maxBatchInterval());
|
||||
|
||||
this.requestAsserts();
|
||||
this.fakeServer.requests.pop().respond(
|
||||
200,
|
||||
{ "Content-Type": "application/json" },
|
||||
'{ "itemsReceived": 1, "itemsAccepted": 1, "errors": [], "appId": "C16FBA4D-ECE9-472E-8125-4FF5BEFAF8C1" }'
|
||||
);
|
||||
|
||||
// verify
|
||||
Assert.ok(sender.successSpy.called, "success was invoked");
|
||||
Assert.ok(sender.errorSpy.notCalled, "error was not invoked");
|
||||
|
||||
Assert.equal("C16FBA4D-ECE9-472E-8125-4FF5BEFAF8C1", sender._appId, "App Id was parsed.");
|
||||
|
||||
// clean up
|
||||
this.testCleanup();
|
||||
}
|
||||
});
|
||||
|
||||
this.testCase({
|
||||
name: "SenderTests: XMLHttpRequest sender does not store appId from the response if it's not returned.",
|
||||
test: () => {
|
||||
// setup
|
||||
XMLHttpRequest = <any>(() => {
|
||||
var xhr = new this.xhr;
|
||||
xhr.withCredentials = false;
|
||||
return xhr;
|
||||
});
|
||||
|
||||
var sender = this.getSender();
|
||||
Assert.ok(sender, "sender was constructed. Testing response code: 200");
|
||||
|
||||
this.fakeServer.requests.pop();
|
||||
sender.send(this.testTelemetry);
|
||||
|
||||
Assert.equal(1, sender._buffer.count(), "Buffer has one item");
|
||||
|
||||
// trigger send
|
||||
this.clock.tick(sender._config.maxBatchInterval());
|
||||
|
||||
this.requestAsserts();
|
||||
this.fakeServer.requests.pop().respond(
|
||||
200,
|
||||
{ "Content-Type": "application/json" },
|
||||
'{ "itemsReceived": 1, "itemsAccepted": 1, "errors": [] }'
|
||||
);
|
||||
|
||||
// verify
|
||||
Assert.ok(sender.successSpy.called, "success was invoked");
|
||||
Assert.ok(sender.errorSpy.notCalled, "error was not invoked");
|
||||
|
||||
Assert.equal(null, sender._appId, "App Id was not parsed.");
|
||||
|
||||
// clean up
|
||||
this.testCleanup();
|
||||
}
|
||||
});
|
||||
|
||||
this.testCase({
|
||||
name: "SenderTests: XMLHttpRequest sender does NOT retry on non-retriable response code from the backend.",
|
||||
test: () => {
|
||||
|
|
|
@ -26,7 +26,8 @@ class TelemetryContextTests extends TestClass {
|
|||
isRetryDisabled: () => false,
|
||||
isBeaconApiDisabled: () => true,
|
||||
sdkExtension: () => null,
|
||||
isBrowserLinkTrackingEnabled: () => false
|
||||
isBrowserLinkTrackingEnabled: () => false,
|
||||
appId: () => undefined,
|
||||
}
|
||||
|
||||
this._telemetryContext = new Microsoft.ApplicationInsights.TelemetryContext(this._config);
|
||||
|
|
|
@ -11,7 +11,8 @@ class AjaxTests extends TestClass {
|
|||
context: {
|
||||
operation: {
|
||||
id: "asdf"
|
||||
}
|
||||
},
|
||||
appId: () => "someid"
|
||||
},
|
||||
config: {
|
||||
disableCorrelationHeaders: false
|
||||
|
|
|
@ -31,7 +31,8 @@ class AppInsightsTests extends TestClass {
|
|||
isCookieUseDisabled: false,
|
||||
isRetryDisabled: false,
|
||||
isStorageUseDisabled: false,
|
||||
isBeaconApiDisabled: true
|
||||
isBeaconApiDisabled: true,
|
||||
appId: undefined
|
||||
};
|
||||
|
||||
// set default values
|
||||
|
@ -175,6 +176,28 @@ class AppInsightsTests extends TestClass {
|
|||
}
|
||||
});
|
||||
|
||||
this.testCase({
|
||||
name: "AppInsightsTests: appId is propagated from the config",
|
||||
test: () => {
|
||||
var expectedAppId = "BDC8736D-D8E8-4B69-B19B-B0CE6B66A456";
|
||||
|
||||
// setup
|
||||
var config = this.getAppInsightsSnippet();
|
||||
config.appId = expectedAppId;
|
||||
var appInsights = new Microsoft.ApplicationInsights.AppInsights(config);
|
||||
var trackStub = this.sandbox.stub(appInsights.context._sender, "send");
|
||||
this.clock.tick(60000);
|
||||
|
||||
Assert.equal(expectedAppId, appInsights.context._sender._appId);
|
||||
|
||||
// act
|
||||
appInsights.trackEvent("testEvent");
|
||||
|
||||
// verify
|
||||
Assert.equal(expectedAppId, appInsights.context._sender._appId);
|
||||
}
|
||||
});
|
||||
|
||||
this.testCase({
|
||||
name: "AppInsightsTests: application context is applied",
|
||||
test: () => {
|
||||
|
@ -1710,13 +1733,14 @@ class AppInsightsTests extends TestClass {
|
|||
});
|
||||
|
||||
this.testCase({
|
||||
name: "Ajax - Request-Id is set and passed correctly",
|
||||
name: "Ajax - Request-Context is not set if appId was not set",
|
||||
test: () => {
|
||||
var snippet = this.getAppInsightsSnippet();
|
||||
snippet.disableAjaxTracking = false;
|
||||
snippet.disableCorrelationHeaders = false;
|
||||
snippet.maxBatchInterval = 0;
|
||||
var appInsights = new Microsoft.ApplicationInsights.AppInsights(snippet);
|
||||
|
||||
var 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");
|
||||
|
@ -1733,7 +1757,40 @@ class AppInsightsTests extends TestClass {
|
|||
(<any>xhr).respond("200", {}, "");
|
||||
|
||||
// Assert
|
||||
Assert.equal(expectedAjaxId, (<any>xhr).requestHeaders['Request-Id'], "Request-Id id set correctly");
|
||||
Assert.equal(expectedAjaxId, (<any>xhr).requestHeaders['Request-Id'], "Request-Id is set correctly");
|
||||
Assert.equal(null, (<any>xhr).requestHeaders['Request-Context'], "Request-Context is not set");
|
||||
Assert.equal(expectedAjaxId, trackStub.args[0][0].id, "ajax id passed to trackAjax correctly");
|
||||
}
|
||||
});
|
||||
|
||||
this.testCase({
|
||||
name: "Ajax - Request-Id and Request-Context are set and passed correctly",
|
||||
test: () => {
|
||||
var snippet = this.getAppInsightsSnippet();
|
||||
snippet.disableAjaxTracking = false;
|
||||
snippet.disableCorrelationHeaders = false;
|
||||
snippet.maxBatchInterval = 0;
|
||||
var appInsights = new Microsoft.ApplicationInsights.AppInsights(snippet);
|
||||
appInsights.context.appId = () => "C16FBA4D-ECE9-472E-8125-4FF5BEFAF8C1";
|
||||
|
||||
var 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");
|
||||
|
||||
// Act
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/bla");
|
||||
xhr.send();
|
||||
|
||||
var expectedAjaxId = (<any>xhr).ajaxData.id;
|
||||
Assert.ok(expectedAjaxId.length > 0, "ajax id was initialized");
|
||||
|
||||
// Emulate response
|
||||
(<any>xhr).respond("200", {}, "");
|
||||
|
||||
// Assert
|
||||
Assert.equal(expectedAjaxId, (<any>xhr).requestHeaders['Request-Id'], "Request-Id is set correctly");
|
||||
Assert.equal("appId=cid-v1:C16FBA4D-ECE9-472E-8125-4FF5BEFAF8C1", (<any>xhr).requestHeaders['Request-Context'], "Request-Context is set correctly");
|
||||
Assert.equal(expectedAjaxId, trackStub.args[0][0].id, "ajax id passed to trackAjax correctly");
|
||||
}
|
||||
});
|
||||
|
@ -1772,13 +1829,16 @@ class AppInsightsTests extends TestClass {
|
|||
});
|
||||
|
||||
this.testCase({
|
||||
name: "Ajax - disableCorrelationHeaders disables Request-Id header",
|
||||
name: "Ajax - disableCorrelationHeaders disables Request-Id and Request-Context headers",
|
||||
test: () => {
|
||||
var snippet = this.getAppInsightsSnippet();
|
||||
snippet.disableAjaxTracking = false;
|
||||
snippet.disableCorrelationHeaders = true;
|
||||
snippet.maxBatchInterval = 0;
|
||||
|
||||
var appInsights = new Microsoft.ApplicationInsights.AppInsights(snippet);
|
||||
appInsights.context.appId = () => "C16FBA4D-ECE9-472E-8125-4FF5BEFAF8C1";
|
||||
|
||||
var 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");
|
||||
|
@ -1793,11 +1853,12 @@ class AppInsightsTests extends TestClass {
|
|||
|
||||
// Assert
|
||||
Assert.equal(null, (<any>xhr).requestHeaders['Request-Id'], "Request-Id header is not set.");
|
||||
Assert.equal(null, (<any>xhr).requestHeaders['Request-Context'], "Request-Context header is not set.");
|
||||
}
|
||||
});
|
||||
|
||||
this.testCase({
|
||||
name: "Ajax - Request-Id header is disabled for excluded domain",
|
||||
name: "Ajax - Request-Id and Request-Context headers are disabled for excluded domain",
|
||||
test: () => {
|
||||
var snippet = this.getAppInsightsSnippet();
|
||||
snippet.disableAjaxTracking = false;
|
||||
|
@ -1819,6 +1880,7 @@ class AppInsightsTests extends TestClass {
|
|||
|
||||
// Assert
|
||||
Assert.equal(null, (<any>xhr).requestHeaders['Request-Id'], "Request-Id header is not set.");
|
||||
Assert.equal(null, (<any>xhr).requestHeaders['Request-Context'], "Request-Context header is not set.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1272,10 +1272,23 @@ declare module Microsoft.ApplicationInsights {
|
|||
* 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;
|
||||
}
|
||||
}
|
||||
declare module Microsoft.Telemetry {
|
||||
|
@ -1613,6 +1626,10 @@ declare module Microsoft.ApplicationInsights {
|
|||
* List of errors for items which were not accepted
|
||||
*/
|
||||
errors: IResponseError[];
|
||||
/**
|
||||
* App id returned by the backend - not necessary returned, but we don't need it with each response.
|
||||
*/
|
||||
appId?: string;
|
||||
}
|
||||
class Sender {
|
||||
/**
|
||||
|
@ -1639,6 +1656,10 @@ declare module Microsoft.ApplicationInsights {
|
|||
* The configuration for this sender instance
|
||||
*/
|
||||
_config: ISenderConfig;
|
||||
/**
|
||||
* AppId of this component parsed from some backend response.
|
||||
*/
|
||||
_appId: string;
|
||||
/**
|
||||
* A method which will cause data to be send to the url
|
||||
*/
|
||||
|
@ -1708,12 +1729,16 @@ declare module Microsoft.ApplicationInsights {
|
|||
*
|
||||
* Note: XDomainRequest does not support sync requests. This 'isAsync' parameter is added
|
||||
* to maintain consistency with the xhrSender's contract
|
||||
* Note: XDomainRequest does not support custom headers and we are not able to get
|
||||
* appId from the backend for the correct correlation.
|
||||
*/
|
||||
private _xdrSender(payload, isAsync);
|
||||
/**
|
||||
* Send Beacon API request
|
||||
* @param payload {string} - The data payload to be sent.
|
||||
* @param isAsync {boolean} - not used
|
||||
* Note: Beacon API does not support custom headers and we are not able to get
|
||||
* appId from the backend for the correct correlation.
|
||||
*/
|
||||
private _beaconSender(payload, isAsync);
|
||||
/**
|
||||
|
@ -2223,6 +2248,7 @@ declare module Microsoft.ApplicationInsights {
|
|||
cookieDomain: () => string;
|
||||
sdkExtension: () => string;
|
||||
isBrowserLinkTrackingEnabled: () => boolean;
|
||||
appId: () => string;
|
||||
}
|
||||
class TelemetryContext implements ITelemetryContext {
|
||||
/**
|
||||
|
@ -2259,6 +2285,10 @@ declare module Microsoft.ApplicationInsights {
|
|||
* The object describing a session tracked by this object.
|
||||
*/
|
||||
session: Context.Session;
|
||||
/**
|
||||
* AppId of this component if returned by the backend.
|
||||
*/
|
||||
appId: () => string;
|
||||
/**
|
||||
* The array of telemetry initializers to call before sending each telemetry item.
|
||||
*/
|
||||
|
@ -2426,6 +2456,7 @@ declare module Microsoft.ApplicationInsights {
|
|||
isBeaconApiDisabled?: boolean;
|
||||
sdkExtension?: string;
|
||||
isBrowserLinkTrackingEnabled?: boolean;
|
||||
appId?: string;
|
||||
}
|
||||
}
|
||||
declare module Microsoft.ApplicationInsights {
|
||||
|
|
|
@ -85,7 +85,8 @@ module Microsoft.ApplicationInsights {
|
|||
isRetryDisabled: () => this.config.isRetryDisabled,
|
||||
isBeaconApiDisabled: () => this.config.isBeaconApiDisabled,
|
||||
sdkExtension: () => this.config.sdkExtension,
|
||||
isBrowserLinkTrackingEnabled: () => this.config.isBrowserLinkTrackingEnabled
|
||||
isBrowserLinkTrackingEnabled: () => this.config.isBrowserLinkTrackingEnabled,
|
||||
appId: () => this.config.appId,
|
||||
}
|
||||
|
||||
if (this.config.isCookieUseDisabled) {
|
||||
|
|
|
@ -5,7 +5,7 @@ module Microsoft.ApplicationInsights {
|
|||
/**
|
||||
* Request-Context header
|
||||
*/
|
||||
public static requestContextHeader = "request-context";
|
||||
public static requestContextHeader = "Request-Context";
|
||||
|
||||
/**
|
||||
* Target instrumentation header that is added to the response and retrieved by the
|
||||
|
@ -13,9 +13,25 @@ module Microsoft.ApplicationInsights {
|
|||
*/
|
||||
public static requestContextTargetKey = "appId";
|
||||
|
||||
/**
|
||||
* Request-Context appId format
|
||||
*/
|
||||
public static requestContextAppIdFormat = "appId=cid-v1:";
|
||||
|
||||
/**
|
||||
* Request-Id header
|
||||
*/
|
||||
public static requestIdHeader = "Request-Id";
|
||||
|
||||
/**
|
||||
* Sdk-Context header
|
||||
* If this header passed with appId in content then appId will be returned back by the backend.
|
||||
*/
|
||||
public static sdkContextHeader = "Sdk-Context";
|
||||
|
||||
/**
|
||||
* String to pass in header for requesting appId back from the backend.
|
||||
*/
|
||||
public static sdkContextHeaderAppIdRequest = "appId";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,6 +89,11 @@ module Microsoft.ApplicationInsights {
|
|||
* List of errors for items which were not accepted
|
||||
*/
|
||||
errors: IResponseError[];
|
||||
|
||||
/**
|
||||
* App id returned by the backend - not necessary returned, but we don't need it with each response.
|
||||
*/
|
||||
appId?: string;
|
||||
}
|
||||
|
||||
export class Sender {
|
||||
|
@ -122,6 +127,11 @@ module Microsoft.ApplicationInsights {
|
|||
*/
|
||||
public _config: ISenderConfig;
|
||||
|
||||
/**
|
||||
* AppId of this component parsed from some backend response.
|
||||
*/
|
||||
public _appId: string;
|
||||
|
||||
/**
|
||||
* A method which will cause data to be send to the url
|
||||
*/
|
||||
|
@ -388,6 +398,7 @@ module Microsoft.ApplicationInsights {
|
|||
xhr[AjaxMonitor.DisabledPropertyName] = true;
|
||||
xhr.open("POST", this._config.endpointUrl(), isAsync);
|
||||
xhr.setRequestHeader("Content-type", "application/json");
|
||||
xhr.setRequestHeader(RequestHeaders.sdkContextHeader, RequestHeaders.sdkContextHeaderAppIdRequest);
|
||||
xhr.onreadystatechange = () => this._xhrReadyStateChange(xhr, payload, payload.length);
|
||||
xhr.onerror = (event: ErrorEvent) => this._onError(payload, this._formatErrorMessageXhr(xhr), event);
|
||||
|
||||
|
@ -405,6 +416,8 @@ module Microsoft.ApplicationInsights {
|
|||
*
|
||||
* Note: XDomainRequest does not support sync requests. This 'isAsync' parameter is added
|
||||
* to maintain consistency with the xhrSender's contract
|
||||
* Note: XDomainRequest does not support custom headers and we are not able to get
|
||||
* appId from the backend for the correct correlation.
|
||||
*/
|
||||
private _xdrSender(payload: string[], isAsync: boolean) {
|
||||
var xdr = new XDomainRequest();
|
||||
|
@ -438,6 +451,8 @@ module Microsoft.ApplicationInsights {
|
|||
* Send Beacon API request
|
||||
* @param payload {string} - The data payload to be sent.
|
||||
* @param isAsync {boolean} - not used
|
||||
* Note: Beacon API does not support custom headers and we are not able to get
|
||||
* appId from the backend for the correct correlation.
|
||||
*/
|
||||
private _beaconSender(payload: string[], isAsync: boolean) {
|
||||
var url = this._config.endpointUrl();
|
||||
|
@ -462,6 +477,14 @@ module Microsoft.ApplicationInsights {
|
|||
*/
|
||||
public _xhrReadyStateChange(xhr: XMLHttpRequest, payload: string[], countOfItemsInPayload: number) {
|
||||
if (xhr.readyState === 4) {
|
||||
var response: IBackendResponse = null;
|
||||
if (!this._appId) {
|
||||
response = this._parseResponse(xhr.responseText || xhr.response);
|
||||
if (response && response.appId) {
|
||||
this._appId = response.appId;
|
||||
}
|
||||
}
|
||||
|
||||
if ((xhr.status < 200 || xhr.status >= 300) && xhr.status !== 0) {
|
||||
if (!this._config.isRetryDisabled() && this._isRetriable(xhr.status)) {
|
||||
this._resendPayload(payload);
|
||||
|
@ -475,7 +498,9 @@ module Microsoft.ApplicationInsights {
|
|||
}
|
||||
} else {
|
||||
if (xhr.status === 206) {
|
||||
var response = this._parseResponse(xhr.responseText || xhr.response);
|
||||
if (!response) {
|
||||
response = this._parseResponse(xhr.responseText || xhr.response);
|
||||
}
|
||||
|
||||
if (response && !this._config.isRetryDisabled()) {
|
||||
this._onPartialSuccess(payload, response);
|
||||
|
|
|
@ -20,6 +20,7 @@ module Microsoft.ApplicationInsights {
|
|||
cookieDomain: () => string;
|
||||
sdkExtension: () => string;
|
||||
isBrowserLinkTrackingEnabled: () => boolean;
|
||||
appId: () => string;
|
||||
}
|
||||
|
||||
export class TelemetryContext implements ITelemetryContext {
|
||||
|
@ -67,6 +68,11 @@ module Microsoft.ApplicationInsights {
|
|||
*/
|
||||
public session: Context.Session;
|
||||
|
||||
/**
|
||||
* AppId of this component if returned by the backend.
|
||||
*/
|
||||
public appId: () => string;
|
||||
|
||||
/**
|
||||
* The array of telemetry initializers to call before sending each telemetry item.
|
||||
*/
|
||||
|
@ -80,6 +86,13 @@ module Microsoft.ApplicationInsights {
|
|||
constructor(config: ITelemetryConfig) {
|
||||
this._config = config;
|
||||
this._sender = new Sender(config);
|
||||
this.appId = () => this._sender._appId;
|
||||
|
||||
// use appId set in config instead of getting it from the backend
|
||||
if (config.appId()) {
|
||||
this._sender._appId = config.appId();
|
||||
}
|
||||
|
||||
this.telemetryInitializers = [];
|
||||
|
||||
// window will be undefined in node.js where we do not want to initialize contexts
|
||||
|
|
|
@ -159,6 +159,12 @@ module Microsoft.ApplicationInsights {
|
|||
|
||||
if (CorrelationIdHelper.canIncludeCorrelationHeader(this.appInsights.config, xhr.ajaxData.getAbsoluteUrl())) {
|
||||
xhr.setRequestHeader(RequestHeaders.requestIdHeader, xhr.ajaxData.id);
|
||||
if (this.appInsights.context) {
|
||||
var appId = this.appInsights.context.appId();
|
||||
if (appId) {
|
||||
xhr.setRequestHeader(RequestHeaders.requestContextHeader, RequestHeaders.requestContextAppIdFormat + appId);
|
||||
}
|
||||
}
|
||||
}
|
||||
xhr.ajaxData.xhrMonitoringState.sendDone = true;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче