-
Notifications
You must be signed in to change notification settings - Fork 241
/
Initialization.ts
189 lines (160 loc) · 9.31 KB
/
Initialization.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
/// <reference path="AppInsights.ts" />
module Microsoft.ApplicationInsights {
"use strict";
export interface Snippet {
queue: Array<() => void>;
config: IConfig;
}
export class Initialization {
public snippet: Snippet;
public config: IConfig;
constructor(snippet: Snippet) {
// initialize the queue and config in case they are undefined
snippet.queue = snippet.queue || [];
var config: IConfig = snippet.config || <any>{};
// ensure instrumentationKey is specified
if (config && !config.instrumentationKey) {
config = <any>snippet;
// check for legacy instrumentation key
if (config["iKey"]) {
Microsoft.ApplicationInsights.Version = "0.10.0.0";
config.instrumentationKey = config["iKey"];
} else if (config["applicationInsightsId"]) {
Microsoft.ApplicationInsights.Version = "0.7.2.0";
config.instrumentationKey = config["applicationInsightsId"];
} else {
throw new Error("Cannot load Application Insights SDK, no instrumentationKey was provided.");
}
}
// set default values
config = Initialization.getDefaultConfig(config);
this.snippet = snippet;
this.config = config;
}
// note: these are split into methods to enable unit tests
public loadAppInsights() {
// initialize global instance of appInsights
var appInsights = new Microsoft.ApplicationInsights.AppInsights(this.config);
// implement legacy version of trackPageView for 0.10<
if (this.config["iKey"]) {
var originalTrackPageView = appInsights.trackPageView;
appInsights.trackPageView = (pagePath?: string, properties?: Object, measurements?: Object) => {
originalTrackPageView.apply(appInsights, [null, pagePath, properties, measurements]);
}
}
// implement legacy pageView interface if it is present in the snippet
var legacyPageView = "logPageView";
if (typeof this.snippet[legacyPageView] === "function") {
appInsights[legacyPageView] = (pagePath?: string, properties?: Object, measurements?: Object) => {
appInsights.trackPageView(null, pagePath, properties, measurements);
}
}
// implement legacy event interface if it is present in the snippet
var legacyEvent = "logEvent";
if (typeof this.snippet[legacyEvent] === "function") {
appInsights[legacyEvent] = (name: string, properties?: Object, measurements?: Object) => {
appInsights.trackEvent(name, properties, measurements);
}
}
return appInsights;
}
public emptyQueue() {
// call functions that were queued before the main script was loaded
try {
if (Microsoft.ApplicationInsights.Util.isArray(this.snippet.queue)) {
// note: do not check length in the for-loop conditional in case something goes wrong and the stub methods are not overridden.
var length = this.snippet.queue.length;
for (var i = 0; i < length; i++) {
var call = this.snippet.queue[i];
call();
}
this.snippet.queue = undefined;
delete this.snippet.queue;
}
} catch (exception) {
var properties: any = {};
if (exception && typeof exception.toString === "function") {
properties.exception = exception.toString();
}
Microsoft.ApplicationInsights._InternalLogging.throwInternal(
LoggingSeverity.WARNING,
_InternalMessageId.FailedToSendQueuedTelemetry,
"Failed to send queued telemetry",
properties);
}
}
public pollInteralLogs(appInsightsInstance: AppInsights) {
return setInterval(() => {
var queue: Array<_InternalLogMessage> = Microsoft.ApplicationInsights._InternalLogging.queue;
var length = queue.length;
for (var i = 0; i < length; i++) {
appInsightsInstance.trackTrace(queue[i].message);
}
queue.length = 0;
}, this.config.diagnosticLogInterval);
}
public addHousekeepingBeforeUnload(appInsightsInstance: AppInsights): void {
// Add callback to push events when the user navigates away
if (!appInsightsInstance.config.disableFlushOnBeforeUnload && ('onbeforeunload' in window)) {
var performHousekeeping = function () {
// Adds the ability to flush all data before the page unloads.
// Note: This approach tries to push an async request with all the pending events onbeforeunload.
// Firefox does not respect this.Other browsers DO push out the call with < 100% hit rate.
// Telemetry here will help us analyze how effective this approach is.
// Another approach would be to make this call sync with a acceptable timeout to reduce the
// impact on user experience.
appInsightsInstance.context._sender.triggerSend();
// Back up the current session to local storage
// This lets us close expired sessions after the cookies themselves expire
appInsightsInstance.context._sessionManager.backup();
};
if (!Microsoft.ApplicationInsights.Util.addEventHandler('beforeunload', performHousekeeping)) {
Microsoft.ApplicationInsights._InternalLogging.throwInternal(
Microsoft.ApplicationInsights.LoggingSeverity.CRITICAL,
Microsoft.ApplicationInsights._InternalMessageId.FailedToAddHandlerForOnBeforeUnload,
'Could not add handler for beforeunload');
}
}
}
public static getDefaultConfig(config?: IConfig): IConfig {
if (!config) {
config = <IConfig>{};
}
// set default values
config.endpointUrl = config.endpointUrl || "https://dc.services.visualstudio.com/v2/track";
config.sessionRenewalMs = 30 * 60 * 1000;
config.sessionExpirationMs = 24 * 60 * 60 * 1000;
config.maxBatchSizeInBytes = config.maxBatchSizeInBytes > 0 ? config.maxBatchSizeInBytes : 102400; // 100kb
config.maxBatchInterval = !isNaN(config.maxBatchInterval) ? config.maxBatchInterval : 15000;
config.enableDebug = Util.stringToBoolOrDefault(config.enableDebug);
config.disableExceptionTracking = Util.stringToBoolOrDefault(config.disableExceptionTracking);
config.disableTelemetry = Util.stringToBoolOrDefault(config.disableTelemetry);
config.verboseLogging = Util.stringToBoolOrDefault(config.verboseLogging);
config.emitLineDelimitedJson = Util.stringToBoolOrDefault(config.emitLineDelimitedJson);
config.diagnosticLogInterval = config.diagnosticLogInterval || 10000;
config.autoTrackPageVisitTime = Util.stringToBoolOrDefault(config.autoTrackPageVisitTime);
if (isNaN(config.samplingPercentage) || config.samplingPercentage <= 0 || config.samplingPercentage >= 100) {
config.samplingPercentage = 100;
}
config.disableAjaxTracking = Util.stringToBoolOrDefault(config.disableAjaxTracking);
config.maxAjaxCallsPerView = !isNaN(config.maxAjaxCallsPerView) ? config.maxAjaxCallsPerView : 500;
config.isBeaconApiDisabled = Util.stringToBoolOrDefault(config.isBeaconApiDisabled, true);
config.disableCorrelationHeaders = Util.stringToBoolOrDefault(config.disableCorrelationHeaders);
config.correlationHeaderExcludedDomains = config.correlationHeaderExcludedDomains || [
"*.blob.core.windows.net",
"*.blob.core.chinacloudapi.cn",
"*.blob.core.cloudapi.de",
"*.blob.core.usgovcloudapi.net"];
config.disableFlushOnBeforeUnload = Util.stringToBoolOrDefault(config.disableFlushOnBeforeUnload);
config.enableSessionStorageBuffer = Util.stringToBoolOrDefault(config.enableSessionStorageBuffer, true);
config.isRetryDisabled = Util.stringToBoolOrDefault(config.isRetryDisabled);
config.isCookieUseDisabled = Util.stringToBoolOrDefault(config.isCookieUseDisabled);
config.isStorageUseDisabled = Util.stringToBoolOrDefault(config.isStorageUseDisabled);
config.isBrowserLinkTrackingEnabled = Util.stringToBoolOrDefault(config.isBrowserLinkTrackingEnabled);
config.enableCorsCorrelation = Util.stringToBoolOrDefault(config.enableCorsCorrelation);
return config;
}
}
}