applicationinsights-js
Advanced tools
Comparing version 0.21.5 to 0.22.8
@@ -56,2 +56,25 @@ <properties | ||
### startTrackPage | ||
startTrackPage(name?: string) | ||
Starts the timer for tracking a page view. Use this instead of ```trackPageView``` if you want to control when the page view timer starts and stops, but don't want to calculate the duration yourself. This method doesn't send any telemetry. Call ```stopTrackPage``` to log the end of the page view and send the event. | ||
| | | ||
---|---|--- | ||
`name` | The name used to identify the page in the portal. Defaults to the document title. | ||
### stopTrackPage | ||
stopTrackPage(name?: string, url?: string, properties?: Object, measurements?: Object) | ||
Stops the timer that was started by calling ```startTrackPage``` and sends the page view telemetry with the specified properties and measurements. The duration of the page view will be the time between calling ```startTrackPage``` and ```stopTrackPage```. | ||
| | | ||
---|---|--- | ||
`name` | The name used to identify the page in the portal. Defaults to the document title. | ||
`url` | A relative or absolute URL that identifies the page or similar item. Defaults to the window location. | ||
`properties` | Map of string to string: Additional data used to [filter pages](https://azure.microsoft.com/documentation/articles/app-insights-api-custom-events-metrics/#properties) in the portal. Defaults to empty. | ||
`measurements` | Map of string to number: Metrics associated with this page, displayed in Metrics Explorer on the portal. Defaults to empty. | ||
### trackEvent | ||
@@ -180,3 +203,2 @@ | ||
accountId: string; | ||
appUserId: string; | ||
@@ -216,3 +238,4 @@ // A session is logged if the user is inactive for this time in milliseconds. Default 30 mins. | ||
// If true, default behavior of trackPageView is changed to record end of page view duration interval when | ||
// trackPageView is called. | ||
// trackPageView is called. If false and no custom duration is provided to trackPageView, the page view | ||
// performance is calculated using the navigation timing API. | ||
overridePageViewDuration: boolean; | ||
@@ -223,2 +246,5 @@ | ||
maxAjaxCallsPerView: number; | ||
// Custom cookie domain. This is helpful if you want to share Application Insights cookies across subdomains. | ||
cookieDomain: string; | ||
} | ||
@@ -344,7 +370,10 @@ | ||
public addTelemetryInitializer(telemetryInitializer: (envelope: Telemetry.Common.Envelope) => void) | ||
public addTelemetryInitializer(telemetryInitializer: (envelope: Telemetry.Common.Envelope) => boolean) | ||
Adds telemetry initializer to the collection. Telemetry initializers will be called one by one | ||
before telemetry item is pushed for sending and in the order they were added. | ||
before telemetry item is pushed for sending and in the order they were added. | ||
If one of telemetry initializers returns false then telemetry item will not be sent. | ||
If one of telemetry initializers throws an error then telemetry item will not be sent. | ||
#### Example | ||
@@ -351,0 +380,0 @@ |
{ | ||
"name": "applicationinsights-js", | ||
"version": "0.21.5", | ||
"main": "dist/ai.0.js", | ||
"version": "0.22.8", | ||
"homepage": "https://github.com/Microsoft/ApplicationInsights-JS", | ||
@@ -5,0 +6,0 @@ "authors": [ |
@@ -7,3 +7,13 @@ /// <reference path="..\TestFramework\Common.ts" /> | ||
private appInsightsMock = { trackAjax: (absoluteUrl: string, isAsync: boolean, totalTime: number, success: boolean) => { } } | ||
private appInsightsMock = { | ||
trackAjax: (id: string, absoluteUrl: string, isAsync: boolean, totalTime: number, success: boolean) => { }, | ||
context: { | ||
operation: { | ||
id: "asdf" | ||
} | ||
}, | ||
config: { | ||
disableCorrelationHeaders: false | ||
} | ||
} | ||
private trackAjaxSpy; | ||
@@ -105,3 +115,3 @@ private callbackSpy; | ||
// Assert | ||
Assert.equal(true, this.trackAjaxSpy.args[0][3], "TrackAjax should receive true as a 'success' argument"); | ||
Assert.equal(true, this.trackAjaxSpy.args[0][4], "TrackAjax should receive true as a 'success' argument"); | ||
@@ -125,3 +135,3 @@ } | ||
// Assert | ||
Assert.equal(false, this.trackAjaxSpy.args[0][3], "TrackAjax should receive false as a 'success' argument"); | ||
Assert.equal(false, this.trackAjaxSpy.args[0][4], "TrackAjax should receive false as a 'success' argument"); | ||
@@ -232,7 +242,7 @@ } | ||
Assert.ok(this.trackAjaxSpy.calledOnce, "TrackAjax should be called"); | ||
Assert.equal(expectedResponseDuration, this.trackAjaxSpy.args[0][2], "Ajax duration should match expected duration"); | ||
Assert.equal(expectedResponseDuration, this.trackAjaxSpy.args[0][3], "Ajax duration should match expected duration"); | ||
} finally { | ||
window.performance = initialPerformance; | ||
} | ||
} | ||
} | ||
}); | ||
@@ -294,5 +304,5 @@ | ||
// Assert | ||
Assert.equal(success, this.trackAjaxSpy.args[0][3], "TrackAjax should receive " + success + " as a 'success' argument"); | ||
Assert.equal(success, this.trackAjaxSpy.args[0][4], "TrackAjax should receive " + success + " as a 'success' argument"); | ||
} | ||
} | ||
new AjaxTests().registerTests(); |
@@ -124,2 +124,32 @@ /// <reference path="../../../JavaScriptSDK/appInsights.ts" /> | ||
}); | ||
this.testCase({ | ||
name: "Sampling: actual sampling rate should fall into 5% error range", | ||
test: () => { | ||
// setup | ||
var errorRange = 5; | ||
var totalItems = 1000; | ||
var ids = []; | ||
for (var i = 0; i < totalItems; ++i) { | ||
ids.push(Microsoft.ApplicationInsights.Util.newId()); | ||
} | ||
var sampleRates = [50, 33, 25, 20, 16, 10]; | ||
// act | ||
sampleRates.forEach((sampleRate) => { | ||
var sut = new Microsoft.ApplicationInsights.HashCodeScoreGenerator(); | ||
var countOfSampledItems = 0; | ||
ids.forEach(function (id) { | ||
if (sut.getHashCodeScore(id) < sampleRate)++countOfSampledItems; | ||
}); | ||
// Assert | ||
var actualSampleRate = 100 * countOfSampledItems / totalItems; | ||
Assert.ok(Math.abs(actualSampleRate - sampleRate) < errorRange, | ||
"Actual sampling (" + actualSampleRate + ") does not fall into +-2% range from expected rate (" + sampleRate + ")"); | ||
}); | ||
} | ||
}); | ||
} | ||
@@ -126,0 +156,0 @@ |
@@ -131,3 +131,3 @@ /// <reference path="../../../JavaScriptSDK/context/session.ts" /> | ||
test: () => { | ||
if (window.localStorage) { | ||
if (Microsoft.ApplicationInsights.Util.canUseLocalStorage()) { | ||
// setup | ||
@@ -184,3 +184,3 @@ var actualCookieName: string; | ||
// Ensure session manager backs up properly | ||
new Microsoft.ApplicationInsights.Context.User(undefined); | ||
new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
var sessionManager = new Microsoft.ApplicationInsights.Context._SessionManager(null,() => { }); | ||
@@ -222,3 +222,3 @@ sessionManager.update(); | ||
// Initalize the session manager | ||
new Microsoft.ApplicationInsights.Context.User(undefined); | ||
new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
var sessionManager = new Microsoft.ApplicationInsights.Context._SessionManager(null,() => { }); | ||
@@ -264,3 +264,3 @@ sessionManager.update(); | ||
// Initialize the session manager | ||
new Microsoft.ApplicationInsights.Context.User(undefined); | ||
new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
var sessionManager = new Microsoft.ApplicationInsights.Context._SessionManager(null,() => { }); | ||
@@ -304,3 +304,3 @@ sessionManager.update(); | ||
// Back up the session | ||
new Microsoft.ApplicationInsights.Context.User(undefined); | ||
new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
var sessionManager = new Microsoft.ApplicationInsights.Context._SessionManager(null,() => { }); | ||
@@ -312,3 +312,3 @@ sessionManager.update(); | ||
cookies['ai_session'] = undefined; | ||
new Microsoft.ApplicationInsights.Context.User(undefined); | ||
new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
var sessionManager = new Microsoft.ApplicationInsights.Context._SessionManager(null,() => { }); | ||
@@ -515,3 +515,4 @@ sessionManager.update(); | ||
sessionRenewalMs: () => sessionRenewalMs, | ||
sessionExpirationMs: () => sessionExpirationMs | ||
sessionExpirationMs: () => sessionExpirationMs, | ||
cookieDomain: () => undefined | ||
}; | ||
@@ -578,7 +579,24 @@ | ||
private resetStorage() { | ||
if (window.localStorage) { | ||
if (Microsoft.ApplicationInsights.Util.canUseLocalStorage()) { | ||
window.localStorage.clear(); | ||
} | ||
} | ||
private getEmptyConfig() { | ||
return { | ||
instrumentationKey: () => null, | ||
accountId: () => null, | ||
sessionRenewalMs: () => null, | ||
sessionExpirationMs: () => null, | ||
sampleRate: () => null, | ||
appUserId: () => null, | ||
endpointUrl: () => null, | ||
cookieDomain: () => null, | ||
emitLineDelimitedJson: () => null, | ||
maxBatchSizeInBytes: () => null, | ||
maxBatchInterval: () => null, | ||
disableTelemetry: () => null | ||
}; | ||
} | ||
} | ||
new SessionContextTests().registerTests(); |
@@ -29,7 +29,7 @@ /// <reference path="../../../JavaScriptSDK/context/user.ts" /> | ||
// act | ||
var user = new Microsoft.ApplicationInsights.Context.User(undefined); | ||
var user = new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
// verify | ||
Assert.equal(id, user.id, "user id was set from cookie"); | ||
} | ||
@@ -46,4 +46,4 @@ }); | ||
var newIdStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "newId", () => "newId"); | ||
var getCookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "getCookie",() => ""); | ||
var setCookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "setCookie",(cookieName, cookieValue) => { | ||
var getCookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "getCookie", () => ""); | ||
var setCookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "setCookie", (cookieName, cookieValue) => { | ||
actualCookieName = cookieName; | ||
@@ -54,3 +54,3 @@ actualCookieValue = cookieValue; | ||
// act | ||
var user = new Microsoft.ApplicationInsights.Context.User(undefined); | ||
var user = new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
@@ -64,6 +64,6 @@ // verify | ||
Assert.equal("newId", cookieValueParts[0].split('|')[0], "First part of ai_user cookie value should be new user id guid"); | ||
Assert.equal(new Date().toString(),(new Date(cookieValueParts[0].split('|')[1])).toString(), "Second part of ai_user cookie should be parsable as date"); | ||
Assert.equal(new Date().toString(), (new Date(cookieValueParts[0].split('|')[1])).toString(), "Second part of ai_user cookie should be parsable as date"); | ||
var expiration = cookieValueParts[1]; | ||
Assert.equal(true, expiration.substr(0, "expires=".length)==="expires=", "ai_user cookie expiration part should start with expires="); | ||
Assert.equal(true, expiration.substr(0, "expires=".length) === "expires=", "ai_user cookie expiration part should start with expires="); | ||
var expirationDate = new Date(expiration.substr("expires=".length)); | ||
@@ -87,4 +87,4 @@ Assert.equal(true, expirationDate > (new Date), "ai_user cookie expiration should be in the future"); | ||
var newIdStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "newId", () => "newId"); | ||
var getCookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "getCookie",() => ""); | ||
var setCookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "setCookie",(cookieName, cookieValue) => { | ||
var getCookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "getCookie", () => ""); | ||
var setCookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "setCookie", (cookieName, cookieValue) => { | ||
actualCookieName = cookieName; | ||
@@ -95,3 +95,3 @@ actualCookieValue = cookieValue; | ||
// act | ||
var user = new Microsoft.ApplicationInsights.Context.User(undefined); | ||
var user = new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
@@ -105,6 +105,6 @@ // verify | ||
Assert.equal("newId", cookieValueParts[0].split('|')[0], "First part of ai_user cookie value should be new user id guid"); | ||
Assert.equal(new Date().toString(),(new Date(cookieValueParts[0].split('|')[1])).toString(), "Second part of ai_user cookie should be parsable as date"); | ||
Assert.equal(new Date().toString(), (new Date(cookieValueParts[0].split('|')[1])).toString(), "Second part of ai_user cookie should be parsable as date"); | ||
var expiration = cookieValueParts[1]; | ||
Assert.equal(true, expiration.substr(0, "expires=".length)==="expires=", "ai_user cookie expiration part should start with expires="); | ||
Assert.equal(true, expiration.substr(0, "expires=".length) === "expires=", "ai_user cookie expiration part should start with expires="); | ||
var expirationDate = new Date(expiration.substr("expires=".length)); | ||
@@ -127,6 +127,7 @@ Assert.equal(true, expirationDate > (new Date), "ai_user cookie expiration should be in the future"); | ||
var cookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "getCookie",() => authId + "|" + accountId); | ||
var cookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "getCookie", () => authId + "|" + accountId); | ||
// act | ||
var user = new Microsoft.ApplicationInsights.Context.User(undefined); | ||
var user = new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig() | ||
); | ||
@@ -136,3 +137,3 @@ // verify | ||
Assert.equal(accountId, user.accountId, "user account id was not set from cookie"); | ||
} | ||
@@ -146,10 +147,10 @@ }); | ||
var authId = "bla@bla.com"; | ||
var cookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "getCookie",() => authId); | ||
var cookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "getCookie", () => authId); | ||
// act | ||
var user = new Microsoft.ApplicationInsights.Context.User(undefined); | ||
var user = new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
// verify | ||
Assert.equal(authId, user.authenticatedId, "user auth id was set from cookie"); | ||
} | ||
@@ -162,6 +163,6 @@ }); | ||
// setup | ||
var cookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "getCookie",() => ""); | ||
var cookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "getCookie", () => ""); | ||
// act | ||
var user = new Microsoft.ApplicationInsights.Context.User(undefined); | ||
var user = new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
@@ -171,3 +172,3 @@ // verify | ||
Assert.equal(undefined, user.accountId, "user account id was not set"); | ||
} | ||
@@ -180,11 +181,13 @@ }); | ||
// setup | ||
var accountIdBackCompat = "account17"; | ||
var cookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "getCookie",() => null); | ||
var config = this.getEmptyConfig(); | ||
config.accountId = () => "account17"; | ||
var cookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "getCookie", () => null); | ||
// act | ||
var user = new Microsoft.ApplicationInsights.Context.User(accountIdBackCompat); | ||
var user = new Microsoft.ApplicationInsights.Context.User(config); | ||
// verify | ||
Assert.equal(accountIdBackCompat, user.accountId, "user account id was set from back compat"); | ||
Assert.equal(config.accountId(), user.accountId, "user account id was set from back compat"); | ||
} | ||
@@ -199,3 +202,3 @@ }); | ||
var cookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "setCookie"); | ||
var user = new Microsoft.ApplicationInsights.Context.User(undefined); | ||
var user = new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
@@ -207,4 +210,4 @@ // act | ||
Assert.equal(authAndAccountId[0], user.authenticatedId, "user auth id was set"); | ||
Assert.equal(cookieStub.calledWithExactly('ai_authUser', encodeURI(authAndAccountId.join('|'))), true, "user auth id nad account id cookie was set"); | ||
Assert.equal(cookieStub.calledWithExactly('ai_authUser', encodeURI(authAndAccountId.join('|')), null), true, "user auth id and account id cookie was set"); | ||
} | ||
@@ -219,3 +222,3 @@ }); | ||
var cookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "setCookie"); | ||
var user = new Microsoft.ApplicationInsights.Context.User(undefined); | ||
var user = new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
@@ -227,4 +230,4 @@ // act | ||
Assert.equal(authAndAccountId[0], user.authenticatedId, "user auth id was set"); | ||
Assert.equal(cookieStub.calledWithExactly('ai_authUser', encodeURI(authAndAccountId.join('|'))), true, "user auth id cookie was set"); | ||
Assert.equal(cookieStub.calledWithExactly('ai_authUser', encodeURI(authAndAccountId.join('|')), null), true, "user auth id cookie was set"); | ||
} | ||
@@ -239,3 +242,3 @@ }); | ||
var cookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "setCookie"); | ||
var user = new Microsoft.ApplicationInsights.Context.User(undefined); | ||
var user = new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
@@ -248,4 +251,4 @@ // act | ||
Assert.equal(null, user.accountId, "user account id was not set"); | ||
Assert.equal(cookieStub.calledWithExactly('ai_authUser', encodeURI(authAndAccountId[0])), true, "user auth id cookie was set"); | ||
Assert.equal(cookieStub.calledWithExactly('ai_authUser', encodeURI(authAndAccountId[0]), null), true, "user auth id cookie was set"); | ||
} | ||
@@ -259,3 +262,3 @@ }); | ||
var cookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "setCookie"); | ||
var user = new Microsoft.ApplicationInsights.Context.User(undefined); | ||
var user = new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
var loggingStub = this.sandbox.stub(Microsoft.ApplicationInsights._InternalLogging, "throwInternalUserActionable"); | ||
@@ -272,4 +275,4 @@ cookieStub.reset(); | ||
Assert.equal(loggingStub.calledOnce, true, "Warning was logged"); | ||
} | ||
@@ -283,3 +286,3 @@ }); | ||
var cookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "setCookie"); | ||
var user = new Microsoft.ApplicationInsights.Context.User(undefined); | ||
var user = new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
var loggingStub = this.sandbox.stub(Microsoft.ApplicationInsights._InternalLogging, "throwInternalUserActionable"); | ||
@@ -295,4 +298,4 @@ | ||
Assert.equal(loggingStub.calledOnce, true, "Warning was logged"); | ||
} | ||
@@ -306,3 +309,3 @@ }); | ||
var cookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "setCookie"); | ||
var user = new Microsoft.ApplicationInsights.Context.User(undefined); | ||
var user = new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
var loggingStub = this.sandbox.stub(Microsoft.ApplicationInsights._InternalLogging, "throwInternalUserActionable"); | ||
@@ -318,4 +321,4 @@ | ||
Assert.equal(loggingStub.calledOnce, true, "Warning was logged"); | ||
} | ||
@@ -329,3 +332,3 @@ }); | ||
var authAndAccountId = ['my|||special;id', '1234']; | ||
var user = new Microsoft.ApplicationInsights.Context.User(undefined); | ||
var user = new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
var cookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "setCookie"); | ||
@@ -342,4 +345,4 @@ var loggingStub = this.sandbox.stub(Microsoft.ApplicationInsights._InternalLogging, "throwInternalUserActionable"); | ||
Assert.equal(loggingStub.calledOnce, true, "Warning was logged"); | ||
} | ||
@@ -353,3 +356,3 @@ }); | ||
var authAndAccountId = ['myid', '1234 5678']; | ||
var user = new Microsoft.ApplicationInsights.Context.User(undefined); | ||
var user = new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
user.clearAuthenticatedUserContext(); | ||
@@ -367,4 +370,4 @@ var cookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "setCookie"); | ||
Assert.equal(loggingStub.calledOnce, true, "Warning was logged"); | ||
} | ||
@@ -378,3 +381,3 @@ }); | ||
var authAndAccountId = ["\u05D0", "\u05D1"]; // Hebrew characters | ||
var user = new Microsoft.ApplicationInsights.Context.User(undefined); | ||
var user = new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
var cookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "setCookie"); | ||
@@ -389,6 +392,6 @@ var loggingStub = this.sandbox.stub(Microsoft.ApplicationInsights._InternalLogging, "throwInternalUserActionable"); | ||
Assert.equal(authAndAccountId[1], user.accountId, "user account id was set"); | ||
Assert.equal(cookieStub.calledWithExactly('ai_authUser', encodeURI(authAndAccountId.join('|'))), true, "user auth id cookie was set"); | ||
Assert.equal(cookieStub.calledWithExactly('ai_authUser', encodeURI(authAndAccountId.join('|')), null), true, "user auth id cookie was set"); | ||
Assert.equal(loggingStub.notCalled, true, "No warnings"); | ||
} | ||
@@ -401,3 +404,3 @@ }); | ||
// setup | ||
var user = new Microsoft.ApplicationInsights.Context.User(undefined); | ||
var user = new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
user.setAuthenticatedUserContext("bla", "123"); | ||
@@ -413,3 +416,3 @@ var cookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "deleteCookie"); | ||
Assert.equal(cookieStub.calledWithExactly('ai_authUser'), true, "cookie was deleted"); | ||
} | ||
@@ -422,3 +425,3 @@ }); | ||
// setup | ||
var user = new Microsoft.ApplicationInsights.Context.User(undefined); | ||
var user = new Microsoft.ApplicationInsights.Context.User(this.getEmptyConfig()); | ||
var cookieStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "deleteCookie"); | ||
@@ -433,7 +436,24 @@ | ||
Assert.equal(cookieStub.calledWithExactly('ai_authUser'), true, "cookie was deleted"); | ||
} | ||
}); | ||
} | ||
private getEmptyConfig() { | ||
return { | ||
instrumentationKey: () => null, | ||
accountId: () => null, | ||
sessionRenewalMs: () => null, | ||
sessionExpirationMs: () => null, | ||
sampleRate: () => null, | ||
appUserId: () => null, | ||
endpointUrl: () => null, | ||
cookieDomain: () => null, | ||
emitLineDelimitedJson: () => null, | ||
maxBatchSizeInBytes: () => null, | ||
maxBatchInterval: () => null, | ||
disableTelemetry: () => null | ||
}; | ||
} | ||
} | ||
new UserContextTests().registerTests(); |
@@ -18,3 +18,2 @@ | ||
accountId: undefined, | ||
appUserId: undefined, | ||
sessionRenewalMs: 10, | ||
@@ -33,3 +32,6 @@ sessionExpirationMs: 10, | ||
overridePageViewDuration: false, | ||
maxAjaxCallsPerView: 44 | ||
maxAjaxCallsPerView: 44, | ||
disableDataLossAnalysis: true, | ||
disableCorrelationHeaders: false, | ||
cookieDomain: undefined | ||
}; | ||
@@ -65,3 +67,2 @@ | ||
accountId: undefined, | ||
appUserId: undefined, | ||
sessionRenewalMs: undefined, | ||
@@ -172,3 +173,3 @@ sessionExpirationMs: undefined, | ||
var queue: Array<string> = Microsoft.ApplicationInsights._InternalLogging["queue"]; | ||
var queue: Array<Microsoft.ApplicationInsights._InternalLogMessage> = Microsoft.ApplicationInsights._InternalLogging["queue"]; | ||
var length = queue.length; | ||
@@ -178,4 +179,4 @@ for (var i = 0; i < length; i++) { | ||
} | ||
queue.push("Hello1"); | ||
queue.push("Hello2"); | ||
queue.push(new Microsoft.ApplicationInsights._InternalLogMessage(1, "Hello1")); | ||
queue.push(new Microsoft.ApplicationInsights._InternalLogMessage(2, "Hello2")); | ||
@@ -182,0 +183,0 @@ init.loadAppInsights(); |
@@ -17,2 +17,5 @@ /// <reference path="..\TestFramework\Common.ts" /> | ||
Microsoft.ApplicationInsights._InternalLogging.setMaxInternalMessageLimit(Number.MAX_VALUE); | ||
// Clear records indicating what internal message types were already logged | ||
Microsoft.ApplicationInsights._InternalLogging.clearInternalMessageLoggedTypes(); | ||
} | ||
@@ -32,2 +35,3 @@ | ||
var InternalLogging = Microsoft.ApplicationInsights._InternalLogging; | ||
var InternalLoggingMessage = Microsoft.ApplicationInsights._InternalLogMessage; | ||
InternalLogging.setMaxInternalMessageLimit(Number.MAX_VALUE); | ||
@@ -46,2 +50,4 @@ | ||
var i = 0; | ||
// verify | ||
@@ -51,3 +57,3 @@ Assert.ok(!InternalLogging.enableDebugExceptions(), "enableDebugExceptions is false by default"); | ||
// act | ||
InternalLogging.throwInternalUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, "error!"); | ||
InternalLogging.throwInternalUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, new InternalLoggingMessage(++i, "error!")); | ||
@@ -62,3 +68,3 @@ // verify | ||
Assert.throws(() => | ||
InternalLogging.throwInternalUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, "error!"), | ||
InternalLogging.throwInternalUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, new InternalLoggingMessage(++i, "error!")), | ||
"error is thrown when enableDebugExceptions is true"); | ||
@@ -79,15 +85,15 @@ Assert.ok(!throwSpy || throwSpy.calledOnce, "console.warn was not called when the error was thrown"); | ||
var i = 2; | ||
// act | ||
var message = "error!"; | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.WARNING, message); | ||
InternalLogging.throwInternalUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.WARNING, message); | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message); | ||
InternalLogging.throwInternalUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message); | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.WARNING, new InternalLoggingMessage(++i, "error!")); | ||
InternalLogging.throwInternalUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.WARNING, new InternalLoggingMessage(++i, "error!")); | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, new InternalLoggingMessage(++i, "error!")); | ||
InternalLogging.throwInternalUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, new InternalLoggingMessage(++i, "error!")); | ||
//verify | ||
Assert.equal(4, InternalLogging.queue.length); | ||
Assert.equal("AI (Internal): " + message, InternalLogging.queue[0]); | ||
Assert.equal("AI: " + message, InternalLogging.queue[1]); | ||
Assert.equal("AI (Internal): " + message, InternalLogging.queue[2]); | ||
Assert.equal("AI: " + message, InternalLogging.queue[3]); | ||
Assert.equal("AI (Internal): " + "NONUSRACT_BrowserCannotWriteLocalStorage message:\"error!\"", InternalLogging.queue[0].message); | ||
Assert.equal("AI: " + "NONUSRACT_BrowserCannotWriteSessionStorage message:\"error!\"", InternalLogging.queue[1].message); | ||
Assert.equal("AI (Internal): " + "NONUSRACT_BrowserFailedRemovalFromLocalStorage message:\"error!\"", InternalLogging.queue[2].message); | ||
Assert.equal("AI: " + "NONUSRACT_BrowserFailedRemovalFromSessionStorage message:\"error!\"", InternalLogging.queue[3].message); | ||
@@ -105,16 +111,16 @@ // cleanup | ||
var i = 0; | ||
// act | ||
var message = "error!"; | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.WARNING, message); | ||
InternalLogging.throwInternalUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.WARNING, message); | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.WARNING, new InternalLoggingMessage(++i, "error!")); | ||
InternalLogging.throwInternalUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.WARNING, new InternalLoggingMessage(++i, "error!")); | ||
Assert.equal(0, InternalLogging.queue.length); | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message); | ||
InternalLogging.throwInternalUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message); | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, new InternalLoggingMessage(++i, "error!")); | ||
InternalLogging.throwInternalUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, new InternalLoggingMessage(++i, "error!")); | ||
//verify | ||
Assert.equal(2, InternalLogging.queue.length); | ||
Assert.equal("AI (Internal): " + message, InternalLogging.queue[0]); | ||
Assert.equal("AI: " + message, InternalLogging.queue[1]); | ||
Assert.equal("AI (Internal): " + "NONUSRACT_BrowserCannotWriteLocalStorage message:\"error!\"", InternalLogging.queue[0].message); | ||
Assert.equal("AI: " + "NONUSRACT_BrowserCannotWriteSessionStorage message:\"error!\"", InternalLogging.queue[1].message); | ||
} | ||
@@ -132,3 +138,3 @@ }); | ||
// act | ||
var message = "error!"; | ||
var message = new InternalLoggingMessage(1, "error!"); | ||
InternalLogging.enableDebugExceptions = () => false; | ||
@@ -140,3 +146,3 @@ InternalLogging.throwInternalUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message); | ||
Assert.equal(1, InternalLogging.queue.length); | ||
Assert.equal("AI: " + message, InternalLogging.queue[0]); | ||
Assert.equal("AI: " + "NONUSRACT_BrowserCannotReadLocalStorage message:\"error!\"", InternalLogging.queue[0].message); | ||
@@ -160,3 +166,3 @@ // cleanup | ||
// act | ||
var message = "error!"; | ||
var message = new InternalLoggingMessage(1, "error!"); | ||
InternalLogging.enableDebugExceptions = () => false; | ||
@@ -169,3 +175,3 @@ InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message); | ||
Assert.equal(1, InternalLogging.queue.length); | ||
Assert.equal("AI (Internal): " + message, InternalLogging.queue[0]); | ||
Assert.equal("AI (Internal): " + "NONUSRACT_BrowserCannotReadLocalStorage message:\"error!\"", InternalLogging.queue[0].message); | ||
@@ -216,3 +222,3 @@ // cleanup | ||
InternalLogging.enableDebugExceptions = () => false; | ||
InternalLogging.throwInternalUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, "error!"); | ||
InternalLogging.throwInternalUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, new InternalLoggingMessage(1, "error!")); | ||
@@ -235,5 +241,10 @@ // verify | ||
test: () => { | ||
var i = 0; | ||
var maxAllowedInternalMessages = 2; | ||
var message = "Internal Test Event"; | ||
var message1 = new InternalLoggingMessage(++i, ""); | ||
var message2 = new InternalLoggingMessage(++i, ""); | ||
var message3 = new InternalLoggingMessage(++i, ""); | ||
var message4 = new InternalLoggingMessage(++i, ""); | ||
// setup | ||
@@ -245,12 +256,12 @@ InternalLogging.enableDebugExceptions = () => false; | ||
// act | ||
InternalLogging.logInternalMessage(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message); | ||
InternalLogging.logInternalMessage(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message); | ||
InternalLogging.logInternalMessage(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message); | ||
InternalLogging.logInternalMessage(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message); | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message1); | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message2); | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message3); | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message4); | ||
// verify | ||
Assert.equal(maxAllowedInternalMessages + 1, InternalLogging.queue.length); // Since we always send one "extra" event to denote that limit was reached | ||
Assert.equal(InternalLogging.queue[0], message); | ||
Assert.equal(InternalLogging.queue[1], message); | ||
Assert.equal(InternalLogging.queue[2], "AI (Internal): Internal events throttle limit per PageView reached for this app."); | ||
Assert.equal(InternalLogging.queue[0], message1); | ||
Assert.equal(InternalLogging.queue[1], message2); | ||
Assert.equal(InternalLogging.queue[2].message, "NONUSRACT_MessageLimitPerPVExceeded message:\"Internal events throttle limit per PageView reached for this app.\""); | ||
} | ||
@@ -263,3 +274,3 @@ }); | ||
var maxAllowedInternalMessages = 2; | ||
var message = "Internal Test Event"; | ||
var message1 = new InternalLoggingMessage(1, ""); | ||
var logInternalMessageStub = this.sandbox.stub(InternalLogging, 'logInternalMessage'); | ||
@@ -272,3 +283,3 @@ | ||
// act | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message); | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message1); | ||
@@ -282,2 +293,30 @@ // verify | ||
}); | ||
this.testCase({ | ||
name: "LoggingTests: only single message of specific type can be sent within the same session", | ||
test: () => { | ||
var maxAllowedInternalMessages = 2; | ||
var message1 = new InternalLoggingMessage(1, "1"); | ||
var message2 = new InternalLoggingMessage(2, "2"); | ||
// setup | ||
InternalLogging.enableDebugExceptions = () => false; | ||
InternalLogging.resetInternalMessageCount(); | ||
InternalLogging.clearInternalMessageLoggedTypes(); | ||
// act | ||
// send 4 messages, with 2 distinct types | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message1); | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message2); | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message1); | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message2); | ||
// verify | ||
// only two messages should be in the queue, because we have to distinct types | ||
Assert.equal(2, InternalLogging.queue.length); | ||
Assert.equal(InternalLogging.queue[0], message1); | ||
Assert.equal(InternalLogging.queue[1], message2); | ||
} | ||
}); | ||
@@ -288,3 +327,3 @@ this.testCase({ | ||
var maxAllowedInternalMessages = 2; | ||
var message = "Internal Test Event"; | ||
var message = new InternalLoggingMessage(1, "Internal Test Event"); | ||
var logInternalMessageStub = this.sandbox.stub(InternalLogging, 'logInternalMessage'); | ||
@@ -311,3 +350,7 @@ | ||
var maxAllowedInternalMessages = 2; | ||
var message = "Internal Test Event"; | ||
var i = 0; | ||
var message1 = new InternalLoggingMessage(++i, "1"); | ||
var message2 = new InternalLoggingMessage(++i, "2"); | ||
var message3 = new InternalLoggingMessage(++i, "3"); | ||
var message4 = new InternalLoggingMessage(++i, "4"); | ||
@@ -318,8 +361,9 @@ // setup | ||
InternalLogging.resetInternalMessageCount(); | ||
InternalLogging.clearInternalMessageLoggedTypes(); | ||
// act | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message); | ||
InternalLogging.throwInternalUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message); | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message); | ||
InternalLogging.throwInternalUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message); | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message1); | ||
InternalLogging.throwInternalUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message2); | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message3); | ||
InternalLogging.throwInternalUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message4); | ||
@@ -333,10 +377,11 @@ // verify that internal events are throttled | ||
InternalLogging.resetInternalMessageCount(); | ||
InternalLogging.clearInternalMessageLoggedTypes(); | ||
// Send some internal messages | ||
InternalLogging.logInternalMessage(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message); | ||
InternalLogging.logInternalMessage(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message); | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message1); | ||
InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, message2); | ||
// verify again | ||
Assert.equal(InternalLogging.queue.length, maxAllowedInternalMessages + 1); // Since we always send one "extra" event to denote that limit was reached | ||
Assert.equal(InternalLogging.queue[0], message); | ||
Assert.equal(InternalLogging.queue[1], message); | ||
Assert.equal(InternalLogging.queue[0], message1); | ||
Assert.equal(InternalLogging.queue[1], message2); | ||
} | ||
@@ -343,0 +388,0 @@ }); |
@@ -20,5 +20,11 @@ /// <reference path="..\TestFramework\Common.ts" /> | ||
private disableTelemetry: boolean; | ||
private requests; | ||
public testInitialize() { | ||
if (Microsoft.ApplicationInsights.Util.canUseSessionStorage()) { | ||
sessionStorage.clear(); | ||
} | ||
this.requests = []; | ||
this.xhr = sinon.useFakeXMLHttpRequest(); | ||
this.xdr = sinon.useFakeXMLHttpRequest(); | ||
@@ -38,6 +44,6 @@ this.fakeServer = sinon.fakeServer.create(); | ||
}; | ||
this.getSender = () => new Microsoft.ApplicationInsights.Sender(config); | ||
this.errorSpy = this.sandbox.spy(Microsoft.ApplicationInsights.Sender, "_onError"); | ||
this.successSpy = this.sandbox.stub(Microsoft.ApplicationInsights.Sender, "_onSuccess"); | ||
this.successSpy = this.sandbox.spy(Microsoft.ApplicationInsights.Sender, "_onSuccess"); | ||
this.loggingSpy = this.sandbox.stub(Microsoft.ApplicationInsights._InternalLogging, "warnToConsole"); | ||
@@ -47,2 +53,6 @@ this.testTelemetry = { aiDataContract: true }; | ||
public testCleanup() { | ||
Microsoft.ApplicationInsights.DataLossAnalyzer.enabled = false; | ||
} | ||
public registerTests() { | ||
@@ -220,3 +230,3 @@ | ||
var sender: Microsoft.ApplicationInsights.Sender = this.getSender(); | ||
@@ -234,3 +244,3 @@ this.clock.tick(sender._config.maxBatchInterval() + 1); | ||
var xdr = new this.xhr; | ||
XMLHttpRequest = <any>(() => {}); | ||
XMLHttpRequest = <any>(() => { }); | ||
XDomainRequest = <any>(() => { | ||
@@ -288,3 +298,3 @@ xdr.onload = xdr.onreadystatechange; | ||
} | ||
@@ -314,3 +324,3 @@ }); | ||
Microsoft.ApplicationInsights._InternalLogging.enableDebugExceptions = () => false; | ||
@@ -353,3 +363,3 @@ } | ||
} | ||
@@ -387,3 +397,3 @@ }); | ||
} | ||
@@ -410,3 +420,3 @@ }); | ||
} | ||
@@ -431,3 +441,3 @@ }); | ||
} | ||
@@ -452,3 +462,3 @@ }); | ||
} | ||
@@ -473,5 +483,87 @@ }); | ||
} | ||
}); | ||
this.testCase({ | ||
name: "SenderTests: data loss analyzer - send(item), queued, sent; result 0", | ||
test: () => { | ||
// setup | ||
Microsoft.ApplicationInsights.DataLossAnalyzer.enabled = true; | ||
Microsoft.ApplicationInsights.DataLossAnalyzer.appInsights = <any>{ trackTrace: (message) => { }, flush: () => { } }; | ||
var sender: Microsoft.ApplicationInsights.Sender = this.getSender(); | ||
this.fakeServer.requests.pop(); // xhr was created inside Sender's constructor, removing it to avoid confusion | ||
var senderSpy = this.sandbox.spy(sender, "_sender"); | ||
// act | ||
sender.send(this.testTelemetry); | ||
sender.triggerSend(); | ||
this.fakeServer.requests[0].respond(200, {}, ""); | ||
// Validate | ||
Assert.equal(0, Microsoft.ApplicationInsights.DataLossAnalyzer.getNumberOfLostItems()); | ||
} | ||
}); | ||
this.testCase({ | ||
name: "SenderTests: data loss analyzer - send(item), queued, send(item), queued, sent; result 0", | ||
test: () => { | ||
// setup | ||
Microsoft.ApplicationInsights.DataLossAnalyzer.enabled = true; | ||
Microsoft.ApplicationInsights.DataLossAnalyzer.appInsights = <any>{ trackTrace: (message) => { }, flush: () => { } }; | ||
var sender: Microsoft.ApplicationInsights.Sender = this.getSender(); | ||
this.fakeServer.requests.pop(); // xhr was created inside Sender's constructor, removing it to avoid confusion | ||
var senderSpy = this.sandbox.spy(sender, "_sender"); | ||
// act | ||
sender.send(this.testTelemetry); | ||
sender.send(this.testTelemetry); | ||
sender.triggerSend(); | ||
this.fakeServer.requests[0].respond(200, {}, ""); | ||
// Validate | ||
Assert.equal(0, Microsoft.ApplicationInsights.DataLossAnalyzer.getNumberOfLostItems()); | ||
} | ||
}); | ||
this.testCase({ | ||
name: "SenderTests: data loss analyzer - send(item), queued, sent, send(item), leave; result 1", | ||
test: () => { | ||
// setup | ||
Microsoft.ApplicationInsights.DataLossAnalyzer.enabled = true; | ||
Microsoft.ApplicationInsights.DataLossAnalyzer.appInsights = <any>{ trackTrace: (message) => { }, flush: () => { } }; | ||
var sender: Microsoft.ApplicationInsights.Sender = this.getSender(); | ||
this.fakeServer.requests.pop(); // xhr was created inside Sender's constructor, removing it to avoid confusion | ||
var senderSpy = this.sandbox.spy(sender, "_sender"); | ||
// act | ||
sender.send(this.testTelemetry); | ||
sender.triggerSend(); | ||
this.fakeServer.requests[0].respond(200, {}, ""); | ||
sender.send(this.testTelemetry); | ||
// Validate | ||
Assert.equal(1, Microsoft.ApplicationInsights.DataLossAnalyzer.getNumberOfLostItems()); | ||
} | ||
}); | ||
this.testCase({ | ||
name: "SenderTests: data loss analyzer - send(item), queued, post failed; result 1", | ||
test: () => { | ||
// setup | ||
Microsoft.ApplicationInsights.DataLossAnalyzer.enabled = true; | ||
Microsoft.ApplicationInsights.DataLossAnalyzer.appInsights = <any>{ trackTrace: (message) => { }, flush: () => { } }; | ||
var sender: Microsoft.ApplicationInsights.Sender = this.getSender(); | ||
this.fakeServer.requests.pop(); // xhr was created inside Sender's constructor, removing it to avoid confusion | ||
var senderSpy = this.sandbox.spy(sender, "_sender"); | ||
// act | ||
sender.send(this.testTelemetry); | ||
sender.triggerSend(); | ||
this.fakeServer.requests[0].respond(400, {}, ""); | ||
// Validate | ||
Assert.equal(1, Microsoft.ApplicationInsights.DataLossAnalyzer.getNumberOfLostItems()); | ||
} | ||
}); | ||
} | ||
@@ -478,0 +570,0 @@ } |
@@ -183,4 +183,4 @@ /// <reference path="..\TestFramework\Common.ts" /> | ||
Assert.ok(this.throwInternalUserActionableSpy.calledTwice, "user actionable error is thrown"); | ||
var error = this.throwInternalUserActionableSpy.args[0][1].toLowerCase(); | ||
Assert.equal("attempting to serialize an object which does not implement iserializable: nocontractwithcycle", error); | ||
var error = this.throwInternalUserActionableSpy.args[0][1].message.toLowerCase(); | ||
Assert.equal("ai: usract_cannotserializeobjectnonserializable message:\"attempting to serialize an object which does not implement iserializable\" props:\"{name:nocontractwithcycle}\"", error); | ||
} | ||
@@ -207,3 +207,3 @@ }); | ||
Assert.ok(this.throwInternalUserActionableSpy.calledOnce, "error is thrown"); | ||
var error = this.throwInternalUserActionableSpy.args[0][1].toLowerCase(); | ||
var error = this.throwInternalUserActionableSpy.args[0][1].message.toLowerCase(); | ||
Assert.ok(error.indexOf("circular") >= 0 || error.indexOf("cyclic") >= 0, "error message"); | ||
@@ -210,0 +210,0 @@ } |
@@ -119,3 +119,3 @@ /// <reference path="../../testframework/common.ts" /> | ||
Assert.equal("client performance math error:59 < 39 + 19 + 12 + 18", actualLoggedMessage); | ||
Assert.equal("AI (Internal): NONUSRACT_ClientPerformanceMathError message:\"client performance math error.\" props:\"{total:59,network:39,request:19,response:12,dom:18}\"", actualLoggedMessage); | ||
@@ -122,0 +122,0 @@ |
@@ -8,2 +8,3 @@ /// <reference path="../../testframework/common.ts" /> | ||
private exception; | ||
private static id = "someid"; | ||
private static name = "testName" | ||
@@ -18,3 +19,3 @@ private static url = "http://myurl.com" | ||
() => new Microsoft.ApplicationInsights.Telemetry.RemoteDependencyData( | ||
RemoteDependencyTests.name, RemoteDependencyTests.url, RemoteDependencyTests.totalTime, RemoteDependencyTests.success, RemoteDependencyTests.resultCode), | ||
RemoteDependencyTests.id, RemoteDependencyTests.name, RemoteDependencyTests.url, RemoteDependencyTests.totalTime, RemoteDependencyTests.success, RemoteDependencyTests.resultCode), | ||
"RemoteDependencyTelemetryTests"); | ||
@@ -31,3 +32,3 @@ } | ||
var telemetry = new Microsoft.ApplicationInsights.Telemetry.RemoteDependencyData( | ||
RemoteDependencyTests.name, RemoteDependencyTests.url, RemoteDependencyTests.totalTime, RemoteDependencyTests.success, RemoteDependencyTests.resultCode); | ||
RemoteDependencyTests.id, RemoteDependencyTests.name, RemoteDependencyTests.url, RemoteDependencyTests.totalTime, RemoteDependencyTests.success, RemoteDependencyTests.resultCode); | ||
@@ -45,3 +46,3 @@ Assert.equal(RemoteDependencyTests.url, telemetry.commandName, "commandName should be set to url"); | ||
test: () => { | ||
var telemetry = new Microsoft.ApplicationInsights.Telemetry.RemoteDependencyData("", "", 0, false, 0); | ||
var telemetry = new Microsoft.ApplicationInsights.Telemetry.RemoteDependencyData("", "", "", 0, false, 0); | ||
@@ -48,0 +49,0 @@ Assert.equal(AI.DependencyKind.Http, telemetry.dependencyKind, "dependencyKind gets correct default value"); |
@@ -16,3 +16,2 @@ /// <reference path="../testframework/common.ts" /> | ||
accountId: () => undefined, | ||
appUserId: () => undefined, | ||
sessionRenewalMs: () => 10, | ||
@@ -25,3 +24,4 @@ sessionExpirationMs: () => 10, | ||
disableTelemetry: () => false, | ||
sampleRate: () => 100 | ||
sampleRate: () => 100, | ||
cookieDomain: undefined | ||
} | ||
@@ -34,2 +34,3 @@ | ||
public testCleanup() { | ||
(<any>this._telemetryContext).telemetryInitializers = undefined; | ||
} | ||
@@ -248,3 +249,3 @@ | ||
(<any>this._telemetryContext).telemetryInitializers = undefined; | ||
} | ||
@@ -280,3 +281,3 @@ }); | ||
(<any>this._telemetryContext).telemetryInitializers = undefined; | ||
} | ||
@@ -336,3 +337,3 @@ }); | ||
(<any>this._telemetryContext).telemetryInitializers = undefined; | ||
} | ||
@@ -360,7 +361,123 @@ }); | ||
Assert.ok(spy2.calledOnce); | ||
} | ||
}); | ||
// tear down | ||
(<any>this._telemetryContext).telemetryInitializers = undefined; | ||
this.testCase({ | ||
name: "TelemetryContext: telemetry initializer - returning false means don't send an item", | ||
test: () => { | ||
// prepare | ||
var eventEnvelope = this.getTestEventEnvelope(); | ||
var stub = this.sandbox.stub(this._telemetryContext._sender, "send"); | ||
// act | ||
this._telemetryContext.addTelemetryInitializer(<any>(() => { return false; })); | ||
(<any>this._telemetryContext)._track(eventEnvelope); | ||
// verify | ||
Assert.ok(stub.notCalled); | ||
} | ||
}); | ||
this.testCase({ | ||
name: "TelemetryContext: telemetry initializer - returning void means do send an item (back compact with older telemetry initializers)", | ||
test: () => { | ||
// prepare | ||
var eventEnvelope = this.getTestEventEnvelope(); | ||
var stub = this.sandbox.stub(this._telemetryContext._sender, "send"); | ||
// act | ||
this._telemetryContext.addTelemetryInitializer(<any>(() => { return; })); | ||
(<any>this._telemetryContext)._track(eventEnvelope); | ||
// verify | ||
Assert.ok(stub.calledOnce); | ||
} | ||
}); | ||
this.testCase({ | ||
name: "TelemetryContext: telemetry initializer - returning true means do send an item", | ||
test: () => { | ||
// prepare | ||
var eventEnvelope = this.getTestEventEnvelope(); | ||
var stub = this.sandbox.stub(this._telemetryContext._sender, "send"); | ||
// act | ||
this._telemetryContext.addTelemetryInitializer(<any>(() => { return true; })); | ||
(<any>this._telemetryContext)._track(eventEnvelope); | ||
// verify | ||
Assert.ok(stub.calledOnce); | ||
} | ||
}); | ||
this.testCase({ | ||
name: "TelemetryContext: telemetry initializer - if one of initializers returns false than item is not sent", | ||
test: () => { | ||
// prepare | ||
var eventEnvelope = this.getTestEventEnvelope(); | ||
var stub = this.sandbox.stub(this._telemetryContext._sender, "send"); | ||
// act | ||
this._telemetryContext.addTelemetryInitializer(<any>(() => { return true; })); | ||
this._telemetryContext.addTelemetryInitializer(<any>(() => { return false; })); | ||
(<any>this._telemetryContext)._track(eventEnvelope); | ||
// verify | ||
Assert.ok(stub.notCalled); | ||
} | ||
}); | ||
this.testCase({ | ||
name: "TelemetryContext: telemetry initializer - if one of initializers returns false (any order) than item is not sent", | ||
test: () => { | ||
// prepare | ||
var eventEnvelope = this.getTestEventEnvelope(); | ||
var stub = this.sandbox.stub(this._telemetryContext._sender, "send"); | ||
// act | ||
this._telemetryContext.addTelemetryInitializer(<any>(() => { return false; })); | ||
this._telemetryContext.addTelemetryInitializer(<any>(() => { return true; })); | ||
(<any>this._telemetryContext)._track(eventEnvelope); | ||
// verify | ||
Assert.ok(stub.notCalled); | ||
} | ||
}); | ||
this.testCase({ | ||
name: "TelemetryContext: telemetry initializer - returning not boolean/undefined/null means do send an item (back compat with older telemetry initializers)", | ||
test: () => { | ||
// prepare | ||
var eventEnvelope = this.getTestEventEnvelope(); | ||
var stub = this.sandbox.stub(this._telemetryContext._sender, "send"); | ||
// act | ||
this._telemetryContext.addTelemetryInitializer(<any>(() => { return "asdf"; })); | ||
this._telemetryContext.addTelemetryInitializer(<any>(() => { return null; })); | ||
this._telemetryContext.addTelemetryInitializer(<any>(() => { return undefined; })); | ||
(<any>this._telemetryContext)._track(eventEnvelope); | ||
// verify | ||
Assert.ok(stub.calledOnce); | ||
} | ||
}); | ||
this.testCase({ | ||
name: "TelemetryContext: telemetry initializer - if one initializer fails then telemetry is not sent", | ||
test: () => { | ||
// prepare | ||
var eventEnvelope = this.getTestEventEnvelope(); | ||
var stub = this.sandbox.stub(this._telemetryContext._sender, "send"); | ||
// act | ||
this._telemetryContext.addTelemetryInitializer(<any>(() => { throw new Error(); })); | ||
this._telemetryContext.addTelemetryInitializer(<any>(() => { })); | ||
(<any>this._telemetryContext)._track(eventEnvelope); | ||
// verify | ||
Assert.ok(stub.notCalled); | ||
} | ||
}); | ||
} | ||
@@ -367,0 +484,0 @@ |
@@ -13,3 +13,3 @@ /// <reference path="..\TestFramework\Common.ts" /> | ||
var storage = this.getMockStorage(); | ||
var getStorageObjectStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "_getStorageObject",() => storage); | ||
var getStorageObjectStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "_getLocalStorageObject",() => storage); | ||
@@ -29,3 +29,3 @@ storage["test"] = "A"; | ||
var storage = undefined; | ||
var getStorageObjectStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "_getStorageObject",() => storage); | ||
var getStorageObjectStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "_getLocalStorageObject",() => storage); | ||
@@ -42,3 +42,3 @@ Assert.equal(null, Util.getStorage("test"), "getStorage should return null when storage is unavailable"); | ||
var storage = this.getMockStorage(); | ||
var getStorageObjectStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "_getStorageObject",() => storage); | ||
var getStorageObjectStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "_getLocalStorageObject",() => storage); | ||
@@ -55,3 +55,3 @@ Assert.ok(Util.setStorage("test","A"), "setStorage should return true if storage is available for writes"); | ||
var storage = undefined; | ||
var getStorageObjectStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "_getStorageObject",() => storage); | ||
var getStorageObjectStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "_getLocalStorageObject",() => storage); | ||
@@ -68,3 +68,3 @@ Assert.ok(!Util.setStorage("test", "A"), "setStorage should return false if storage is unavailable for writes"); | ||
var storage = this.getMockStorage(); | ||
var getStorageObjectStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "_getStorageObject",() => storage); | ||
var getStorageObjectStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "_getLocalStorageObject",() => storage); | ||
@@ -84,3 +84,3 @@ storage["test"] = "A"; | ||
var storage = undefined; | ||
var getStorageObjectStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "_getStorageObject",() => storage); | ||
var getStorageObjectStub = this.sandbox.stub(Microsoft.ApplicationInsights.Util, "_getLocalStorageObject",() => storage); | ||
@@ -367,2 +367,12 @@ Assert.ok(!Util.removeStorage("test"), "removeStorage should return false if storage is unavailable for writes"); | ||
}); | ||
this.testCase({ | ||
name: "getIE function should return null for non-IE user agent string and IE version for IE", | ||
test: () => { | ||
// Assert | ||
Assert.equal(null, Util.getIEVersion("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36"), "Should return null for non-IE"); | ||
Assert.equal(8, Util.getIEVersion("Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 10.0; Win64; x64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729"), "Should return IE version for IE browser"); | ||
} | ||
}); | ||
} | ||
@@ -369,0 +379,0 @@ |
@@ -34,3 +34,3 @@ /// <reference path="..\TestFramework\Common.ts" /> | ||
config.endpointUrl = "https://dc.services.visualstudio.com/v2/track"; | ||
config.instrumentationKey = "89330895-7c53-4315-a242-85d136ad9c16"; | ||
config.instrumentationKey = "3e6a441c-b52b-4f39-8944-f81dd6c2dc46"; | ||
@@ -37,0 +37,0 @@ var delay = config.maxBatchInterval + 10; |
@@ -32,3 +32,3 @@ /// <reference path="..\TestFramework\Common.ts" /> | ||
config.endpointUrl = "https://dc.services.visualstudio.com/v2/track"; | ||
config.instrumentationKey = "89330895-7c53-4315-a242-85d136ad9c16"; | ||
config.instrumentationKey = "3e6a441c-b52b-4f39-8944-f81dd6c2dc46"; | ||
@@ -35,0 +35,0 @@ var delay = config.maxBatchInterval + 100; |
@@ -32,3 +32,3 @@ /// <reference path="..\TestFramework\Common.ts" /> | ||
config.endpointUrl = "https://dc.services.visualstudio.com/v2/track"; | ||
config.instrumentationKey = "89330895-7c53-4315-a242-85d136ad9c16"; | ||
config.instrumentationKey = "3e6a441c-b52b-4f39-8944-f81dd6c2dc46"; | ||
@@ -35,0 +35,0 @@ var delay = config.maxBatchInterval + 100; |
@@ -7,3 +7,3 @@ /// <reference path="..\TestFramework\Common.ts" /> | ||
private name = "appInsights"; | ||
private instrumentationKey = "89330895-7c53-4315-a242-85d136ad9c16"; | ||
private instrumentationKey = "3e6a441c-b52b-4f39-8944-f81dd6c2dc46"; | ||
private originalAppInsights; | ||
@@ -210,3 +210,2 @@ private timingOffset = 0; | ||
testContextValues("accountId", "accountId"); | ||
testContextValues("appUserId", "appUserId"); | ||
@@ -213,0 +212,0 @@ // logging |
@@ -1,2 +0,3 @@ | ||
/// <reference path="../checkintests/context/SamplingScoreGenerator.tests.ts" /> | ||
/// <reference path="../checkintests/appinsights.tests.ts" /> | ||
/// <reference path="../checkintests/context/HashCodeScoreGenerator.tests.ts" /> | ||
/// <reference path="../checkintests/context/sample.tests.ts" /> | ||
@@ -16,3 +17,2 @@ /// <reference path="../checkintests/context/user.tests.ts" /> | ||
/// <reference path="../checkintests/PageVisitTimeManager.tests.ts" /> | ||
/// <reference path="../checkintests/appinsights.tests.ts" /> | ||
/// <reference path="../checkintests/logging.tests.ts" /> | ||
@@ -25,1 +25,2 @@ /// <reference path="../checkintests/sender.tests.ts" /> | ||
/// <reference path="../checkintests/ajax.tests.ts" /> | ||
/// <reference path="../checkintests/SplitTest.tests.ts" /> |
@@ -57,3 +57,3 @@ /// <reference path="..\TestFramework\Common.ts" /> | ||
this.appInsights = new Microsoft.ApplicationInsights.AppInsights(<any>{ | ||
instrumentationKey: "89330895-7c53-4315-a242-85d136ad9c16", | ||
instrumentationKey: "3e6a441c-b52b-4f39-8944-f81dd6c2dc46", | ||
url: "file:///C:/src/sdk/src/JavaScript/JavaScriptSDK.Tests//E2ETests/ai.js", | ||
@@ -60,0 +60,0 @@ endpointUrl: "http://dc.services.visualstudio.com/v2/track", |
@@ -17,4 +17,6 @@ /// <reference path="../logging.ts" /> | ||
private static instrumentedByAppInsightsName = "InstrumentedByAppInsights"; | ||
private currentWindowHost; | ||
constructor(appInsights: Microsoft.ApplicationInsights.AppInsights) { | ||
this.currentWindowHost = window.location.host; | ||
this.appInsights = appInsights; | ||
@@ -81,6 +83,6 @@ this.initialized = false; | ||
LoggingSeverity.CRITICAL, | ||
"Failed to monitor XMLHttpRequest.open" | ||
+ AjaxMonitor.getFailedAjaxDiagnosticsMessage(this) | ||
+ ", monitoring data for this ajax call may be incorrect: " | ||
+ Microsoft.ApplicationInsights.Util.dump(e)); | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_FailedMonitorAjaxOpen, "Failed to monitor XMLHttpRequest.open, monitoring data for this ajax call may be incorrect.", { | ||
ajaxDiagnosticsMessage: AjaxMonitor.getFailedAjaxDiagnosticsMessage(this), | ||
exception: Microsoft.ApplicationInsights.Util.dump(e) | ||
})); | ||
} | ||
@@ -93,3 +95,3 @@ | ||
private openHandler(xhr: XMLHttpRequestInstrumented, method, url, async) { | ||
var ajaxData = new ajaxRecord(); | ||
var ajaxData = new ajaxRecord(Util.newId()); | ||
ajaxData.method = method; | ||
@@ -127,6 +129,6 @@ ajaxData.requestUrl = url; | ||
LoggingSeverity.CRITICAL, | ||
"Failed to monitor XMLHttpRequest.send" | ||
+ AjaxMonitor.getFailedAjaxDiagnosticsMessage(this) | ||
+ ", monitoring data for this ajax call may be incorrect: " | ||
+ Microsoft.ApplicationInsights.Util.dump(e)); | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_FailedMonitorAjaxSend, "Failed to monitor XMLHttpRequest, monitoring data for this ajax call may be incorrect.", { | ||
ajaxDiagnosticsMessage: AjaxMonitor.getFailedAjaxDiagnosticsMessage(this), | ||
exception: Microsoft.ApplicationInsights.Util.dump(e) | ||
})); | ||
} | ||
@@ -139,3 +141,6 @@ | ||
private sendHandler(xhr: XMLHttpRequestInstrumented, content) { | ||
xhr.ajaxData.requestSentTime = dateTime.Now(); | ||
xhr.ajaxData.requestSentTime = dateTime.Now(); | ||
if (!this.appInsights.config.disableCorrelationHeaders && (UrlHelper.parseUrl(xhr.ajaxData.getAbsoluteUrl()).host == this.currentWindowHost)) { | ||
xhr.setRequestHeader("x-ms-request-id", xhr.ajaxData.id); | ||
} | ||
xhr.ajaxData.xhrMonitoringState.sendDone = true; | ||
@@ -156,6 +161,6 @@ } | ||
LoggingSeverity.CRITICAL, | ||
"Failed to monitor XMLHttpRequest.abort" | ||
+ AjaxMonitor.getFailedAjaxDiagnosticsMessage(this) | ||
+ ", monitoring data for this ajax call may be incorrect: " | ||
+ Microsoft.ApplicationInsights.Util.dump(e)); | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_FailedMonitorAjaxAbort, "Failed to monitor XMLHttpRequest.abort, monitoring data for this ajax call may be incorrect.", { | ||
ajaxDiagnosticsMessage: AjaxMonitor.getFailedAjaxDiagnosticsMessage(this), | ||
exception: Microsoft.ApplicationInsights.Util.dump(e) | ||
})); | ||
} | ||
@@ -174,11 +179,16 @@ | ||
ajaxMonitorInstance.onAjaxComplete(xhr); | ||
} | ||
} | ||
} catch (e) { | ||
var exceptionText = Microsoft.ApplicationInsights.Util.dump(e); | ||
// ignore messages with c00c023f, as this a known IE9 XHR abort issue | ||
if (!exceptionText || exceptionText.toLowerCase().indexOf("c00c023f") == -1) { | ||
_InternalLogging.throwInternalNonUserActionable( | ||
LoggingSeverity.CRITICAL, | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_FailedMonitorAjaxRSC, "Failed to monitor XMLHttpRequest 'readystatechange' event handler, monitoring data for this ajax call may be incorrect.", { | ||
ajaxDiagnosticsMessage: AjaxMonitor.getFailedAjaxDiagnosticsMessage(xhr), | ||
exception: Microsoft.ApplicationInsights.Util.dump(e) | ||
})); | ||
} | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable( | ||
LoggingSeverity.CRITICAL, | ||
"Failed to monitor XMLHttpRequest 'readystatechange' event handler" | ||
+ AjaxMonitor.getFailedAjaxDiagnosticsMessage(xhr) | ||
+ ", monitoring data for this ajax call may be incorrect: " | ||
+ Microsoft.ApplicationInsights.Util.dump(e)); | ||
} | ||
@@ -191,22 +201,20 @@ }); | ||
xhr.ajaxData.status = xhr.status; | ||
xhr.ajaxData.CalculateMetrics(); | ||
xhr.ajaxData.CalculateMetrics(); | ||
if (xhr.ajaxData.ajaxTotalDuration < 0) { | ||
_InternalLogging.throwInternalNonUserActionable( | ||
LoggingSeverity.CRITICAL, | ||
"Failed to calculate the duration of the ajax call" | ||
+ AjaxMonitor.getFailedAjaxDiagnosticsMessage(xhr) | ||
+ " (" | ||
+ xhr.ajaxData.requestSentTime | ||
+ ", " | ||
+ xhr.ajaxData.responseFinishedTime | ||
+ "), monitoring data for this ajax call won't be sent." | ||
); | ||
LoggingSeverity.WARNING, | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_FailedMonitorAjaxDur, "Failed to calculate the duration of the ajax call, monitoring data for this ajax call won't be sent.", { | ||
ajaxDiagnosticsMessage: AjaxMonitor.getFailedAjaxDiagnosticsMessage(xhr), | ||
requestSentTime: xhr.ajaxData.requestSentTime, | ||
responseFinishedTime: xhr.ajaxData.responseFinishedTime | ||
})); | ||
} | ||
else { | ||
this.appInsights.trackAjax( | ||
xhr.ajaxData.id, | ||
xhr.ajaxData.getAbsoluteUrl(), | ||
xhr.ajaxData.getPathName(), | ||
xhr.ajaxData.ajaxTotalDuration, | ||
(+(xhr.ajaxData.status)) < 400, | ||
(+(xhr.ajaxData.status)) >= 200 && (+(xhr.ajaxData.status)) < 400, | ||
+xhr.ajaxData.status | ||
@@ -220,2 +228,2 @@ ); | ||
} | ||
} | ||
} |
@@ -57,2 +57,10 @@ /// <reference path="../logging.ts" /> | ||
public id: string; | ||
constructor(id: string) { | ||
this.id = id; | ||
} | ||
public getAbsoluteUrl() { | ||
@@ -59,0 +67,0 @@ return this.requestUrl ? UrlHelper.getAbsoluteUrl(this.requestUrl) : null; |
@@ -9,4 +9,5 @@ /// <reference path="telemetrycontext.ts" /> | ||
/// <reference path="./ajax/ajax.ts"/> | ||
/// <reference path="./DataLossAnalyzer.ts"/> | ||
/// <reference path="./SplitTest.ts"/> | ||
module Microsoft.ApplicationInsights { | ||
@@ -16,3 +17,3 @@ | ||
export var Version = "0.21.5"; | ||
export var Version = "0.22.8"; | ||
@@ -24,3 +25,2 @@ export interface IConfig { | ||
accountId: string; | ||
appUserId: string; | ||
sessionRenewalMs: number; | ||
@@ -40,2 +40,5 @@ sessionExpirationMs: number; | ||
maxAjaxCallsPerView: number; | ||
disableDataLossAnalysis: boolean; | ||
disableCorrelationHeaders: boolean; | ||
cookieDomain: string; | ||
} | ||
@@ -93,3 +96,2 @@ | ||
accountId: () => this.config.accountId, | ||
appUserId: () => this.config.appUserId, | ||
sessionRenewalMs: () => this.config.sessionRenewalMs, | ||
@@ -102,7 +104,8 @@ sessionExpirationMs: () => this.config.sessionExpirationMs, | ||
disableTelemetry: () => this.config.disableTelemetry, | ||
sampleRate: () => this.config.samplingPercentage | ||
sampleRate: () => this.config.samplingPercentage, | ||
cookieDomain: () => this.config.cookieDomain | ||
} | ||
this.context = new ApplicationInsights.TelemetryContext(configGetters); | ||
this._pageViewManager = new Microsoft.ApplicationInsights.Telemetry.PageViewManager(this, this.config.overridePageViewDuration); | ||
@@ -138,3 +141,3 @@ | ||
if (!this.config.disableAjaxTracking) { new Microsoft.ApplicationInsights.AjaxMonitor(this); } | ||
if (!this.config.disableAjaxTracking) { new Microsoft.ApplicationInsights.AjaxMonitor(this); } | ||
} | ||
@@ -173,3 +176,5 @@ | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "startTrackPage failed, page view may not be collected: " + Util.dump(e)); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_StartTrackFailed, "startTrackPage failed, page view may not be collected: " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) })); | ||
} | ||
@@ -202,3 +207,5 @@ } | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "stopTrackPage failed, page view will not be collected: " + Util.dump(e)); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_StopTrackFailed, "stopTrackPage failed, page view will not be collected: " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) })); | ||
} | ||
@@ -224,3 +231,5 @@ } | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "trackPageView failed, page view will not be collected: " + Util.dump(e)); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_TrackPVFailed, "trackPageView failed, page view will not be collected: " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) })); | ||
} | ||
@@ -237,3 +246,5 @@ } | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "startTrackEvent failed, event will not be collected: " + Util.dump(e)); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_StartTrackEventFailed, "startTrackEvent failed, event will not be collected: " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) })); | ||
} | ||
@@ -252,3 +263,5 @@ } | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "stopTrackEvent failed, event will not be collected: " + Util.dump(e)); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_StopTrackEventFailed, "stopTrackEvent failed, event will not be collected: " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) })); | ||
} | ||
@@ -270,17 +283,20 @@ } | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "trackEvent failed, event will not be collected: " + Util.dump(e)); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_TrackEventFailed, "trackEvent failed, event will not be collected: " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) })); | ||
} | ||
} | ||
public trackAjax(absoluteUrl: string, pathName: string, totalTime: number, success: boolean, resultCode: number) { | ||
public trackAjax(id: string, absoluteUrl: string, pathName: string, totalTime: number, success: boolean, resultCode: number) { | ||
if (this.config.maxAjaxCallsPerView === -1 || | ||
this._trackAjaxAttempts < this.config.maxAjaxCallsPerView) { | ||
var dependency = new Telemetry.RemoteDependencyData(absoluteUrl, pathName, totalTime, success, resultCode); | ||
var dependency = new Telemetry.RemoteDependencyData(id, absoluteUrl, pathName, totalTime, success, resultCode); | ||
var dependencyData = new ApplicationInsights.Telemetry.Common.Data<ApplicationInsights.Telemetry.RemoteDependencyData>( | ||
Telemetry.RemoteDependencyData.dataType, dependency); | ||
var envelope = new Telemetry.Common.Envelope(dependencyData, "Microsoft.ApplicationInsights." + this.config.instrumentationKey.replace(/-/g, "") + ".RemoteDependency"); | ||
var envelope = new Telemetry.Common.Envelope(dependencyData, ApplicationInsights.Telemetry.RemoteDependencyData.envelopeType); | ||
this.context.track(envelope); | ||
} else if (this._trackAjaxAttempts === this.config.maxAjaxCallsPerView) { | ||
_InternalLogging.throwInternalUserActionable(LoggingSeverity.CRITICAL, | ||
"Maximum ajax per page view limit reached, ajax monitoring is paused until the next trackPageView(). In order to increase the limit set the maxAjaxCallsPerView configuration parameter."); | ||
_InternalLogging.throwInternalUserActionable(LoggingSeverity.CRITICAL, new _InternalLogMessage( | ||
_InternalMessageId.USRACT_MaxAjaxPerPVExceeded, | ||
"Maximum ajax per page view limit reached, ajax monitoring is paused until the next trackPageView(). In order to increase the limit set the maxAjaxCallsPerView configuration parameter.")); | ||
} | ||
@@ -313,3 +329,5 @@ | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "trackException failed, exception will not be collected: " + Util.dump(e)); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_TrackExceptionFailed, "trackException failed, exception will not be collected: " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) })); | ||
} | ||
@@ -336,3 +354,5 @@ } | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "trackMetric failed, metric will not be collected: " + Util.dump(e)); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_TrackMetricFailed, "trackMetric failed, metric will not be collected: " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) })); | ||
} | ||
@@ -354,3 +374,5 @@ } | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.WARNING, "trackTrace failed, trace will not be collected: " + Util.dump(e)); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.WARNING, | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_TrackTraceFailed, "trackTrace failed, trace will not be collected: " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) })); | ||
} | ||
@@ -376,3 +398,5 @@ } | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "flush failed, telemetry will not be collected: " + Util.dump(e)); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_FlushFailed, "flush failed, telemetry will not be collected: " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) })); | ||
} | ||
@@ -392,3 +416,5 @@ } | ||
} catch (e) { | ||
_InternalLogging.throwInternalUserActionable(LoggingSeverity.WARNING, "Setting auth user context failed. " + Util.dump(e)); | ||
_InternalLogging.throwInternalUserActionable(LoggingSeverity.WARNING, | ||
new _InternalLogMessage(_InternalMessageId.USRACT_SetAuthContextFailed, "Setting auth user context failed. " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) })); | ||
} | ||
@@ -404,3 +430,5 @@ } | ||
} catch (e) { | ||
_InternalLogging.throwInternalUserActionable(LoggingSeverity.WARNING, "Clearing auth user context failed. " + Util.dump(e)); | ||
_InternalLogging.throwInternalUserActionable(LoggingSeverity.WARNING, | ||
new _InternalLogMessage(_InternalMessageId.USRACT_SetAuthContextFailed, "Clearing auth user context failed. " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) })); | ||
} | ||
@@ -453,3 +481,5 @@ } | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "_onerror threw " + exceptionDump + " while logging error, error will not be collected: " + errorString); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_ExceptionWhileLoggingError, "_onerror threw exception while logging error, error will not be collected: " + Util.getExceptionName(exception), | ||
{ exception: exceptionDump, errorString: errorString })); | ||
} | ||
@@ -478,4 +508,4 @@ } | ||
_InternalLogging.throwInternalUserActionable( | ||
LoggingSeverity.WARNING, | ||
"start" + this._name + " was called more than once for this event without calling stop" + this._name + ". key is '" + name + "'"); | ||
LoggingSeverity.WARNING, new _InternalLogMessage(_InternalMessageId.USRACT_StartCalledMoreThanOnce, "start was called more than once for this event without calling stop.", | ||
{ name: this._name, key: name })); | ||
} | ||
@@ -490,4 +520,4 @@ | ||
_InternalLogging.throwInternalUserActionable( | ||
LoggingSeverity.WARNING, | ||
"stop" + this._name + " was called without a corresponding start" + this._name + " . Event name is '" + name + "'"); | ||
LoggingSeverity.WARNING, new _InternalLogMessage(_InternalMessageId.USRACT_StopCalledWithoutStart, "stop was called without a corresponding start.", | ||
{ name: this._name, key: name })); | ||
} else { | ||
@@ -494,0 +524,0 @@ var end = +new Date; |
@@ -8,2 +8,3 @@ /// <reference path="../SamplingScoreGenerator.ts" /> | ||
public sampleRate: number; | ||
private samplingScoreGenerator: SamplingScoreGenerator; | ||
@@ -15,8 +16,11 @@ // We're using 32 bit math, hence max value is (2^31 - 1) | ||
if (sampleRate > 100 || sampleRate < 0) { | ||
_InternalLogging.throwInternalUserActionable(LoggingSeverity.WARNING, "Sampling rate is out of range (0..100): '" + sampleRate | ||
+ "'. Sampling will be disabled, you may be sending too much data which may affect your AI service level."); | ||
_InternalLogging.throwInternalUserActionable(LoggingSeverity.WARNING, new _InternalLogMessage( | ||
_InternalMessageId.USRACT_SampleRateOutOfRange, | ||
"Sampling rate is out of range (0..100). Sampling will be disabled, you may be sending too much data which may affect your AI service level.", | ||
{ samplingRate: sampleRate })); | ||
this.sampleRate = 100; | ||
} | ||
this.sampleRate = sampleRate; | ||
this.samplingScoreGenerator = new SamplingScoreGenerator(); | ||
} | ||
@@ -30,3 +34,3 @@ | ||
var score = SamplingScoreGenerator.getScore(envelope); | ||
var score = this.samplingScoreGenerator.getSamplingScore(envelope); | ||
@@ -33,0 +37,0 @@ return score < this.sampleRate; |
@@ -10,2 +10,3 @@ /// <reference path="../util.ts" /> | ||
sessionExpirationMs: () => number; | ||
cookieDomain: () => string; | ||
} | ||
@@ -151,7 +152,12 @@ | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "Error parsing ai_session cookie, session will be reset: " + Util.dump(e)); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, | ||
new _InternalLogMessage( | ||
_InternalMessageId.NONUSRACT_ErrorParsingAISessionCookie, | ||
"Error parsing ai_session cookie, session will be reset: " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) })); | ||
} | ||
if (this.automaticSession.renewalDate == 0) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.WARNING, "AI session renewal date is 0, session will be reset."); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.WARNING, | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_SessionRenewalDateIsZero, "AI session renewal date is 0, session will be reset.")); | ||
} | ||
@@ -175,3 +181,4 @@ } | ||
if (!Util.canUseLocalStorage()) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.WARNING, "Browser does not support local storage. Session durations will be inaccurate."); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.WARNING, | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_BrowserDoesNotSupportLocalStorage, "Browser does not support local storage. Session durations will be inaccurate.")); | ||
} | ||
@@ -194,3 +201,5 @@ } | ||
Util.setCookie('ai_session', cookie.join('|') + ';expires=' + cookieExpiry.toUTCString()); | ||
var cookieDomnain = this.config.cookieDomain ? this.config.cookieDomain() : null; | ||
Util.setCookie('ai_session', cookie.join('|') + ';expires=' + cookieExpiry.toUTCString(), cookieDomnain); | ||
} | ||
@@ -197,0 +206,0 @@ |
@@ -13,2 +13,7 @@ /// <reference path="../util.ts" /> | ||
/** | ||
* The telemetry configuration. | ||
*/ | ||
public config: ITelemetryConfig; | ||
/** | ||
* The user ID. | ||
@@ -43,8 +48,8 @@ */ | ||
/** | ||
* Sets the autheticated user id and the account id in this session. | ||
* | ||
* @param authenticatedUserId {string} - The authenticated user id. A unique and persistent string that represents each authenticated user in the service. | ||
* @param accountId {string} - An optional string to represent the account associated with the authenticated user. | ||
*/ | ||
/** | ||
* Sets the autheticated user id and the account id in this session. | ||
* | ||
* @param authenticatedUserId {string} - The authenticated user id. A unique and persistent string that represents each authenticated user in the service. | ||
* @param accountId {string} - An optional string to represent the account associated with the authenticated user. | ||
*/ | ||
public setAuthenticatedUserContext(authenticatedUserId: string, accountId?: string) { | ||
@@ -55,4 +60,7 @@ | ||
if (isInvalidInput) { | ||
_InternalLogging.throwInternalUserActionable(LoggingSeverity.WARNING, "Setting auth user context failed. " + | ||
"User auth/account id should be of type string, and not contain commas, semi-colons, equal signs, spaces, or vertical-bars."); | ||
_InternalLogging.throwInternalUserActionable(LoggingSeverity.WARNING, | ||
new _InternalLogMessage( | ||
_InternalMessageId.USRACT_SetAuthContextFailedAccountName, | ||
"Setting auth user context failed. " + | ||
"User auth/account id should be of type string, and not contain commas, semi-colons, equal signs, spaces, or vertical-bars.")); | ||
return; | ||
@@ -71,3 +79,3 @@ } | ||
// Encoding the cookie to handle unexpected unicode characters. | ||
Util.setCookie(User.authUserCookieName, encodeURI(authCookie)); | ||
Util.setCookie(User.authUserCookieName, encodeURI(authCookie), this.config.cookieDomain()); | ||
} | ||
@@ -85,3 +93,3 @@ | ||
constructor(accountId: string) { | ||
constructor(config: ITelemetryConfig) { | ||
@@ -97,2 +105,4 @@ //get userId or create new one if none exists | ||
this.config = config; | ||
if (!this.id) { | ||
@@ -104,8 +114,10 @@ this.id = Util.newId(); | ||
// without expiration, cookies expire at the end of the session | ||
// set it to a year from now | ||
// set it to 365 days from now | ||
// 365 * 24 * 60 * 60 * 1000 = 31536000000 | ||
date.setTime(date.getTime() + 31536000000); | ||
var newCookie = [this.id, acqStr]; | ||
Util.setCookie(User.userCookieName, newCookie.join(User.cookieSeparator) + ';expires=' + date.toUTCString()); | ||
var cookieDomain = this.config.cookieDomain ? this.config.cookieDomain() : undefined; | ||
Util.setCookie(User.userCookieName, newCookie.join(User.cookieSeparator) + ';expires=' + date.toUTCString(), cookieDomain); | ||
// If we have an ai_session in local storage this means the user actively removed our cookies. | ||
@@ -118,3 +130,3 @@ // We should respect their wishes and clear ourselves from local storage | ||
// But if the the customer set the accountId through the newer setAuthenticatedUserContext API, we will override it. | ||
this.accountId = accountId; | ||
this.accountId = config.accountId ? config.accountId() : undefined; | ||
@@ -149,3 +161,3 @@ // Get the auth user id and account id from the cookie if exists | ||
} | ||
} |
@@ -92,7 +92,9 @@ /// <reference path="appinsights.ts" /> | ||
} catch (exception) { | ||
var message = "Failed to send queued telemetry"; | ||
var properties: any = {}; | ||
if (exception && typeof exception.toString === "function") { | ||
message += ": " + exception.toString(); | ||
properties.exception = exception.toString(); | ||
} | ||
var message = new _InternalLogMessage(_InternalMessageId.NONUSRACT_FailedToSendQueuedTelemetry, "Failed to send queued telemetry", properties); | ||
Microsoft.ApplicationInsights._InternalLogging.throwInternalNonUserActionable(LoggingSeverity.WARNING, message); | ||
@@ -104,6 +106,6 @@ } | ||
return setInterval(() => { | ||
var queue: Array<string> = Microsoft.ApplicationInsights._InternalLogging.queue; | ||
var queue: Array<_InternalLogMessage> = Microsoft.ApplicationInsights._InternalLogging.queue; | ||
var length = queue.length; | ||
for (var i = 0; i < length; i++) { | ||
appInsightsInstance.trackTrace(queue[i]); | ||
appInsightsInstance.trackTrace(queue[i].message); | ||
} | ||
@@ -133,3 +135,4 @@ queue.length = 0; | ||
if (!Microsoft.ApplicationInsights.Util.addEventHandler('beforeunload', performHousekeeping)) { | ||
Microsoft.ApplicationInsights._InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, 'Could not add handler for beforeunload'); | ||
Microsoft.ApplicationInsights._InternalLogging.throwInternalNonUserActionable(Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL, | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_FailedToAddHandlerForOnBeforeUnload, 'Could not add handler for beforeunload')); | ||
} | ||
@@ -146,4 +149,2 @@ } | ||
config.endpointUrl = config.endpointUrl || "//dc.services.visualstudio.com/v2/track"; | ||
config.accountId = config.accountId; | ||
config.appUserId = config.appUserId; | ||
config.sessionRenewalMs = 30 * 60 * 1000; | ||
@@ -172,3 +173,6 @@ config.sessionExpirationMs = 24 * 60 * 60 * 1000; | ||
config.maxAjaxCallsPerView = !isNaN(config.maxAjaxCallsPerView) ? config.maxAjaxCallsPerView : 500; | ||
config.disableCorrelationHeaders = (config.disableCorrelationHeaders !== undefined && config.disableCorrelationHeaders !== null) ? | ||
Util.stringToBoolOrDefault(config.disableCorrelationHeaders) : | ||
true; | ||
return config; | ||
@@ -175,0 +179,0 @@ } |
module Microsoft.ApplicationInsights { | ||
export enum LoggingSeverity { | ||
@@ -15,2 +15,89 @@ /** | ||
/** | ||
* Internal message ID. Please create a new one for every conceptually different message. Please keep alphabetically ordered | ||
*/ | ||
export enum _InternalMessageId { | ||
NONUSRACT_BrowserDoesNotSupportLocalStorage, | ||
NONUSRACT_BrowserCannotReadLocalStorage, | ||
NONUSRACT_BrowserCannotReadSessionStorage, | ||
NONUSRACT_BrowserCannotWriteLocalStorage, | ||
NONUSRACT_BrowserCannotWriteSessionStorage, | ||
NONUSRACT_BrowserFailedRemovalFromLocalStorage, | ||
NONUSRACT_BrowserFailedRemovalFromSessionStorage, | ||
NONUSRACT_CannotSendEmptyTelemetry, | ||
NONUSRACT_ClientPerformanceMathError, | ||
NONUSRACT_ErrorParsingAISessionCookie, | ||
NONUSRACT_ErrorPVCalc, | ||
NONUSRACT_ExceptionWhileLoggingError, | ||
NONUSRACT_FailedAddingTelemetryToBuffer, | ||
NONUSRACT_FailedMonitorAjaxAbort, | ||
NONUSRACT_FailedMonitorAjaxDur, | ||
NONUSRACT_FailedMonitorAjaxOpen, | ||
NONUSRACT_FailedMonitorAjaxRSC, | ||
NONUSRACT_FailedMonitorAjaxSend, | ||
NONUSRACT_FailedToAddHandlerForOnBeforeUnload, | ||
NONUSRACT_FailedToSendQueuedTelemetry, | ||
NONUSRACT_FailedToReportDataLoss, | ||
NONUSRACT_FlushFailed, | ||
NONUSRACT_MessageLimitPerPVExceeded, | ||
NONUSRACT_MissingRequiredFieldSpecification, | ||
NONUSRACT_NavigationTimingNotSupported, | ||
NONUSRACT_OnError, | ||
NONUSRACT_SessionRenewalDateIsZero, | ||
NONUSRACT_SenderNotInitialized, | ||
NONUSRACT_StartTrackEventFailed, | ||
NONUSRACT_StopTrackEventFailed, | ||
NONUSRACT_StartTrackFailed, | ||
NONUSRACT_StopTrackFailed, | ||
NONUSRACT_TelemetrySampledAndNotSent, | ||
NONUSRACT_TrackEventFailed, | ||
NONUSRACT_TrackExceptionFailed, | ||
NONUSRACT_TrackMetricFailed, | ||
NONUSRACT_TrackPVFailed, | ||
NONUSRACT_TrackPVFailedCalc, | ||
NONUSRACT_TrackTraceFailed, | ||
NONUSRACT_TransmissionFailed, | ||
USRACT_CannotSerializeObject, | ||
USRACT_CannotSerializeObjectNonSerializable, | ||
USRACT_CircularReferenceDetected, | ||
USRACT_ClearAuthContextFailed, | ||
USRACT_ExceptionTruncated, | ||
USRACT_IllegalCharsInName, | ||
USRACT_ItemNotInArray, | ||
USRACT_MaxAjaxPerPVExceeded, | ||
USRACT_MessageTruncated, | ||
USRACT_NameTooLong, | ||
USRACT_SampleRateOutOfRange, | ||
USRACT_SetAuthContextFailed, | ||
USRACT_SetAuthContextFailedAccountName, | ||
USRACT_StringValueTooLong, | ||
USRACT_StartCalledMoreThanOnce, | ||
USRACT_StopCalledWithoutStart, | ||
USRACT_TelemetryInitializerFailed, | ||
USRACT_TrackArgumentsNotSpecified, | ||
USRACT_UrlTooLong, | ||
} | ||
export class _InternalLogMessage { | ||
public message: string; | ||
public messageId: _InternalMessageId; | ||
constructor(msgId: _InternalMessageId, msg: string, properties?: Object) { | ||
this.message = _InternalMessageId[msgId].toString(); | ||
this.messageId = msgId; | ||
var diagnosticText = | ||
(msg ? " message:" + _InternalLogMessage.sanitizeDiagnosticText(msg) : "") + | ||
(properties ? " props:" + _InternalLogMessage.sanitizeDiagnosticText(JSON.stringify(properties)) : ""); | ||
this.message += diagnosticText; | ||
} | ||
private static sanitizeDiagnosticText(text: string) { | ||
return "\"" + text.replace(/\"/g, "") + "\""; | ||
} | ||
} | ||
export class _InternalLogging { | ||
@@ -24,2 +111,7 @@ | ||
/** | ||
* Session storage key for the prefix for the key indicating message type already logged | ||
*/ | ||
private static AIInternalMessagePrefix: string = "AITR_"; | ||
/** | ||
* For user non actionable traces use AI Internal prefix. | ||
@@ -57,10 +149,16 @@ */ | ||
* @param severity {LoggingSeverity} - The severity of the log message | ||
* @param message {string} - The log message. | ||
* @param message {_InternalLogMessage} - The log message. | ||
*/ | ||
public static throwInternalNonUserActionable(severity: LoggingSeverity, message: string) { | ||
public static throwInternalNonUserActionable(severity: LoggingSeverity, message: _InternalLogMessage) { | ||
if (this.enableDebugExceptions()) { | ||
throw message; | ||
} else { | ||
this.warnToConsole(message); | ||
this.logInternalMessage(severity, this.AiNonUserActionablePrefix + message); | ||
if (typeof (message) !== "undefined" && !!message) { | ||
if (typeof (message.message) !== "undefined") { | ||
message.message = this.AiNonUserActionablePrefix + message.message; | ||
this.warnToConsole(message.message); | ||
this.logInternalMessage(severity, message); | ||
} | ||
} | ||
} | ||
@@ -72,10 +170,15 @@ } | ||
* @param severity {LoggingSeverity} - The severity of the log message | ||
* @param message {string} - The log message. | ||
* @param message {_InternalLogMessage} - The log message. | ||
*/ | ||
public static throwInternalUserActionable(severity: LoggingSeverity, message: string) { | ||
public static throwInternalUserActionable(severity: LoggingSeverity, message: _InternalLogMessage) { | ||
if (this.enableDebugExceptions()) { | ||
throw message; | ||
} else { | ||
this.warnToConsole(message); | ||
this.logInternalMessage(severity, this.AiUserActionablePrefix + message); | ||
if (typeof (message) !== "undefined" && !!message) { | ||
if (typeof (message.message) !== "undefined") { | ||
message.message = this.AiUserActionablePrefix + message.message; | ||
this.warnToConsole(message.message); | ||
this.logInternalMessage(severity, message); | ||
} | ||
} | ||
} | ||
@@ -106,2 +209,16 @@ } | ||
/** | ||
* Clears the list of records indicating that internal message type was already logged | ||
*/ | ||
public static clearInternalMessageLoggedTypes(): void { | ||
if (Util.canUseSessionStorage()) { | ||
var sessionStorageKeys = Util.getSessionStorageKeys(); | ||
for (var i = 0; i < sessionStorageKeys.length; i++) { | ||
if (sessionStorageKeys[i].indexOf(_InternalLogging.AIInternalMessagePrefix) === 0) { | ||
Util.removeSessionStorage(sessionStorageKeys[i]); | ||
} | ||
} | ||
} | ||
} | ||
/** | ||
* Sets the limit for the number of internal events before they are throttled | ||
@@ -114,3 +231,3 @@ * @param limit {number} - The throttle limit to set for internal events | ||
} | ||
this.MAX_INTERNAL_MESSAGE_LIMIT = limit; | ||
@@ -122,5 +239,5 @@ } | ||
* @param severity {LoggingSeverity} - The severity of the log message | ||
* @param message {string} - The message to log. | ||
* @param message {_InternalLogMessage} - The message to log. | ||
*/ | ||
public static logInternalMessage(severity: LoggingSeverity, message: string): void { | ||
private static logInternalMessage(severity: LoggingSeverity, message: _InternalLogMessage): void { | ||
if (this._areInternalMessagesThrottled()) { | ||
@@ -130,13 +247,29 @@ return; | ||
// Push the event in the internal queue | ||
if (this.verboseLogging() || severity === LoggingSeverity.CRITICAL) { | ||
this.queue.push(message); | ||
this._messageCount++; | ||
// check if this message type was already logged for this session and if so, don't log it again | ||
var logMessage = true; | ||
if (Util.canUseSessionStorage()) { | ||
var storageMessageKey = _InternalLogging.AIInternalMessagePrefix + _InternalMessageId[message.messageId]; | ||
var internalMessageTypeLogRecord = Util.getSessionStorage(storageMessageKey); | ||
if (internalMessageTypeLogRecord) { | ||
logMessage = false; | ||
} else { | ||
Util.setSessionStorage(storageMessageKey, "1"); | ||
} | ||
} | ||
// When throttle limit reached, send a special event | ||
if (this._messageCount == this.MAX_INTERNAL_MESSAGE_LIMIT) { | ||
var throttleLimitMessage = this.AiNonUserActionablePrefix + "Internal events throttle limit per PageView reached for this app."; | ||
this.queue.push(throttleLimitMessage); | ||
this.warnToConsole(throttleLimitMessage); | ||
if (logMessage) { | ||
// Push the event in the internal queue | ||
if (this.verboseLogging() || severity === LoggingSeverity.CRITICAL) { | ||
this.queue.push(message); | ||
this._messageCount++; | ||
} | ||
// When throttle limit reached, send a special event | ||
if (this._messageCount == this.MAX_INTERNAL_MESSAGE_LIMIT) { | ||
var throttleLimitMessage = "Internal events throttle limit per PageView reached for this app."; | ||
var throttleMessage = new _InternalLogMessage(_InternalMessageId.NONUSRACT_MessageLimitPerPVExceeded, throttleLimitMessage); | ||
this.queue.push(throttleMessage); | ||
this.warnToConsole(throttleLimitMessage); | ||
} | ||
} | ||
@@ -143,0 +276,0 @@ } |
@@ -1,7 +0,7 @@ | ||
c:\src\ApplicationInsights-JS\JavaScript\JavaScriptSDK\bin\JavaScriptSDK.dll.config | ||
c:\src\ApplicationInsights-JS\JavaScript\JavaScriptSDK\bin\JavaScriptSDK.dll | ||
c:\src\ApplicationInsights-JS\JavaScript\JavaScriptSDK\bin\JavaScriptSDK.pdb | ||
c:\src\ApplicationInsights-JS\JavaScript\JavaScriptSDK\bin\AjaxMin.dll | ||
c:\src\ApplicationInsights-JS\JavaScript\JavaScriptSDK\obj\Debug\JavaScriptSDK.dll | ||
c:\src\ApplicationInsights-JS\JavaScript\JavaScriptSDK\obj\Debug\JavaScriptSDK.pdb | ||
C:\src\ApplicationInsights-JS\JavaScript\JavaScriptSDK\obj\Debug\JavaScriptSDK.csprojResolveAssemblyReference.cache | ||
e:\ai-gh-js\JavaScript\JavaScriptSDK\bin\JavaScriptSDK.dll | ||
e:\ai-gh-js\JavaScript\JavaScriptSDK\bin\JavaScriptSDK.pdb | ||
e:\ai-gh-js\JavaScript\JavaScriptSDK\bin\AjaxMin.dll | ||
e:\ai-gh-js\JavaScript\JavaScriptSDK\obj\Debug\JavaScriptSDK.dll | ||
e:\ai-gh-js\JavaScript\JavaScriptSDK\obj\Debug\JavaScriptSDK.pdb | ||
e:\ai-gh-js\JavaScript\JavaScriptSDK\bin\JavaScriptSDK.dll.config | ||
E:\ai-gh-js\JavaScript\JavaScriptSDK\obj\Debug\JavaScriptSDK.csprojResolveAssemblyReference.cache |
@@ -1,14 +0,18 @@ | ||
module Microsoft.ApplicationInsights { | ||
/// <reference path="./HashCodeScoreGenerator.ts" /> | ||
module Microsoft.ApplicationInsights { | ||
export class SamplingScoreGenerator { | ||
private hashCodeGeneragor: HashCodeScoreGenerator; | ||
// We're using 32 bit math, hence max value is (2^31 - 1) | ||
public static INT_MAX_VALUE: number = 2147483647; | ||
constructor() { | ||
this.hashCodeGeneragor = new HashCodeScoreGenerator(); | ||
} | ||
public static getScore(envelope: Telemetry.Common.Envelope): number { | ||
public getSamplingScore(envelope: Telemetry.Common.Envelope): number { | ||
var tagKeys: AI.ContextTagKeys = new AI.ContextTagKeys(); | ||
var score: number = 0; | ||
if (envelope.tags[tagKeys.userId]) { | ||
score = SamplingScoreGenerator.getSamplingHashCode(envelope.tags[tagKeys.userId]) / SamplingScoreGenerator.INT_MAX_VALUE; | ||
score = this.hashCodeGeneragor.getHashCodeScore(envelope.tags[tagKeys.userId]); | ||
} else if (envelope.tags[tagKeys.operationId]) { | ||
score = SamplingScoreGenerator.getSamplingHashCode(envelope.tags[tagKeys.operationId]) / SamplingScoreGenerator.INT_MAX_VALUE; | ||
score = this.hashCodeGeneragor.getHashCodeScore(envelope.tags[tagKeys.operationId]); | ||
} else { | ||
@@ -18,21 +22,5 @@ score = Math.random() | ||
return score * 100; | ||
return score; | ||
} | ||
public static getSamplingHashCode(input: string): number { | ||
if (input == "") { return 0; } | ||
// 5358 is a magic number: http://stackoverflow.com/questions/10696223/reason-for-5381-number-in-djb-hash-function | ||
var hash: number = 5381; | ||
for (var i: number = 0; i < input.length; ++i) { | ||
hash = ((hash << 5) + hash) + input.charCodeAt(i); | ||
// 'hash' is of number type which means 53 bit integer (http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types-number-type) | ||
// 'hash & hash' will keep it 32 bit integer - just to make it clearer what the result is. | ||
hash = hash & hash; | ||
} | ||
return Math.abs(hash); | ||
} | ||
} | ||
} |
@@ -14,2 +14,3 @@ /// <reference path="serializer.ts" /> | ||
/// <reference path="ajax/ajax.ts"/> | ||
/// <reference path="./DataLossAnalyzer.ts"/> | ||
@@ -25,3 +26,2 @@ interface XDomainRequest extends XMLHttpRequestEventTarget { | ||
new (): XDomainRequest; | ||
create(): XDomainRequest; | ||
}; | ||
@@ -72,3 +72,3 @@ | ||
*/ | ||
public _sender: (payload: string, isAsync: boolean) => void; | ||
public _sender: (payload: string, isAsync: boolean, numberOfItemsInPayload: number) => void; | ||
@@ -106,3 +106,3 @@ /** | ||
if (!envelope) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "Cannot send empty telemetry"); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, new _InternalLogMessage(_InternalMessageId.NONUSRACT_CannotSendEmptyTelemetry, "Cannot send empty telemetry")); | ||
return; | ||
@@ -113,3 +113,3 @@ } | ||
if (!this._sender) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "Sender was not initialized"); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, new _InternalLogMessage(_InternalMessageId.NONUSRACT_SenderNotInitialized, "Sender was not initialized")); | ||
return; | ||
@@ -136,4 +136,8 @@ } | ||
} | ||
DataLossAnalyzer.incrementItemsQueued(); | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "Failed adding telemetry to the sender's buffer, some telemetry will be lost: " + Util.dump(e)); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_FailedAddingTelemetryToBuffer, "Failed adding telemetry to the sender's buffer, some telemetry will be lost: " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) })); | ||
} | ||
@@ -168,3 +172,3 @@ } | ||
} | ||
try { | ||
@@ -181,3 +185,3 @@ // Send data only if disableTelemetry is false | ||
// invoke send | ||
this._sender(batch, isAsync); | ||
this._sender(batch, isAsync, this._buffer.length); | ||
} | ||
@@ -194,3 +198,7 @@ | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "Telemetry transmission failed, some telemetry will be lost: " + Util.dump(e)); | ||
/* Ignore this error for IE under v10 */ | ||
if (!Util.getIEVersion() || Util.getIEVersion() > 9) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, new _InternalLogMessage(_InternalMessageId.NONUSRACT_TransmissionFailed, "Telemetry transmission failed, some telemetry will be lost: " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) })); | ||
} | ||
} | ||
@@ -204,3 +212,3 @@ } | ||
*/ | ||
private _xhrSender(payload: string, isAsync: boolean) { | ||
private _xhrSender(payload: string, isAsync: boolean, countOfItemsInPayload: number) { | ||
var xhr = new XMLHttpRequest(); | ||
@@ -210,3 +218,3 @@ xhr[AjaxMonitor.DisabledPropertyName] = true; | ||
xhr.setRequestHeader("Content-type", "application/json"); | ||
xhr.onreadystatechange = () => Sender._xhrReadyStateChange(xhr, payload); | ||
xhr.onreadystatechange = () => Sender._xhrReadyStateChange(xhr, payload, countOfItemsInPayload); | ||
xhr.onerror = (event: ErrorEvent) => Sender._onError(payload, xhr.responseText || xhr.response || "", event); | ||
@@ -235,3 +243,3 @@ xhr.send(payload); | ||
*/ | ||
public static _xhrReadyStateChange(xhr: XMLHttpRequest, payload: string) { | ||
public static _xhrReadyStateChange(xhr: XMLHttpRequest, payload: string, countOfItemsInPayload: number) { | ||
if (xhr.readyState === 4) { | ||
@@ -241,3 +249,3 @@ if ((xhr.status < 200 || xhr.status >= 300) && xhr.status !== 0) { | ||
} else { | ||
Sender._onSuccess(payload); | ||
Sender._onSuccess(payload, countOfItemsInPayload); | ||
} | ||
@@ -252,3 +260,3 @@ } | ||
if (xdr && (xdr.responseText + "" === "200" || xdr.responseText === "")) { | ||
Sender._onSuccess(payload); | ||
Sender._onSuccess(payload, 0); | ||
} else { | ||
@@ -263,3 +271,4 @@ Sender._onError(payload, xdr && xdr.responseText || ""); | ||
public static _onError(payload: string, message: string, event?: ErrorEvent) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.WARNING, "Failed to send telemetry:\n" + message); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.WARNING, | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_OnError, "Failed to send telemetry.", { message: message })); | ||
} | ||
@@ -270,4 +279,4 @@ | ||
*/ | ||
public static _onSuccess(payload: string) { | ||
// no-op, used in tests | ||
public static _onSuccess(payload: string, countOfItemsInPayload: number) { | ||
DataLossAnalyzer.decrementItemsQueued(countOfItemsInPayload); | ||
} | ||
@@ -274,0 +283,0 @@ } |
@@ -37,3 +37,4 @@ /// <reference path="logging.ts" /> | ||
if (!source) { | ||
_InternalLogging.throwInternalUserActionable(LoggingSeverity.CRITICAL, "cannot serialize " + name + " because it is null or undefined"); | ||
_InternalLogging.throwInternalUserActionable(LoggingSeverity.CRITICAL, | ||
new _InternalLogMessage(_InternalMessageId.USRACT_CannotSerializeObject, "cannot serialize object because it is null or undefined", { name: name })); | ||
return output; | ||
@@ -43,3 +44,4 @@ } | ||
if (source[circularReferenceCheck]) { | ||
_InternalLogging.throwInternalUserActionable(LoggingSeverity.WARNING, "Circular reference detected while serializing: '" + name); | ||
_InternalLogging.throwInternalUserActionable(LoggingSeverity.WARNING, | ||
new _InternalLogMessage(_InternalMessageId.USRACT_CircularReferenceDetected, "Circular reference detected while serializing object", { name: name })); | ||
return output; | ||
@@ -59,3 +61,4 @@ } | ||
} else { | ||
_InternalLogging.throwInternalUserActionable(LoggingSeverity.WARNING, "Attempting to serialize an object which does not implement ISerializable: " + name); | ||
_InternalLogging.throwInternalUserActionable(LoggingSeverity.WARNING, | ||
new _InternalLogMessage(_InternalMessageId.USRACT_CannotSerializeObjectNonSerializable, "Attempting to serialize an object which does not implement ISerializable", { name: name })); | ||
@@ -89,3 +92,4 @@ try { | ||
LoggingSeverity.CRITICAL, | ||
"Missing required field specification: The field '" + field + "' on '"+ name + "' is required but not present on source"); | ||
new _InternalLogMessage(_InternalMessageId.NONUSRACT_MissingRequiredFieldSpecification, "Missing required field specification. The field is required but not present on source", | ||
{ field: field, name: name })); | ||
@@ -132,3 +136,4 @@ // If not in debug mode, continue and hope the error is permissible | ||
LoggingSeverity.CRITICAL, | ||
"This field was specified as an array in the contract but the item is not an array.\r\n" + name); | ||
new _InternalLogMessage(_InternalMessageId.USRACT_ItemNotInArray, "This field was specified as an array in the contract but the item is not an array.\r\n", | ||
{ name: name })); | ||
} else { | ||
@@ -135,0 +140,0 @@ output = []; |
@@ -60,4 +60,4 @@ /// <reference path="../../logging.ts" /> | ||
_InternalLogging.throwInternalUserActionable( | ||
LoggingSeverity.WARNING, | ||
"name contains illegal characters. Illgeal character have been replaced with '_'. new name: " + name); | ||
LoggingSeverity.WARNING, new _InternalLogMessage(_InternalMessageId.USRACT_IllegalCharsInName, "name contains illegal characters. Illegal characters have been replaced with '_'.", | ||
{ newName: name })); | ||
} | ||
@@ -69,4 +69,4 @@ | ||
_InternalLogging.throwInternalUserActionable( | ||
LoggingSeverity.WARNING, | ||
"name is too long. It has been truncated to " + DataSanitizer.MAX_NAME_LENGTH + " characters. name: " + name); | ||
LoggingSeverity.WARNING, new _InternalLogMessage(_InternalMessageId.USRACT_NameTooLong, "name is too long. It has been truncated to " + DataSanitizer.MAX_NAME_LENGTH + " characters.", | ||
{ name: name })); | ||
} | ||
@@ -84,4 +84,4 @@ } | ||
_InternalLogging.throwInternalUserActionable( | ||
LoggingSeverity.WARNING, | ||
"string value is too long. It has been truncated to " + DataSanitizer.MAX_STRING_LENGTH + " characters. value: " + value); | ||
LoggingSeverity.WARNING, new _InternalLogMessage(_InternalMessageId.USRACT_StringValueTooLong, "string value is too long. It has been truncated to " + DataSanitizer.MAX_STRING_LENGTH + " characters.", | ||
{ value: value })); | ||
} | ||
@@ -98,4 +98,4 @@ } | ||
_InternalLogging.throwInternalUserActionable( | ||
LoggingSeverity.WARNING, | ||
"url is too long, it has been trucated to " + DataSanitizer.MAX_URL_LENGTH + " characters. url: " + url); | ||
LoggingSeverity.WARNING, new _InternalLogMessage(_InternalMessageId.USRACT_UrlTooLong, "url is too long, it has been trucated to " + DataSanitizer.MAX_URL_LENGTH + " characters.", | ||
{ url: url })); | ||
} | ||
@@ -112,4 +112,4 @@ } | ||
_InternalLogging.throwInternalUserActionable( | ||
LoggingSeverity.WARNING, | ||
"message is too long, it has been trucated to " + DataSanitizer.MAX_MESSAGE_LENGTH + " characters. message: " + message); | ||
LoggingSeverity.WARNING, new _InternalLogMessage(_InternalMessageId.USRACT_MessageTruncated, "message is too long, it has been trucated to " + DataSanitizer.MAX_MESSAGE_LENGTH + " characters.", | ||
{ message: message })); | ||
} | ||
@@ -126,4 +126,4 @@ } | ||
_InternalLogging.throwInternalUserActionable( | ||
LoggingSeverity.WARNING, | ||
"exception is too long, iit has been trucated to " + DataSanitizer.MAX_EXCEPTION_LENGTH + " characters. exception: " + exception); | ||
LoggingSeverity.WARNING, new _InternalLogMessage(_InternalMessageId.USRACT_ExceptionTruncated, "exception is too long, it has been trucated to " + DataSanitizer.MAX_EXCEPTION_LENGTH + " characters.", | ||
{ exception: exception })); | ||
} | ||
@@ -130,0 +130,0 @@ } |
@@ -9,3 +9,3 @@ /// <reference path="../Contracts/Generated/EventData.ts" /> | ||
public static envelopeType = "Microsoft.ApplicationInsights.Event"; | ||
public static envelopeType = "Microsoft.ApplicationInsights.{0}.Event"; | ||
public static dataType = "EventData"; | ||
@@ -12,0 +12,0 @@ |
@@ -10,3 +10,3 @@ /// <reference path="../Contracts/Generated/ExceptionData.ts" /> | ||
public static envelopeType = "Microsoft.ApplicationInsights.Exception"; | ||
public static envelopeType = "Microsoft.ApplicationInsights.{0}.Exception"; | ||
public static dataType = "ExceptionData"; | ||
@@ -13,0 +13,0 @@ |
@@ -10,3 +10,3 @@ /// <reference path="../Contracts/Generated/MetricData.ts" /> | ||
public static envelopeType = "Microsoft.ApplicationInsights.Metric"; | ||
public static envelopeType = "Microsoft.ApplicationInsights.{0}.Metric"; | ||
public static dataType = "MetricData"; | ||
@@ -13,0 +13,0 @@ |
@@ -9,3 +9,3 @@ /// <reference path="../Contracts/Generated/PageViewData.ts" /> | ||
public static envelopeType = "Microsoft.ApplicationInsights.Pageview"; | ||
public static envelopeType = "Microsoft.ApplicationInsights.{0}.Pageview"; | ||
public static dataType = "PageviewData"; | ||
@@ -12,0 +12,0 @@ |
@@ -54,3 +54,3 @@ /// <reference path="../Contracts/Generated/PageViewData.ts" /> | ||
url, | ||
0, | ||
!isNaN(duration) ? duration : 0, | ||
properties, | ||
@@ -67,3 +67,3 @@ measurements); | ||
url, | ||
duration ? duration : customDuration, | ||
!isNaN(duration) ? duration : customDuration, | ||
properties, | ||
@@ -79,4 +79,5 @@ measurements); | ||
// no navigation timing (IE 8, iOS Safari 8.4, Opera Mini 8 - see http://caniuse.com/#feat=nav-timing) | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.WARNING, | ||
"trackPageView: navigation timing API used for calculation of page duration is not supported in this browser. This page view will be collected without duration and timing info."); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.WARNING, new _InternalLogMessage( | ||
_InternalMessageId.NONUSRACT_NavigationTimingNotSupported, | ||
"trackPageView: navigation timing API used for calculation of page duration is not supported in this browser. This page view will be collected without duration and timing info.")); | ||
return; | ||
@@ -116,3 +117,5 @@ } | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "trackPageView failed on page load calculation: " + Util.dump(e)); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, new _InternalLogMessage( | ||
_InternalMessageId.NONUSRACT_TrackPVFailedCalc, | ||
"trackPageView failed on page load calculation: " + Util.getExceptionName(e), { exception: Util.dump(e) })); | ||
} | ||
@@ -119,0 +122,0 @@ }, 100); |
@@ -10,3 +10,3 @@ /// <reference path="../Contracts/Generated/PageViewPerfData.ts"/> | ||
public static envelopeType = "Microsoft.ApplicationInsights.PageviewPerformance"; | ||
public static envelopeType = "Microsoft.ApplicationInsights.{0}.PageviewPerformance"; | ||
public static dataType = "PageviewPerformanceData"; | ||
@@ -79,6 +79,4 @@ | ||
_InternalLogging.throwInternalNonUserActionable( | ||
LoggingSeverity.WARNING, | ||
"error calculating page view performance: total='" + | ||
total + "', network='" + network + "', request='" + request + "', response='" + | ||
response + "', dom='" + dom + "'"); | ||
LoggingSeverity.WARNING, new _InternalLogMessage(_InternalMessageId.NONUSRACT_ErrorPVCalc, "error calculating page view performance.", | ||
{ total: total, network: network, request: request, response: response, dom: dom })); | ||
} else if (total < Math.floor(network) + Math.floor(request) + Math.floor(response) + Math.floor(dom)) { | ||
@@ -88,4 +86,4 @@ // some browsers may report individual components incorrectly so that the sum of the parts will be bigger than total PLT | ||
_InternalLogging.throwInternalNonUserActionable( | ||
LoggingSeverity.WARNING, | ||
"client performance math error:" + total + " < " + network + " + " + request + " + " + response + " + " + dom); | ||
LoggingSeverity.WARNING, new _InternalLogMessage(_InternalMessageId.NONUSRACT_ClientPerformanceMathError, "client performance math error.", | ||
{ total: total, network: network, request: request, response: response, dom: dom })); | ||
} else { | ||
@@ -92,0 +90,0 @@ this.durationMs = total; |
@@ -10,6 +10,7 @@ /// <reference path="../Contracts/Generated/PageViewData.ts" /> | ||
public static envelopeType = "Microsoft.ApplicationInsights.RemoteDependencyData"; | ||
public static envelopeType = "Microsoft.ApplicationInsights.{0}.RemoteDependency"; | ||
public static dataType = "RemoteDependencyData"; | ||
public aiDataContract = { | ||
id: FieldType.Required, | ||
ver: FieldType.Required, | ||
@@ -36,5 +37,6 @@ name: FieldType.Default, | ||
*/ | ||
constructor(name: string, commandName: string, value: number, success: boolean, resultCode: number) { | ||
constructor(id: string, name: string, commandName: string, value: number, success: boolean, resultCode: number) { | ||
super(); | ||
this.id = id; | ||
this.name = name; | ||
@@ -41,0 +43,0 @@ this.commandName = commandName; |
@@ -10,3 +10,3 @@ /// <reference path="../Contracts/Generated/SessionStateData.ts" /> | ||
public static envelopeType = "Microsoft.ApplicationInsights.SessionState"; | ||
public static envelopeType = "Microsoft.ApplicationInsights.{0}.SessionState"; | ||
public static dataType = "SessionStateData"; | ||
@@ -13,0 +13,0 @@ |
@@ -9,3 +9,3 @@ /// <reference path="../Contracts/Generated/MessageData.ts" /> | ||
public static envelopeType = "Microsoft.ApplicationInsights.Message"; | ||
public static envelopeType = "Microsoft.ApplicationInsights.{0}.Message"; | ||
public static dataType = "MessageData"; | ||
@@ -12,0 +12,0 @@ |
@@ -21,4 +21,4 @@ /// <reference path="sender.ts"/> | ||
sampleRate: () => number; | ||
appUserId: () => string; | ||
endpointUrl: () => string; | ||
cookieDomain: () => string; | ||
} | ||
@@ -74,3 +74,3 @@ | ||
*/ | ||
private telemetryInitializers: { (envelope: Telemetry.Common.Envelope): void; }[]; | ||
private telemetryInitializers: { (envelope: Telemetry.Common.Envelope): boolean; }[]; | ||
@@ -85,2 +85,3 @@ /** | ||
this._sender = new Sender(config); | ||
// window will be undefined in node.js where we do not want to initialize contexts | ||
@@ -95,3 +96,3 @@ if (typeof window !== 'undefined') { | ||
this.location = new Context.Location(); | ||
this.user = new Context.User(config.accountId()); | ||
this.user = new Context.User(config); | ||
this.operation = new Context.Operation(); | ||
@@ -107,3 +108,3 @@ this.session = new Context.Session(); | ||
*/ | ||
public addTelemetryInitializer(telemetryInitializer: (envelope: Telemetry.Common.Envelope) => void) { | ||
public addTelemetryInitializer(telemetryInitializer: (envelope: Telemetry.Common.Envelope) => boolean) { | ||
this.telemetryInitializers = this.telemetryInitializers || []; | ||
@@ -118,3 +119,3 @@ this.telemetryInitializers.push(telemetryInitializer); | ||
if (!envelope) { | ||
_InternalLogging.throwInternalUserActionable(LoggingSeverity.CRITICAL, "cannot call .track() with a null or undefined argument"); | ||
_InternalLogging.throwInternalUserActionable(LoggingSeverity.CRITICAL, new _InternalLogMessage(_InternalMessageId.USRACT_TrackArgumentsNotSpecified, "cannot call .track() with a null or undefined argument")); | ||
} else { | ||
@@ -160,3 +161,3 @@ // If the envelope is PageView, reset the internal message count so that we can send internal telemetry for the new page. | ||
var telemetryInitializersFailed = false; | ||
var doNotSendItem = false; | ||
try { | ||
@@ -168,20 +169,25 @@ this.telemetryInitializers = this.telemetryInitializers || []; | ||
if (telemetryInitializer) { | ||
telemetryInitializer.apply(null, [envelope]); | ||
if (telemetryInitializer.apply(null, [envelope]) === false) { | ||
doNotSendItem = true; | ||
break; | ||
} | ||
} | ||
} | ||
} catch (e) { | ||
telemetryInitializersFailed = true; | ||
doNotSendItem = true; | ||
_InternalLogging.throwInternalUserActionable( | ||
LoggingSeverity.CRITICAL, | ||
"One of telemetry initializers failed, telemetry item will not be sent: " + Util.dump(e)); | ||
LoggingSeverity.CRITICAL, new _InternalLogMessage(_InternalMessageId.USRACT_TelemetryInitializerFailed, "One of telemetry initializers failed, telemetry item will not be sent: " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) })); | ||
} | ||
if (!telemetryInitializersFailed) { | ||
if (!doNotSendItem) { | ||
if (envelope.name === Telemetry.SessionTelemetry.envelopeType || | ||
envelope.name === Telemetry.Metric.envelopeType || | ||
this.sample.isSampledIn(envelope)) { | ||
this._sender.send(envelope); | ||
var iKeyNoDashes = this._config.instrumentationKey().replace(/-/g, ""); | ||
envelope.name = envelope.name.replace("{0}", iKeyNoDashes); | ||
this._sender.send(envelope); | ||
} else { | ||
_InternalLogging.logInternalMessage(LoggingSeverity.WARNING, | ||
"Telemetry is sampled and not sent to the AI service. SampleRate is " + this.sample.sampleRate); | ||
_InternalLogging.throwInternalUserActionable(LoggingSeverity.WARNING, new _InternalLogMessage(_InternalMessageId.NONUSRACT_TelemetrySampledAndNotSent, | ||
"Telemetry is sampled and not sent to the AI service.", { SampleRate: this.sample.sampleRate })); | ||
} | ||
@@ -188,0 +194,0 @@ } |
/// <reference path="./logging.ts" /> | ||
module Microsoft.ApplicationInsights { | ||
/** | ||
* Type of storage to differentiate between local storage and session storage | ||
*/ | ||
enum StorageType { | ||
LocalStorage, | ||
SessionStorage | ||
} | ||
export class Util { | ||
@@ -12,13 +20,30 @@ private static document: any = typeof document !== "undefined" ? document : {}; | ||
*/ | ||
private static _getStorageObject(): Storage { | ||
private static _getLocalStorageObject(): Storage { | ||
return Util._getVerifiedStorageObject(StorageType.LocalStorage); | ||
} | ||
/** | ||
* Tests storage object (localStorage or sessionStorage) to verify that it is usable | ||
* More details here: https://mathiasbynens.be/notes/localstorage-pattern | ||
* @param storageType Type of storage | ||
* @return {Storage} Returns storage object verified that it is usable | ||
*/ | ||
private static _getVerifiedStorageObject(storageType: StorageType): Storage { | ||
var storage: Storage = null; | ||
var fail: boolean; | ||
var uid; | ||
try { | ||
if (window.localStorage) { | ||
return window.localStorage; | ||
} else { | ||
return null; | ||
uid = new Date; | ||
storage = storageType === StorageType.LocalStorage ? window.localStorage : window.sessionStorage; | ||
storage.setItem(uid, uid); | ||
fail = storage.getItem(uid) != uid; | ||
storage.removeItem(uid); | ||
if (fail) { | ||
storage = null; | ||
} | ||
} catch (e) { | ||
_InternalLogging.warnToConsole('Failed to get client localStorage: ' + e.message); | ||
return null; | ||
} catch (exception) { | ||
storage = null; | ||
} | ||
return storage; | ||
} | ||
@@ -32,3 +57,3 @@ | ||
public static canUseLocalStorage(): boolean { | ||
return !!Util._getStorageObject(); | ||
return !!Util._getLocalStorageObject(); | ||
} | ||
@@ -43,3 +68,3 @@ | ||
public static getStorage(name: string): string { | ||
var storage = Util._getStorageObject(); | ||
var storage = Util._getLocalStorageObject(); | ||
if (storage !== null) { | ||
@@ -49,3 +74,8 @@ try { | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.WARNING, "Browser failed read of local storage." + Util.dump(e)); | ||
var message = new _InternalLogMessage( | ||
_InternalMessageId.NONUSRACT_BrowserCannotReadLocalStorage, | ||
"Browser failed read of local storage. " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) } | ||
); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.WARNING, message); | ||
} | ||
@@ -64,3 +94,3 @@ } | ||
public static setStorage(name: string, data: string): boolean { | ||
var storage = Util._getStorageObject(); | ||
var storage = Util._getLocalStorageObject(); | ||
if (storage !== null) { | ||
@@ -71,3 +101,8 @@ try { | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.WARNING, "Browser failed write to local storage." + Util.dump(e)); | ||
var message = new _InternalLogMessage( | ||
_InternalMessageId.NONUSRACT_BrowserCannotWriteLocalStorage, | ||
"Browser failed write to local storage. " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) } | ||
); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.WARNING, message); | ||
} | ||
@@ -85,3 +120,3 @@ } | ||
public static removeStorage(name: string): boolean { | ||
var storage = Util._getStorageObject(); | ||
var storage = Util._getLocalStorageObject(); | ||
if (storage !== null) { | ||
@@ -92,3 +127,8 @@ try { | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.WARNING, "Browser failed removal of local storage item." + Util.dump(e)); | ||
var message = new _InternalLogMessage( | ||
_InternalMessageId.NONUSRACT_BrowserFailedRemovalFromLocalStorage, | ||
"Browser failed removal of local storage item. " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) } | ||
); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.WARNING, message); | ||
} | ||
@@ -100,16 +140,7 @@ } | ||
/** | ||
* Gets the localStorage object if available | ||
* Gets the sessionStorage object if available | ||
* @return {Storage} - Returns the storage object if available else returns null | ||
*/ | ||
private static _getSessionStorageObject(): Storage { | ||
try { | ||
if (window.sessionStorage) { | ||
return window.sessionStorage; | ||
} else { | ||
return null; | ||
} | ||
} catch (e) { | ||
_InternalLogging.warnToConsole('Failed to get client session storage: ' + e.message); | ||
return null; | ||
} | ||
return Util._getVerifiedStorageObject(StorageType.SessionStorage); | ||
} | ||
@@ -127,2 +158,18 @@ | ||
/** | ||
* Gets the list of session storage keys | ||
* | ||
* @returns {string[]} List of session storage keys | ||
*/ | ||
public static getSessionStorageKeys(): string[] { | ||
var keys = []; | ||
if (Util.canUseSessionStorage()) { | ||
for (var key in window.sessionStorage) { | ||
keys.push(key); | ||
} | ||
} | ||
return keys; | ||
} | ||
/** | ||
* Get an object from the browser's session storage | ||
@@ -139,3 +186,8 @@ * | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "Browser failed read of session storage." + Util.dump(e)); | ||
var message = new _InternalLogMessage( | ||
_InternalMessageId.NONUSRACT_BrowserCannotReadSessionStorage, | ||
"Browser failed read of session storage. " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) } | ||
); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, message); | ||
} | ||
@@ -160,3 +212,8 @@ } | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "Browser failed write to session storage." + Util.dump(e)); | ||
var message = new _InternalLogMessage( | ||
_InternalMessageId.NONUSRACT_BrowserCannotWriteSessionStorage, | ||
"Browser failed write to session storage. " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) } | ||
); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, message); | ||
} | ||
@@ -180,3 +237,8 @@ } | ||
} catch (e) { | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "Browser failed removal of session storage item." + Util.dump(e)); | ||
var message = new _InternalLogMessage( | ||
_InternalMessageId.NONUSRACT_BrowserFailedRemovalFromSessionStorage, | ||
"Browser failed removal of session storage item. " + Util.getExceptionName(e), | ||
{ exception: Util.dump(e) } | ||
); | ||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, message); | ||
} | ||
@@ -190,4 +252,10 @@ } | ||
*/ | ||
public static setCookie(name, value) { | ||
Util.document.cookie = name + "=" + value + ";path=/"; | ||
public static setCookie(name, value, domain?) { | ||
var domainAttrib = ""; | ||
if (domain) { | ||
domainAttrib = ";domain=" + domain; | ||
} | ||
Util.document.cookie = name + "=" + value + domainAttrib + ";path=/"; | ||
} | ||
@@ -242,3 +310,3 @@ | ||
/** | ||
* generate GUID | ||
* generate random id string | ||
*/ | ||
@@ -310,2 +378,10 @@ public static newId(): string { | ||
/** | ||
* Gets IE version if we are running on IE, or null otherwise | ||
*/ | ||
public static getIEVersion(userAgentStr: string = null): number { | ||
var myNav = userAgentStr ? userAgentStr.toLowerCase() : navigator.userAgent.toLowerCase(); | ||
return (myNav.indexOf('msie') != -1) ? parseInt(myNav.split('msie')[1]) : null; | ||
} | ||
/** | ||
* Convert ms to c# time span format | ||
@@ -351,4 +427,15 @@ */ | ||
} | ||
/** | ||
* Returns the name of object if it's an Error. Otherwise, returns empty string. | ||
*/ | ||
public static getExceptionName(object: any): string { | ||
var objectTypeDump: string = Object.prototype.toString.call(object); | ||
if (objectTypeDump === "[object Error]") { | ||
return object.name; | ||
} | ||
return ""; | ||
} | ||
/** | ||
* Adds an event handler for the specified event | ||
@@ -355,0 +442,0 @@ * @param eventName {string} - The name of the event |
{ | ||
"name": "applicationinsights-js", | ||
"version": "0.21.5", | ||
"version": "0.22.8", | ||
"description": "[Application Insights](https://azure.microsoft.com/services/application-insights/) tells you about your app's performance and usage. By adding a few lines of code to your web pages, you get data about how many users you have, which pages are most popular, how fast pages load, whether they throw exceptions, and more. And you can add code to track more detailed user activity.", | ||
@@ -5,0 +5,0 @@ "main": "dist/ai.0.js", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 2 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
13056856
217
35246
12