@oneteme/inspect-ng-collector 1.2.0 → 1.3.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,142 +1,41 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import { Injectable, inject, APP_INITIALIZER, ErrorHandler, NgModule } from '@angular/core';
|
|
3
3
|
import { HttpResponse, HTTP_INTERCEPTORS } from '@angular/common/http';
|
|
4
|
-
import {
|
|
5
|
-
import { tap
|
|
6
|
-
import {
|
|
7
|
-
import { DOCUMENT } from '@angular/common';
|
|
4
|
+
import { finalize, interval, startWith, tap as tap$1 } from 'rxjs';
|
|
5
|
+
import { tap } from 'rxjs/operators';
|
|
6
|
+
import { NavigationStart, NavigationEnd, Router } from '@angular/router';
|
|
8
7
|
|
|
9
8
|
const WIN = window;
|
|
10
9
|
function dateNow() {
|
|
11
10
|
return Date.now() / 1_000;
|
|
12
11
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
console.log(`[INSPECT]-(${level})`, ...args);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
function prettyActionUserFormat(session, userAction) {
|
|
28
|
-
let s = `(${session.location}) `;
|
|
29
|
-
if (userAction.type) {
|
|
30
|
-
s += `[${userAction.type}]`;
|
|
31
|
-
}
|
|
32
|
-
if (userAction.nodeName) {
|
|
33
|
-
s += `<${userAction.nodeName}>`;
|
|
34
|
-
}
|
|
35
|
-
if (userAction.name) {
|
|
36
|
-
s += `(${userAction.name}) `;
|
|
37
|
-
}
|
|
38
|
-
s += ` >> ${new Date(userAction.start * 1000).toISOString()}`;
|
|
39
|
-
return s;
|
|
40
|
-
}
|
|
41
|
-
function prettySessionFormat(session) {
|
|
42
|
-
let s = `[${session.name}]`;
|
|
43
|
-
if (session.user) {
|
|
44
|
-
s += `<${session.user}>`;
|
|
45
|
-
}
|
|
46
|
-
if (session.location) {
|
|
47
|
-
s += `(${session.location}) `;
|
|
48
|
-
}
|
|
49
|
-
s += prettyDurationFormat(session.start, session.end) + '\n';
|
|
50
|
-
session.restRequests.forEach(r => {
|
|
51
|
-
s += prettyRestRequestFormat(r) + '\n';
|
|
52
|
-
});
|
|
53
|
-
session.localRequests.forEach(r => {
|
|
54
|
-
s += prettyLocalRequestFormat(r) + '\n';
|
|
55
|
-
});
|
|
56
|
-
return s;
|
|
57
|
-
}
|
|
58
|
-
function prettyRestRequestFormat(rest) {
|
|
59
|
-
let s = ` - [${rest.method}]`;
|
|
60
|
-
if (rest.protocol) {
|
|
61
|
-
s += `${rest.protocol}://`;
|
|
62
|
-
}
|
|
63
|
-
if (rest.host) {
|
|
64
|
-
s += rest.host;
|
|
65
|
-
}
|
|
66
|
-
if (rest.port > 0) {
|
|
67
|
-
s += `:${rest.port}`;
|
|
68
|
-
}
|
|
69
|
-
if (rest.path) {
|
|
70
|
-
if (!rest.path.startsWith("/") && !s.endsWith("/")) {
|
|
71
|
-
s += '/';
|
|
72
|
-
}
|
|
73
|
-
s += rest.path;
|
|
74
|
-
}
|
|
75
|
-
if (rest.query) {
|
|
76
|
-
s += rest.query;
|
|
77
|
-
}
|
|
78
|
-
if (rest.exception?.type) {
|
|
79
|
-
s += ` ${rest.exception?.type}:`;
|
|
80
|
-
}
|
|
81
|
-
if (rest.exception?.message) {
|
|
82
|
-
s += ` ${rest.exception.message}`;
|
|
83
|
-
}
|
|
84
|
-
s += ` >> ${rest.status}`;
|
|
85
|
-
s += prettyDurationFormat(rest.start, rest.end);
|
|
86
|
-
return s;
|
|
87
|
-
}
|
|
88
|
-
function prettyLocalRequestFormat(local) {
|
|
89
|
-
let s = ` - [${local.name}]`;
|
|
90
|
-
if (local.location) {
|
|
91
|
-
s += `(${local.location})`;
|
|
92
|
-
}
|
|
93
|
-
if (local.exception?.type) {
|
|
94
|
-
s += ` ${local.exception?.type}:`;
|
|
95
|
-
}
|
|
96
|
-
if (local.exception?.message) {
|
|
97
|
-
s += ` ${local.exception.message}`;
|
|
98
|
-
}
|
|
99
|
-
s += ` >> ${prettyDurationFormat(local.start, local.end)}`;
|
|
100
|
-
return s;
|
|
101
|
-
}
|
|
102
|
-
function prettyDurationFormat(start, end) {
|
|
103
|
-
return start && end ? `(in ${(end - start).toFixed(2)} s)` : '';
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const SLASH = '/';
|
|
107
|
-
const HOST_PATERN = /https?:\/\/[\w\-.]+(:\d{2,5})?\/?/;
|
|
108
|
-
const PATH_PATERN = /[\w-]+(\/[\w-]+)*/;
|
|
109
|
-
function validateAndGetConfig(conf) {
|
|
110
|
-
let host = matchRegex(getStringOrCall(conf.host), "host", HOST_PATERN);
|
|
111
|
-
let sessionApi = matchRegex(getStringOrCall(conf.sessionApi), "sessionApi", PATH_PATERN, "v3/trace/instance/:id/session");
|
|
112
|
-
let instanceApi = matchRegex(getStringOrCall(conf.instanceApi), "intanceApi", PATH_PATERN, "v3/trace/instance");
|
|
113
|
-
initDebug(conf.debug ?? { app: false, user: false });
|
|
12
|
+
var RequestMask;
|
|
13
|
+
(function (RequestMask) {
|
|
14
|
+
RequestMask[RequestMask["LOCAL"] = 1] = "LOCAL";
|
|
15
|
+
RequestMask[RequestMask["REST"] = 4] = "REST";
|
|
16
|
+
})(RequestMask || (RequestMask = {}));
|
|
17
|
+
const DISPATCH = 'dispatch';
|
|
18
|
+
const PRE_DISPATCH = 'pre-dispatch';
|
|
19
|
+
const BEFOREUNLOAD = 'beforeunload';
|
|
20
|
+
function createLogEntry(level, message, sessionId) {
|
|
114
21
|
return {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
exclude: getRegArrOrCall(conf.exclude) || [],
|
|
121
|
-
debug: conf.debug ?? { app: false, user: false },
|
|
122
|
-
analytics: conf.analytics ?? false,
|
|
123
|
-
enabled: conf.enabled ?? false
|
|
22
|
+
"@type": "log",
|
|
23
|
+
level: level,
|
|
24
|
+
message: message,
|
|
25
|
+
instant: dateNow(),
|
|
26
|
+
sessionId: sessionId
|
|
124
27
|
};
|
|
125
28
|
}
|
|
126
|
-
function
|
|
29
|
+
function createReport(message) {
|
|
127
30
|
return {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
env: require(getStringOrCall(conf.env), 'env'),
|
|
132
|
-
os: detectOs(),
|
|
133
|
-
re: detectBrowser(),
|
|
134
|
-
user: undefined, // cannot get user
|
|
135
|
-
type: "CLIENT",
|
|
31
|
+
"@type": "log",
|
|
32
|
+
level: "ERROR",
|
|
33
|
+
message: message,
|
|
136
34
|
instant: dateNow(),
|
|
137
|
-
collector: "inspect-ng-collector-0.0.1"
|
|
138
35
|
};
|
|
139
36
|
}
|
|
37
|
+
|
|
38
|
+
const SLASH$1 = '/';
|
|
140
39
|
function getNumberOrCall(o) {
|
|
141
40
|
return typeof o === "function" ? o() : o;
|
|
142
41
|
}
|
|
@@ -191,14 +90,14 @@ function detectOs() {
|
|
|
191
90
|
}
|
|
192
91
|
return undefined;
|
|
193
92
|
}
|
|
194
|
-
function instanceApiURL(host, path) {
|
|
195
|
-
return toURL(host, path);
|
|
93
|
+
function instanceApiURL$1(host, path) {
|
|
94
|
+
return toURL$1(host, path);
|
|
196
95
|
}
|
|
197
|
-
function sessionApiURL(host, path) {
|
|
198
|
-
return toURL(host, path);
|
|
96
|
+
function sessionApiURL$1(host, path) {
|
|
97
|
+
return toURL$1(host, path);
|
|
199
98
|
}
|
|
200
|
-
function toURL(host, path) {
|
|
201
|
-
return host.endsWith(SLASH) || path.startsWith(SLASH) ? host + path : [host, path].join(SLASH);
|
|
99
|
+
function toURL$1(host, path) {
|
|
100
|
+
return host.endsWith(SLASH$1) || path.startsWith(SLASH$1) ? host + path : [host, path].join(SLASH$1);
|
|
202
101
|
}
|
|
203
102
|
function matchRegex(v, name, pattern, defaultValue) {
|
|
204
103
|
if (v && pattern.exec(v)) {
|
|
@@ -229,27 +128,115 @@ function require(v, name) {
|
|
|
229
128
|
}
|
|
230
129
|
throw new Error(`${name} property is required`);
|
|
231
130
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
.
|
|
243
|
-
.
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
131
|
+
function adaptedConfig(conf) {
|
|
132
|
+
return {
|
|
133
|
+
...conf,
|
|
134
|
+
scheduling: {
|
|
135
|
+
...conf.scheduling,
|
|
136
|
+
interval: conf.scheduling?.interval && conf.scheduling.interval / 1000
|
|
137
|
+
},
|
|
138
|
+
monitoring: {
|
|
139
|
+
...conf.monitoring,
|
|
140
|
+
additionalProperties: String(conf.monitoring?.additionalProperties),
|
|
141
|
+
name: String(conf.monitoring?.name),
|
|
142
|
+
version: String(conf.monitoring?.version),
|
|
143
|
+
env: String(conf.monitoring?.env),
|
|
144
|
+
user: String(conf.monitoring?.user),
|
|
145
|
+
httpRoute: {
|
|
146
|
+
...conf.monitoring?.httpRoute,
|
|
147
|
+
excludes: {
|
|
148
|
+
path: (conf?.monitoring?.httpRoute?.excludes?.path).map(r => r.source) // convert to string array to conform to backend expectation
|
|
149
|
+
}
|
|
247
150
|
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
|
|
151
|
+
},
|
|
152
|
+
tracing: {
|
|
153
|
+
...conf.tracing,
|
|
154
|
+
remote: {
|
|
155
|
+
...conf.tracing?.remote,
|
|
156
|
+
'@type': "rest-rmt", // add this to conform to backend expectation
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const SLASH = '/';
|
|
163
|
+
const HOST_PATERN = /https?:\/\/[\w\-.]+(:\d{2,5})?\/?/;
|
|
164
|
+
class ContextManager {
|
|
165
|
+
constructor(_instanceEnv, _techConfig) {
|
|
166
|
+
this._instanceEnv = _instanceEnv;
|
|
167
|
+
this._techConfig = _techConfig;
|
|
168
|
+
}
|
|
169
|
+
get techConfig() {
|
|
170
|
+
return this._techConfig;
|
|
171
|
+
}
|
|
172
|
+
get instanceEnv() {
|
|
173
|
+
return this._instanceEnv;
|
|
251
174
|
}
|
|
252
175
|
static get instance() {
|
|
176
|
+
if (!ContextManager._instance) {
|
|
177
|
+
console.warn("[Inspect-ng-collecotor] Error while initializing ContextManager");
|
|
178
|
+
}
|
|
179
|
+
return ContextManager._instance;
|
|
180
|
+
}
|
|
181
|
+
static init(conf) {
|
|
182
|
+
let id = crypto.randomUUID();
|
|
183
|
+
return ContextManager._instance = new ContextManager(ContextManager.createInstance(conf, id), ContextManager.validateAndGetConfig(conf, id));
|
|
184
|
+
}
|
|
185
|
+
static validateAndGetConfig(conf, instanceId) {
|
|
186
|
+
let host = matchRegex(getStringOrCall(conf?.tracing?.remote?.host), "host", HOST_PATERN);
|
|
187
|
+
let sessionApi = "v4/trace/instance/:id/session";
|
|
188
|
+
let instanceApi = "v4/trace/instance";
|
|
189
|
+
return {
|
|
190
|
+
user: getStringOrCall(conf?.monitoring?.user),
|
|
191
|
+
queueCapacity: requirePostitiveValue(getNumberOrCall(conf?.tracing?.queueCapacity), "queueCapacity", 1000),
|
|
192
|
+
interval: requirePostitiveValue(getNumberOrCall(conf?.scheduling?.interval), "interval", 60000),
|
|
193
|
+
delayIfPending: requirePostitiveValue(getNumberOrCall(conf?.tracing?.delayIfPending), "delayIfPending", 30),
|
|
194
|
+
instanceApi: sessionApiURL(host, instanceApi),
|
|
195
|
+
sessionApi: instanceApiURL(host, sessionApi).replace(':id', instanceId),
|
|
196
|
+
exclude: getRegArrOrCall(conf?.monitoring?.httpRoute?.excludes?.path) || [],
|
|
197
|
+
hostExcludes: conf?.monitoring?.httpRequest?.excludes?.host || [],
|
|
198
|
+
debugMode: conf.debugMode ?? false,
|
|
199
|
+
analytics: conf?.monitoring?.analytics?.enabled ?? false,
|
|
200
|
+
resources: conf?.monitoring?.resources?.enabled ?? false,
|
|
201
|
+
storage: conf?.monitoring?.storage?.enabled ?? false,
|
|
202
|
+
enabled: conf.enabled ?? false
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
static createInstance(conf, instanceId) {
|
|
206
|
+
return {
|
|
207
|
+
id: instanceId,
|
|
208
|
+
name: require(getStringOrCall(conf?.monitoring?.name), 'name'),
|
|
209
|
+
version: getStringOrCall(conf?.monitoring?.version),
|
|
210
|
+
address: undefined, //server side
|
|
211
|
+
env: require(getStringOrCall(conf?.monitoring?.env), 'env'),
|
|
212
|
+
os: detectOs(),
|
|
213
|
+
re: detectBrowser(),
|
|
214
|
+
user: undefined, // cannot get user
|
|
215
|
+
type: "CLIENT",
|
|
216
|
+
instant: dateNow(),
|
|
217
|
+
collector: "inspect-ng-collector-0.0.1",
|
|
218
|
+
resource: { maxHeap: (('memory' in performance) && performance.memory.jsHeapSizeLimit / (1024 * 1024)) || undefined },
|
|
219
|
+
additionalProperties: conf?.monitoring?.additionalProperties(),
|
|
220
|
+
configuration: adaptedConfig(conf)
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
function instanceApiURL(host, path) {
|
|
225
|
+
return toURL(host, path);
|
|
226
|
+
}
|
|
227
|
+
function sessionApiURL(host, path) {
|
|
228
|
+
return toURL(host, path);
|
|
229
|
+
}
|
|
230
|
+
function toURL(host, path) {
|
|
231
|
+
return host.endsWith(SLASH) || path.startsWith(SLASH) ? host + path : [host, path].join(SLASH);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
class SessionManager {
|
|
235
|
+
static get instance() {
|
|
236
|
+
if (!SessionManager._instance) {
|
|
237
|
+
SessionManager._instance = new SessionManager();
|
|
238
|
+
WIN["inspect-session-manager"] = SessionManager._instance;
|
|
239
|
+
}
|
|
253
240
|
return SessionManager._instance;
|
|
254
241
|
}
|
|
255
242
|
newSession(url) {
|
|
@@ -257,178 +244,115 @@ class SessionManager {
|
|
|
257
244
|
this.currentSession.end = dateNow();
|
|
258
245
|
this.currentSession.name = document.title;
|
|
259
246
|
this.currentSession.location = document.URL;
|
|
260
|
-
if (
|
|
261
|
-
|
|
262
|
-
logInspect('app', `added element to session queue, new size is:${this.sessionQueue.length}`);
|
|
247
|
+
if (!ContextManager.instance.techConfig.exclude?.some((e) => e.test(this.currentSession.location))) {
|
|
248
|
+
window.dispatchEvent(new CustomEvent(DISPATCH, { detail: { traces: this.currentSession } }));
|
|
263
249
|
}
|
|
264
|
-
logInspect('app', () => prettySessionFormat(this.currentSession));
|
|
265
250
|
}
|
|
266
251
|
if (url) {
|
|
267
252
|
this.currentSession = {
|
|
268
|
-
'@type': "main",
|
|
269
|
-
|
|
253
|
+
'@type': "main-ses",
|
|
254
|
+
id: crypto.randomUUID(),
|
|
255
|
+
user: "",
|
|
270
256
|
start: dateNow(),
|
|
271
257
|
type: "VIEW",
|
|
272
258
|
location: url,
|
|
273
259
|
loading: true,
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
userActions: [],
|
|
277
|
-
exceptions: []
|
|
260
|
+
exceptions: [],
|
|
261
|
+
requestsMask: 0
|
|
278
262
|
};
|
|
263
|
+
window.dispatchEvent(new CustomEvent(DISPATCH, { detail: { traces: this.currentSession } }));
|
|
279
264
|
}
|
|
280
265
|
}
|
|
281
|
-
|
|
282
|
-
if (this.
|
|
283
|
-
return this.
|
|
284
|
-
}
|
|
285
|
-
return this.postInstanceEnv().then((id) => {
|
|
286
|
-
if (id) {
|
|
287
|
-
return this.sendSessions();
|
|
288
|
-
}
|
|
289
|
-
console.warn(`Error while attempting to send Environement instance, attempts ${this.sessionSendAttempts}`);
|
|
290
|
-
return Promise.reject(new Error('No instance id'));
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
sendSessions(instanceComplete) {
|
|
294
|
-
if (this.sessionQueue.length > 0) {
|
|
295
|
-
if (instanceComplete) {
|
|
296
|
-
this.config.sessionApi += "?end=" + new Date().toISOString();
|
|
297
|
-
}
|
|
298
|
-
this.sessionSendAttempts++;
|
|
299
|
-
let sessions = [...this.sessionQueue];
|
|
300
|
-
this.sessionQueue.splice(0, sessions.length); // add rest of sessions
|
|
301
|
-
logInspect('app', `sending sessions, attempts:${this.sessionSendAttempts}, queue size : ${sessions.length}`);
|
|
302
|
-
return this.putSessions(sessions)
|
|
303
|
-
.then(ok => {
|
|
304
|
-
if (ok) {
|
|
305
|
-
logInspect('app', `sessions sent successfully, queue size reset, new size is: ${this.sessionQueue.length}`);
|
|
306
|
-
this.sessionSendAttempts = 0;
|
|
307
|
-
return sessions.length;
|
|
308
|
-
}
|
|
309
|
-
else {
|
|
310
|
-
console.warn(`Error while attempting to send sessions, attempts: ${this.sessionSendAttempts}`); //
|
|
311
|
-
this.revertQueueSize(sessions);
|
|
312
|
-
return -1;
|
|
313
|
-
}
|
|
314
|
-
});
|
|
266
|
+
currentSessionID() {
|
|
267
|
+
if (this.currentSession) {
|
|
268
|
+
return this.currentSession.id;
|
|
315
269
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
putSessions(sessionList) {
|
|
319
|
-
return fetch(this.config.sessionApi, {
|
|
320
|
-
method: 'PUT',
|
|
321
|
-
headers: { 'Content-Type': 'application/json' },
|
|
322
|
-
mode: 'cors',
|
|
323
|
-
body: JSON.stringify(sessionList)
|
|
324
|
-
})
|
|
325
|
-
.then(res => res.ok)
|
|
326
|
-
.catch(err => false);
|
|
270
|
+
window.dispatchEvent(new CustomEvent(DISPATCH, { detail: { traces: createReport("no active session found ") } }));
|
|
271
|
+
return undefined;
|
|
327
272
|
}
|
|
328
|
-
|
|
329
|
-
this.
|
|
330
|
-
return fetch(this.config.instanceApi, {
|
|
331
|
-
method: 'POST',
|
|
332
|
-
headers: { 'Content-Type': 'application/json' },
|
|
333
|
-
mode: 'cors',
|
|
334
|
-
body: JSON.stringify(this.instanceEnvironment)
|
|
335
|
-
})
|
|
336
|
-
.then(res => res.ok ? res.text().then(id => {
|
|
337
|
-
this.config.sessionApi = this.config.sessionApi.replace(':id', id);
|
|
338
|
-
logInspect('app', 'Environement instance sent successfully', id);
|
|
339
|
-
this.sessionSendAttempts = 0;
|
|
340
|
-
return this.instanceEnvironment.id = id;
|
|
341
|
-
}) : null)
|
|
342
|
-
.catch(err => null);
|
|
273
|
+
getCurrentSession() {
|
|
274
|
+
return this.currentSession;
|
|
343
275
|
}
|
|
344
|
-
|
|
345
|
-
this.
|
|
346
|
-
|
|
347
|
-
let diff = this.sessionQueue.length - this.config.bufferMaxSize;
|
|
348
|
-
this.sessionQueue = this.sessionQueue.slice(0, this.config.bufferMaxSize);
|
|
349
|
-
logInspect('app', `Buffer size exeeded the max size,last sessions have been removed from buffer, (number of sessions removed):${diff}`);
|
|
276
|
+
updateMask(requestMask) {
|
|
277
|
+
if (this.currentSession) {
|
|
278
|
+
this.currentSession.requestsMask |= requestMask;
|
|
350
279
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
if (this.scheduledSessionSender) {
|
|
354
|
-
this.scheduledSessionSender.unsubscribe();
|
|
280
|
+
else {
|
|
281
|
+
window.dispatchEvent(new CustomEvent(DISPATCH, { detail: { traces: createReport("no active session found ") } }));
|
|
355
282
|
}
|
|
356
283
|
}
|
|
357
|
-
|
|
358
|
-
|
|
284
|
+
addException(exception) {
|
|
285
|
+
if (this.currentSession) {
|
|
286
|
+
this.currentSession.exceptions.push(exception);
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
window.dispatchEvent(new CustomEvent(DISPATCH, { detail: { traces: createReport("no active session found ") } }));
|
|
290
|
+
}
|
|
359
291
|
}
|
|
360
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: SessionManager, deps: [{ token: 'config' }, { token: 'instance' }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
361
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: SessionManager, providedIn: 'root' }); }
|
|
362
292
|
}
|
|
363
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: SessionManager, decorators: [{
|
|
364
|
-
type: Injectable,
|
|
365
|
-
args: [{ providedIn: 'root' }]
|
|
366
|
-
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
367
|
-
type: Inject,
|
|
368
|
-
args: ['config']
|
|
369
|
-
}] }, { type: undefined, decorators: [{
|
|
370
|
-
type: Inject,
|
|
371
|
-
args: ['instance']
|
|
372
|
-
}] }] });
|
|
373
293
|
|
|
374
|
-
class
|
|
375
|
-
constructor(
|
|
376
|
-
this.SessionManager = SessionManager;
|
|
377
|
-
} // change this to session manager
|
|
378
|
-
intercept(req, next) {
|
|
294
|
+
class RestRequestMonitor {
|
|
295
|
+
constructor(restRequest) {
|
|
379
296
|
const start = dateNow();
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
297
|
+
const url = toHref(restRequest.urlWithParams);
|
|
298
|
+
const auth_user = extractAuthSchemeAnduser(restRequest.headers);
|
|
299
|
+
this.restRequest = {
|
|
300
|
+
"@type": "http-req",
|
|
301
|
+
id: crypto.randomUUID(),
|
|
302
|
+
method: restRequest.method,
|
|
303
|
+
protocol: url.protocol.slice(0, -1),
|
|
304
|
+
host: exctractHost(url.host),
|
|
305
|
+
port: +url.port || -1,
|
|
306
|
+
path: url.pathname,
|
|
307
|
+
query: url.search.slice(1, url.search.length),
|
|
308
|
+
contentType: restRequest.responseType,
|
|
309
|
+
authScheme: auth_user.authScheme,
|
|
310
|
+
user: auth_user.user,
|
|
311
|
+
ouDataSize: sizeOf(restRequest.body),
|
|
312
|
+
start: start,
|
|
313
|
+
sessionId: SessionManager.instance.currentSessionID()
|
|
314
|
+
};
|
|
315
|
+
SessionManager.instance.updateMask(RequestMask.REST);
|
|
316
|
+
}
|
|
317
|
+
postProcess(event, error) {
|
|
318
|
+
let status = 0, exception = null;
|
|
319
|
+
if (event) {
|
|
320
|
+
status = +event.status;
|
|
321
|
+
this.restRequest.inDataSize = sizeOf(event.body);
|
|
322
|
+
this.assertSessionID(this.restRequest.id, event.headers);
|
|
323
|
+
}
|
|
324
|
+
if (error) {
|
|
325
|
+
this.assertSessionID(this.restRequest.id, error?.headers);
|
|
390
326
|
status = +error.status;
|
|
391
327
|
exception = {
|
|
392
328
|
type: error.name,
|
|
393
329
|
message: error.error && error.status ? JSON.stringify(error.error) : error.message
|
|
394
330
|
};
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
exception: exception
|
|
417
|
-
});
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
catch (err) {
|
|
421
|
-
console.warn(err);
|
|
331
|
+
}
|
|
332
|
+
this.restRequest.end = dateNow();
|
|
333
|
+
this.restRequest.status = +status;
|
|
334
|
+
let stage = {
|
|
335
|
+
"@type": "http-stg",
|
|
336
|
+
name: "PROCESS",
|
|
337
|
+
start: this.restRequest.start,
|
|
338
|
+
end: dateNow(),
|
|
339
|
+
order: 0,
|
|
340
|
+
exception: exception,
|
|
341
|
+
requestId: this.restRequest.id
|
|
342
|
+
};
|
|
343
|
+
window.dispatchEvent(new CustomEvent(DISPATCH, { detail: { traces: this.restRequest } }));
|
|
344
|
+
window.dispatchEvent(new CustomEvent(DISPATCH, { detail: { traces: stage } }));
|
|
345
|
+
}
|
|
346
|
+
assertSessionID(id, headers) {
|
|
347
|
+
if (headers?.has('x-tracert')) {
|
|
348
|
+
if (id !== headers.get('x-tracert')) {
|
|
349
|
+
window.dispatchEvent(new CustomEvent(DISPATCH, {
|
|
350
|
+
detail: { traces: createReport("The received x-tracert header (" + headers.get('x-tracert') + ") does not match the request id (" + id + ")") }
|
|
351
|
+
}));
|
|
422
352
|
}
|
|
423
|
-
}
|
|
353
|
+
}
|
|
424
354
|
}
|
|
425
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: HttpInterceptorService, deps: [{ token: SessionManager }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
426
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: HttpInterceptorService, providedIn: 'root' }); }
|
|
427
355
|
}
|
|
428
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: HttpInterceptorService, decorators: [{
|
|
429
|
-
type: Injectable,
|
|
430
|
-
args: [{ providedIn: 'root' }]
|
|
431
|
-
}], ctorParameters: () => [{ type: SessionManager }] });
|
|
432
356
|
function toHref(url) {
|
|
433
357
|
const href = document.createElement('a');
|
|
434
358
|
href.setAttribute('href', url);
|
|
@@ -444,7 +368,7 @@ function extractAuthSchemeAnduser(headers) {
|
|
|
444
368
|
authScheme: undefined
|
|
445
369
|
};
|
|
446
370
|
try {
|
|
447
|
-
auth_user.authScheme = headers.get('authorization').match(/^(\w+) /)?.at(1);
|
|
371
|
+
auth_user.authScheme = headers.has('authorization') && headers.get('authorization').match(/^(\w+) /)?.at(1);
|
|
448
372
|
switch (auth_user.authScheme) {
|
|
449
373
|
case "Basic":
|
|
450
374
|
auth_user.user = atob(headers.get('authorization').split(" ")[1]).toString().split(':')[0];
|
|
@@ -457,18 +381,216 @@ function extractAuthSchemeAnduser(headers) {
|
|
|
457
381
|
}
|
|
458
382
|
}
|
|
459
383
|
}
|
|
460
|
-
catch (err) {
|
|
384
|
+
catch (err) {
|
|
385
|
+
createReport(JSON.stringify(err));
|
|
386
|
+
}
|
|
461
387
|
return auth_user;
|
|
462
388
|
}
|
|
463
|
-
function getReqid(headers) {
|
|
464
|
-
return headers.has('x-tracert')
|
|
465
|
-
? headers.get('x-tracert')
|
|
466
|
-
: undefined;
|
|
467
|
-
}
|
|
468
389
|
function sizeOf(body) {
|
|
469
390
|
return body ? JSON.stringify(body).length : 0;
|
|
470
391
|
}
|
|
471
392
|
|
|
393
|
+
class HttpInterceptorService {
|
|
394
|
+
constructor() { }
|
|
395
|
+
intercept(req, next) {
|
|
396
|
+
let restRequestMonitor = new RestRequestMonitor(req);
|
|
397
|
+
let e;
|
|
398
|
+
window.dispatchEvent(new CustomEvent(DISPATCH, { detail: { traces: restRequestMonitor.restRequest } }));
|
|
399
|
+
const host = new URL(req.url, window.location.origin).host;
|
|
400
|
+
if (!ContextManager.instance.techConfig.hostExcludes?.some((e) => e == host)) {
|
|
401
|
+
req = req.clone({ headers: req.headers.set('x-tracert', restRequestMonitor.restRequest.id) });
|
|
402
|
+
}
|
|
403
|
+
return next.handle(req).pipe(tap((event) => {
|
|
404
|
+
if (event instanceof HttpResponse) {
|
|
405
|
+
e = event;
|
|
406
|
+
}
|
|
407
|
+
}, error => {
|
|
408
|
+
e = error;
|
|
409
|
+
}), finalize(() => {
|
|
410
|
+
e instanceof HttpResponse ? restRequestMonitor.postProcess(e, null) : restRequestMonitor.postProcess(null, e ?? {
|
|
411
|
+
status: 0,
|
|
412
|
+
name: "IOException",
|
|
413
|
+
message: "The remote server is unavailable.",
|
|
414
|
+
});
|
|
415
|
+
}));
|
|
416
|
+
}
|
|
417
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: HttpInterceptorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
418
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: HttpInterceptorService, providedIn: 'root' }); }
|
|
419
|
+
}
|
|
420
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: HttpInterceptorService, decorators: [{
|
|
421
|
+
type: Injectable,
|
|
422
|
+
args: [{ providedIn: 'root' }]
|
|
423
|
+
}], ctorParameters: () => [] });
|
|
424
|
+
|
|
425
|
+
class GlobalErrorHandlerService {
|
|
426
|
+
handleError(error) {
|
|
427
|
+
try {
|
|
428
|
+
SessionManager.instance.addException({
|
|
429
|
+
type: error?.name,
|
|
430
|
+
message: error?.message
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
catch (e) {
|
|
434
|
+
window.dispatchEvent(new CustomEvent(DISPATCH, { detail: { traces: createReport("Erreur dans GlobalErrorHandlerService: " + JSON.stringify(e)) } }));
|
|
435
|
+
}
|
|
436
|
+
throw error;
|
|
437
|
+
}
|
|
438
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: GlobalErrorHandlerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
439
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: GlobalErrorHandlerService, providedIn: 'root' }); }
|
|
440
|
+
}
|
|
441
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: GlobalErrorHandlerService, decorators: [{
|
|
442
|
+
type: Injectable,
|
|
443
|
+
args: [{ providedIn: 'root' }]
|
|
444
|
+
}] });
|
|
445
|
+
|
|
446
|
+
function eventTraceScheduledDispatcher() {
|
|
447
|
+
return EventTraceScheduledDispatcherService._instance = new EventTraceScheduledDispatcherService();
|
|
448
|
+
}
|
|
449
|
+
class EventTraceScheduledDispatcherService {
|
|
450
|
+
constructor() {
|
|
451
|
+
this.traceQueue = new Set();
|
|
452
|
+
this.sessionSendAttempts = 0;
|
|
453
|
+
this.sendSessionfinished = true;
|
|
454
|
+
this.instanceSaved = false;
|
|
455
|
+
interval(ContextManager.instance.techConfig.interval)
|
|
456
|
+
.pipe(startWith(0))
|
|
457
|
+
.pipe(tap$1(() => {
|
|
458
|
+
if (this.sendSessionfinished) {
|
|
459
|
+
this.sendSessionfinished = false;
|
|
460
|
+
setTimeout(() => window.dispatchEvent(new CustomEvent(PRE_DISPATCH)), 50);
|
|
461
|
+
this.Dispatch().finally(() => { this.sendSessionfinished = true; });
|
|
462
|
+
}
|
|
463
|
+
}))
|
|
464
|
+
.subscribe();
|
|
465
|
+
window.addEventListener(DISPATCH, (e) => {
|
|
466
|
+
e.detail.traces && this.addtoQueue(e.detail.traces);
|
|
467
|
+
e.detail.force && this.sendSessions(true);
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
Dispatch() {
|
|
471
|
+
if (this.instanceSaved) {
|
|
472
|
+
return this.sendSessions();
|
|
473
|
+
}
|
|
474
|
+
return this.postInstanceEnv().then((ok) => {
|
|
475
|
+
if (ok) {
|
|
476
|
+
return this.sendSessions();
|
|
477
|
+
}
|
|
478
|
+
this.sessionSendAttempts % 5 == 0 && console.warn(`Error while attempting to send Environement instance, attempts ${this.sessionSendAttempts}`);
|
|
479
|
+
return Promise.reject(new Error('No instance id'));
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
sendSessions(instanceComplete) {
|
|
483
|
+
if (this.traceQueue.size > 0) {
|
|
484
|
+
let uri = ContextManager.instance.techConfig.sessionApi + "?attempts=" + ++this.sessionSendAttempts;
|
|
485
|
+
if (instanceComplete) {
|
|
486
|
+
uri += "&end=" + new Date().toISOString();
|
|
487
|
+
}
|
|
488
|
+
let sessions = this.traceQueue;
|
|
489
|
+
this.traceQueue = new Set();
|
|
490
|
+
return fetch(uri, this.getRequestInit(sessions))
|
|
491
|
+
.then(res => {
|
|
492
|
+
if (res.ok) {
|
|
493
|
+
this.sessionSendAttempts = 0;
|
|
494
|
+
return sessions.size;
|
|
495
|
+
}
|
|
496
|
+
return this.handleEventTraceSavingError(sessions);
|
|
497
|
+
})
|
|
498
|
+
.catch(() => this.handleEventTraceSavingError(sessions));
|
|
499
|
+
}
|
|
500
|
+
return Promise.resolve(0);
|
|
501
|
+
}
|
|
502
|
+
handleEventTraceSavingError(sessions) {
|
|
503
|
+
this.sessionSendAttempts % 5 == 0 && console.warn(`Error while attempting to send sessions, attempts: ${this.sessionSendAttempts}`);
|
|
504
|
+
this.revertQueueSize(sessions);
|
|
505
|
+
return -1;
|
|
506
|
+
}
|
|
507
|
+
getRequestInit(sessionList) {
|
|
508
|
+
return {
|
|
509
|
+
method: 'PUT',
|
|
510
|
+
headers: { 'Content-Type': 'application/json' },
|
|
511
|
+
mode: 'cors',
|
|
512
|
+
body: JSON.stringify(Array.from(sessionList))
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
postInstanceEnv() {
|
|
516
|
+
this.sessionSendAttempts++;
|
|
517
|
+
return fetch(ContextManager.instance.techConfig.instanceApi, {
|
|
518
|
+
method: 'POST',
|
|
519
|
+
headers: { 'Content-Type': 'application/json' },
|
|
520
|
+
mode: 'cors',
|
|
521
|
+
body: JSON.stringify(ContextManager.instance.instanceEnv)
|
|
522
|
+
})
|
|
523
|
+
.then(res => res.ok ? res.text().then(id => {
|
|
524
|
+
this.sessionSendAttempts = 0;
|
|
525
|
+
return this.instanceSaved = true;
|
|
526
|
+
}) : false)
|
|
527
|
+
.catch(err => false);
|
|
528
|
+
}
|
|
529
|
+
revertQueueSize(sessions) {
|
|
530
|
+
sessions.forEach(session => this.traceQueue.add(session));
|
|
531
|
+
if (this.traceQueue.size > ContextManager.instance.techConfig.queueCapacity) {
|
|
532
|
+
const items = Array.from(this.traceQueue).slice(0, ContextManager.instance.techConfig.queueCapacity);
|
|
533
|
+
this.traceQueue = new Set(items);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
async addtoQueue(event) {
|
|
537
|
+
try {
|
|
538
|
+
if (event) {
|
|
539
|
+
this.traceQueue.add(event);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
catch (e) {
|
|
543
|
+
this.addtoQueue(createReport(String(e)));
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
function routeHandler(event) {
|
|
549
|
+
if (event instanceof NavigationStart) {
|
|
550
|
+
SessionManager.instance.newSession(event.url);
|
|
551
|
+
}
|
|
552
|
+
if (event instanceof NavigationEnd) {
|
|
553
|
+
delete SessionManager.instance.getCurrentSession().loading;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
function windowUnloadHandler(event) {
|
|
557
|
+
if (!SessionManager.instance.getCurrentSession().loading) {
|
|
558
|
+
SessionManager.instance.newSession();
|
|
559
|
+
}
|
|
560
|
+
window.dispatchEvent(new CustomEvent(DISPATCH, { detail: { force: true } }));
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
function machineRessourceUsageHandler(event) {
|
|
564
|
+
window.dispatchEvent(new CustomEvent(DISPATCH, { detail: { traces: getMemoryInfo() } }));
|
|
565
|
+
}
|
|
566
|
+
function getMemoryInfo() {
|
|
567
|
+
try {
|
|
568
|
+
const memory = performance.memory;
|
|
569
|
+
return {
|
|
570
|
+
'@type': 'rsrc-usg',
|
|
571
|
+
instant: dateNow(),
|
|
572
|
+
usedHeap: memory.usedJSHeapSize / (1024 * 1024),
|
|
573
|
+
commitedHeap: memory.totalJSHeapSize / (1024 * 1024),
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
catch (e) {
|
|
577
|
+
createReport(JSON.stringify(e));
|
|
578
|
+
}
|
|
579
|
+
return null;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
function routerEventsListener() {
|
|
583
|
+
inject(Router).events.subscribe(routeHandler);
|
|
584
|
+
}
|
|
585
|
+
function beforeUnloadListener() {
|
|
586
|
+
window.addEventListener(BEFOREUNLOAD, windowUnloadHandler);
|
|
587
|
+
}
|
|
588
|
+
function beforeDispatchListener() {
|
|
589
|
+
if (ContextManager.instance.techConfig.resources && 'memory' in performance) {
|
|
590
|
+
window.addEventListener(PRE_DISPATCH, machineRessourceUsageHandler);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
|
|
472
594
|
const genericMap = [
|
|
473
595
|
t => t.getAttribute('placeholder'),
|
|
474
596
|
t => t.getAttribute('title'),
|
|
@@ -518,125 +640,256 @@ function extractName(t) {
|
|
|
518
640
|
return null;
|
|
519
641
|
}
|
|
520
642
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
'click': (target) => this.lookUpChild(target, 1),
|
|
527
|
-
};
|
|
528
|
-
this.patchedEvent = {};
|
|
529
|
-
this.elementsWithClickListeners = new WeakSet();
|
|
530
|
-
}
|
|
531
|
-
subscribeToEvents() {
|
|
532
|
-
const body = this.document.body;
|
|
533
|
-
body.addEventListener('click', (event) => this.globalHandler(event), true);
|
|
534
|
-
body.addEventListener('change', (event) => this.globalHandler(event), true);
|
|
535
|
-
body.addEventListener('scrollend', (event) => this.globalHandler(event), true);
|
|
536
|
-
body.addEventListener('dragend', (event) => this.globalHandler(event), true);
|
|
537
|
-
this.document.addEventListener('DOMContentLoaded', (event) => this.globalHandler(event), true);
|
|
538
|
-
/* let that =this;
|
|
539
|
-
|
|
540
|
-
const originalAddEventListener = EventTarget.prototype.addEventListener;
|
|
541
|
-
EventTarget.prototype.addEventListener = function(type: string, listener: any, options?: boolean | AddEventListenerOptions) {
|
|
542
|
-
if(type === "click"){
|
|
543
|
-
that.elementsWithClickListeners.add(this);
|
|
544
|
-
const wrapperListener = (event: any) => {
|
|
545
|
-
if(that.elementsWithClickListeners.has(event.currentTarget)){
|
|
546
|
-
console.log('click event',event);
|
|
547
|
-
that.GlobalHandler(event);
|
|
548
|
-
}
|
|
549
|
-
return listener.apply(this, arguments);
|
|
550
|
-
};
|
|
551
|
-
return originalAddEventListener.apply(this,[type,wrapperListener,options])
|
|
552
|
-
}
|
|
553
|
-
return originalAddEventListener.call(this, type, listener, options);
|
|
554
|
-
}*/
|
|
555
|
-
}
|
|
556
|
-
globalHandler(event) {
|
|
557
|
-
// event.stopPropagation()
|
|
558
|
-
// event.preventDefault()
|
|
559
|
-
let target = event.target;
|
|
560
|
-
let eventType = event.type;
|
|
643
|
+
let eventHandlers = {
|
|
644
|
+
'click': (target) => lookUpChild(target, 1),
|
|
645
|
+
};
|
|
646
|
+
function analyticsEventsListener() {
|
|
647
|
+
if (ContextManager.instance.techConfig.analytics) {
|
|
561
648
|
try {
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
649
|
+
const body = window.document.body;
|
|
650
|
+
body.addEventListener('click', globalHandler, true);
|
|
651
|
+
body.addEventListener('change', (event) => globalHandler(event), true);
|
|
652
|
+
body.addEventListener('scrollend', (event) => globalHandler(event), true);
|
|
653
|
+
body.addEventListener('dragend', (event) => globalHandler(event), true);
|
|
654
|
+
window.document.addEventListener('DOMContentLoaded', (event) => globalHandler(event), true);
|
|
566
655
|
}
|
|
567
|
-
catch (
|
|
568
|
-
|
|
656
|
+
catch (e) {
|
|
657
|
+
window.dispatchEvent(new CustomEvent(DISPATCH, { detail: { traces: createReport("Error while subscribing to analytics user events: " + JSON.stringify(e)) } }));
|
|
569
658
|
}
|
|
570
659
|
}
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
660
|
+
}
|
|
661
|
+
function globalHandler(event) {
|
|
662
|
+
let target = event.target;
|
|
663
|
+
let eventType = event.type;
|
|
664
|
+
try {
|
|
665
|
+
if (eventHandlers.hasOwnProperty(eventType) && !eventHandlers[eventType](target)) {
|
|
666
|
+
return;
|
|
577
667
|
}
|
|
578
|
-
|
|
668
|
+
addActionUser(eventType, target);
|
|
579
669
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
type: eventType,
|
|
583
|
-
start: dateNow(),
|
|
584
|
-
name: extractName(target),
|
|
585
|
-
nodeName: target.tagName?.toLowerCase(),
|
|
586
|
-
};
|
|
587
|
-
logInspect('user', () => prettyActionUserFormat(this.sessionManager.getCurrentSession(), ua));
|
|
588
|
-
this.sessionManager.getCurrentSession().userActions.push(ua);
|
|
670
|
+
catch (err) {
|
|
671
|
+
console.warn(err);
|
|
589
672
|
}
|
|
590
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: AnalyticsCollector, deps: [{ token: DOCUMENT }, { token: SessionManager }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
591
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: AnalyticsCollector, providedIn: 'root' }); }
|
|
592
673
|
}
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
674
|
+
function lookUpChild(t, depth) {
|
|
675
|
+
if (t.hasChildNodes() && t.children.length <= 5) {
|
|
676
|
+
if (++depth > 5) {
|
|
677
|
+
return false;
|
|
678
|
+
}
|
|
679
|
+
return Array.from(t.childNodes).reduce((acc, c) => acc && lookUpChild(c, depth), true);
|
|
680
|
+
}
|
|
681
|
+
return true;
|
|
682
|
+
}
|
|
683
|
+
function addActionUser(eventType, target) {
|
|
684
|
+
const ua = {
|
|
685
|
+
'@type': "user-act",
|
|
686
|
+
type: eventType,
|
|
687
|
+
start: dateNow(),
|
|
688
|
+
name: extractName(target),
|
|
689
|
+
nodeName: target.tagName?.toLowerCase(),
|
|
690
|
+
sessionId: SessionManager.instance?.getCurrentSession().id
|
|
691
|
+
};
|
|
692
|
+
// window.dispatchEvent(new CustomEvent( DISPATCH ,{ detail : { traces:ua }}));
|
|
693
|
+
}
|
|
602
694
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
695
|
+
function eventTraceDebugger() {
|
|
696
|
+
EventTraceDebugger._instance = new EventTraceDebugger();
|
|
697
|
+
}
|
|
698
|
+
class EventTraceDebugger {
|
|
699
|
+
constructor() {
|
|
700
|
+
this.restRequests = [];
|
|
701
|
+
this.httpRequestStages = [];
|
|
702
|
+
this.localRequests = [];
|
|
703
|
+
this.userActions = [];
|
|
704
|
+
this.logEntries = [];
|
|
705
|
+
try {
|
|
706
|
+
if (ContextManager.instance.techConfig.debugMode || WIN['inspect']) {
|
|
707
|
+
window.addEventListener(DISPATCH, this.handleTraces.bind(this));
|
|
708
|
+
}
|
|
709
|
+
WIN["inspect-setup"] = {
|
|
710
|
+
init: () => {
|
|
711
|
+
WIN['inspect'] = true;
|
|
712
|
+
EventTraceDebugger.init();
|
|
713
|
+
},
|
|
714
|
+
printConfig: () => console.log(ContextManager.instance.techConfig),
|
|
715
|
+
printInstance: () => console.log(ContextManager.instance)
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
catch (e) {
|
|
719
|
+
console.warn(e);
|
|
720
|
+
window.dispatchEvent(new CustomEvent(DISPATCH, { detail: { traces: createReport("Error while setting up debug mode: " + JSON.stringify(e)) } }));
|
|
721
|
+
}
|
|
606
722
|
}
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
723
|
+
handleTraces(e) {
|
|
724
|
+
let trace = e.detail.traces;
|
|
725
|
+
if (trace && !e.detail.force) {
|
|
726
|
+
switch (trace['@type']) {
|
|
727
|
+
case 'main-ses':
|
|
728
|
+
if (trace.end) {
|
|
729
|
+
console.log(this.prettySessionFormat(SessionManager.instance.currentSession));
|
|
730
|
+
}
|
|
731
|
+
break;
|
|
732
|
+
case 'http-req':
|
|
733
|
+
this.restRequests.push(trace);
|
|
734
|
+
break;
|
|
735
|
+
case 'http-stg':
|
|
736
|
+
this.httpRequestStages.push(trace);
|
|
737
|
+
break;
|
|
738
|
+
case 'user-act':
|
|
739
|
+
this.userActions.push(trace);
|
|
740
|
+
break;
|
|
741
|
+
case 'locl-req':
|
|
742
|
+
this.localRequests.push(trace);
|
|
743
|
+
break;
|
|
744
|
+
case 'log':
|
|
745
|
+
trace.sessionId ? this.logEntries.push(trace) : console.warn(this.prettyLogEntryFormat(trace));
|
|
746
|
+
break;
|
|
747
|
+
case 'rsrc-usg':
|
|
748
|
+
console.log(this.prettyMachineResourceUsageFormat(trace));
|
|
749
|
+
break;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
static init() {
|
|
754
|
+
return EventTraceDebugger._instance = new EventTraceDebugger();
|
|
755
|
+
}
|
|
756
|
+
prettySessionFormat(session) {
|
|
757
|
+
let s = `[${session.name}]`;
|
|
758
|
+
if (session.user) {
|
|
759
|
+
s += `<${session.user}>`;
|
|
760
|
+
}
|
|
761
|
+
if (session.location) {
|
|
762
|
+
s += `(${session.location}) `;
|
|
763
|
+
}
|
|
764
|
+
s += this.prettyDurationFormat(session.start, session.end) + '\n';
|
|
765
|
+
s += this.getChildPrint(this.restRequests, this.prettyRestRequestFormat.bind(this));
|
|
766
|
+
s += this.getChildPrint(this.localRequests, this.prettyLocalRequestFormat.bind(this));
|
|
767
|
+
s += this.getChildPrint(this.userActions, this.prettyActionUserFormat.bind(this));
|
|
768
|
+
s += this.getChildPrint(this.logEntries, this.prettyLogEntryFormat.bind(this));
|
|
769
|
+
this.resetList();
|
|
770
|
+
return s;
|
|
771
|
+
}
|
|
772
|
+
prettyRestRequestFormat(rest) {
|
|
773
|
+
let s = ` - [${rest.method}]`;
|
|
774
|
+
if (rest.protocol) {
|
|
775
|
+
s += `${rest.protocol}://`;
|
|
776
|
+
}
|
|
777
|
+
if (rest.host) {
|
|
778
|
+
s += rest.host;
|
|
779
|
+
}
|
|
780
|
+
if (rest.port > 0) {
|
|
781
|
+
s += `:${rest.port}`;
|
|
782
|
+
}
|
|
783
|
+
if (rest.path) {
|
|
784
|
+
if (!rest.path.startsWith("/") && !s.endsWith("/")) {
|
|
785
|
+
s += '/';
|
|
786
|
+
}
|
|
787
|
+
s += rest.path;
|
|
788
|
+
}
|
|
789
|
+
if (rest.query) {
|
|
790
|
+
s += rest.query;
|
|
791
|
+
}
|
|
792
|
+
s += ` >> ${rest.status} `;
|
|
793
|
+
s += this.prettyDurationFormat(rest.start, rest.end) + '\n';
|
|
794
|
+
this.httpRequestStages.filter((s) => s.requestId == rest.id).forEach((stage) => {
|
|
795
|
+
s += this.prettyHttpRequestStageFormat(stage);
|
|
611
796
|
});
|
|
612
|
-
|
|
797
|
+
return s;
|
|
798
|
+
}
|
|
799
|
+
prettyHttpRequestStageFormat(stage) {
|
|
800
|
+
let s = ` - [${stage.name}]`;
|
|
801
|
+
s += " >> ";
|
|
802
|
+
if (stage.exception?.type) {
|
|
803
|
+
s += ` ${stage.exception?.type}:`;
|
|
804
|
+
}
|
|
805
|
+
if (stage.exception?.message) {
|
|
806
|
+
s += ` ${stage.exception.message}`;
|
|
807
|
+
}
|
|
808
|
+
s += ` ${this.prettyDurationFormat(stage.start, stage.end)}`;
|
|
809
|
+
return s;
|
|
810
|
+
}
|
|
811
|
+
prettyLocalRequestFormat(local) {
|
|
812
|
+
let s = ` - [${local.name}]`;
|
|
813
|
+
if (local.location) {
|
|
814
|
+
s += `(${local.location})`;
|
|
815
|
+
}
|
|
816
|
+
s += " >> ";
|
|
817
|
+
if (local.exception?.type) {
|
|
818
|
+
s += ` ${local.exception?.type}:`;
|
|
819
|
+
}
|
|
820
|
+
if (local.exception?.message) {
|
|
821
|
+
s += ` ${local.exception.message}`;
|
|
822
|
+
}
|
|
823
|
+
s += ` ${this.prettyDurationFormat(local.start, local.end)}`;
|
|
824
|
+
return s;
|
|
825
|
+
}
|
|
826
|
+
prettyLogEntryFormat(log) {
|
|
827
|
+
let s = ` - [${log.level}]`;
|
|
828
|
+
if (log.message) {
|
|
829
|
+
s += ` ${log.message}`;
|
|
830
|
+
}
|
|
831
|
+
s += ` >> ${new Date(log.instant * 1000).toISOString()}`;
|
|
832
|
+
return s;
|
|
833
|
+
}
|
|
834
|
+
prettyMachineResourceUsageFormat(resource) {
|
|
835
|
+
return ` - [METRIC] heap :${resource.usedHeap.toFixed(2)}/${resource.commitedHeap.toFixed(2)} >> ${new Date(resource.instant * 1000).toISOString()}`;
|
|
836
|
+
}
|
|
837
|
+
prettyActionUserFormat(userAction) {
|
|
838
|
+
let s = ` - `;
|
|
839
|
+
if (userAction.type) {
|
|
840
|
+
s += `[${userAction.type}]`;
|
|
841
|
+
}
|
|
842
|
+
if (userAction.nodeName) {
|
|
843
|
+
s += `<${userAction.nodeName}>`;
|
|
844
|
+
}
|
|
845
|
+
if (userAction.name) {
|
|
846
|
+
s += `(${userAction.name}) `;
|
|
847
|
+
}
|
|
848
|
+
s += ` >> ${new Date(userAction.start * 1000).toISOString()}`;
|
|
849
|
+
return s;
|
|
850
|
+
}
|
|
851
|
+
getChildPrint(o, print) {
|
|
852
|
+
let s = "";
|
|
853
|
+
if (o.length) {
|
|
854
|
+
o = o.filter((r) => {
|
|
855
|
+
if (r.sessionId === SessionManager.instance.currentSessionID()) {
|
|
856
|
+
s += print(r) + '\n';
|
|
857
|
+
return false;
|
|
858
|
+
}
|
|
859
|
+
return true;
|
|
860
|
+
});
|
|
861
|
+
const remainingRequests = o.map((r) => print(r)).join('\n');
|
|
862
|
+
if (remainingRequests) {
|
|
863
|
+
console.warn(remainingRequests);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
return s;
|
|
867
|
+
}
|
|
868
|
+
prettyDurationFormat(start, end) {
|
|
869
|
+
return start && end ? `(in ${(end - start).toFixed(2)} s)` : '';
|
|
870
|
+
}
|
|
871
|
+
resetList() {
|
|
872
|
+
this.restRequests = [];
|
|
873
|
+
this.httpRequestStages = [];
|
|
874
|
+
this.localRequests = [];
|
|
875
|
+
this.userActions = [];
|
|
613
876
|
}
|
|
614
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: GlobalErrorHandlerService, deps: [{ token: SessionManager }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
615
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: GlobalErrorHandlerService, providedIn: 'root' }); }
|
|
616
877
|
}
|
|
617
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: GlobalErrorHandlerService, decorators: [{
|
|
618
|
-
type: Injectable,
|
|
619
|
-
args: [{ providedIn: 'root' }]
|
|
620
|
-
}], ctorParameters: () => [{ type: SessionManager }] });
|
|
621
878
|
|
|
622
879
|
class NgCollectorModule {
|
|
880
|
+
static { this.forRootCalled = false; }
|
|
623
881
|
static forRoot(configuration) {
|
|
624
|
-
|
|
882
|
+
console.log("forRoodtCalled");
|
|
883
|
+
if (configuration?.enabled && !NgCollectorModule.forRootCalled) {
|
|
884
|
+
NgCollectorModule.forRootCalled = true;
|
|
625
885
|
try {
|
|
626
|
-
|
|
627
|
-
let instance = GetInstanceEnvironement(configuration);
|
|
628
|
-
let deps = [Router, SessionManager];
|
|
629
|
-
logInspect('app', JSON.stringify(config));
|
|
630
|
-
logInspect('app', JSON.stringify(instance));
|
|
631
|
-
config.analytics && deps.push(AnalyticsCollector);
|
|
886
|
+
ContextManager.init(configuration);
|
|
632
887
|
return {
|
|
633
888
|
ngModule: NgCollectorModule,
|
|
634
889
|
providers: [
|
|
635
|
-
|
|
636
|
-
{ provide: APP_INITIALIZER, useFactory: initializeEvents,
|
|
890
|
+
//provideAppInitializer(initializeEvents),
|
|
891
|
+
{ provide: APP_INITIALIZER, useFactory: initializeEvents, multi: true },
|
|
637
892
|
{ provide: HTTP_INTERCEPTORS, useClass: HttpInterceptorService, multi: true },
|
|
638
|
-
{ provide: 'instance', useValue: instance },
|
|
639
|
-
{ provide: 'config', useValue: config },
|
|
640
893
|
{ provide: ErrorHandler, useClass: GlobalErrorHandlerService }
|
|
641
894
|
]
|
|
642
895
|
};
|
|
@@ -649,33 +902,22 @@ class NgCollectorModule {
|
|
|
649
902
|
ngModule: NgCollectorModule
|
|
650
903
|
};
|
|
651
904
|
}
|
|
652
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
653
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.
|
|
654
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.
|
|
905
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: NgCollectorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
906
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.4", ngImport: i0, type: NgCollectorModule }); }
|
|
907
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: NgCollectorModule }); }
|
|
655
908
|
}
|
|
656
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
909
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: NgCollectorModule, decorators: [{
|
|
657
910
|
type: NgModule
|
|
658
911
|
}] });
|
|
659
|
-
function initializeEvents(
|
|
912
|
+
function initializeEvents() {
|
|
660
913
|
return () => {
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
router.events.subscribe(event => {
|
|
669
|
-
if (event instanceof NavigationStart) {
|
|
670
|
-
sessionManager.newSession(event.url);
|
|
671
|
-
}
|
|
672
|
-
if (event instanceof NavigationEnd) {
|
|
673
|
-
delete sessionManager.getCurrentSession().loading;
|
|
674
|
-
}
|
|
675
|
-
});
|
|
676
|
-
if (analyticsCollector) {
|
|
677
|
-
analyticsCollector.subscribeToEvents();
|
|
678
|
-
}
|
|
914
|
+
eventTraceScheduledDispatcher();
|
|
915
|
+
eventTraceDebugger();
|
|
916
|
+
analyticsEventsListener();
|
|
917
|
+
//storageEventListener();
|
|
918
|
+
beforeDispatchListener();
|
|
919
|
+
beforeUnloadListener();
|
|
920
|
+
routerEventsListener();
|
|
679
921
|
};
|
|
680
922
|
}
|
|
681
923
|
|
|
@@ -683,51 +925,72 @@ function TraceableStage() {
|
|
|
683
925
|
return function (target, propertyKey, descriptor) {
|
|
684
926
|
const originalMethod = descriptor.value;
|
|
685
927
|
descriptor.value = function (...args) {
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
928
|
+
let exception;
|
|
929
|
+
let start, end;
|
|
930
|
+
start = Date.now();
|
|
931
|
+
try {
|
|
932
|
+
WIN["inspect-session-manager"]?.updateMask(RequestMask.LOCAL);
|
|
933
|
+
return originalMethod.apply(this, args);
|
|
934
|
+
}
|
|
935
|
+
catch (e) {
|
|
936
|
+
let type = null, message = null;
|
|
937
|
+
if (e) {
|
|
938
|
+
if (typeof e === "string") {
|
|
939
|
+
message = e;
|
|
940
|
+
}
|
|
941
|
+
else if (e instanceof Error) {
|
|
942
|
+
type = e.name;
|
|
943
|
+
message = e.message;
|
|
944
|
+
}
|
|
945
|
+
else {
|
|
946
|
+
message = JSON.stringify(e);
|
|
947
|
+
}
|
|
693
948
|
}
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
949
|
+
exception = {
|
|
950
|
+
type: type,
|
|
951
|
+
message: message
|
|
952
|
+
};
|
|
953
|
+
throw e;
|
|
954
|
+
}
|
|
955
|
+
finally {
|
|
956
|
+
end = Date.now();
|
|
957
|
+
window.dispatchEvent(new CustomEvent(DISPATCH, { detail: { traces: {
|
|
958
|
+
"@type": "locl-req",
|
|
959
|
+
id: crypto.randomUUID(),
|
|
960
|
+
name: propertyKey,
|
|
961
|
+
location: target.constructor.name,
|
|
962
|
+
user: WIN["inspect-session-manager"]?.currentSession?.user,
|
|
963
|
+
start: start,
|
|
964
|
+
end: end,
|
|
965
|
+
exception: exception,
|
|
966
|
+
sessionId: WIN["inspect-session-manager"]?.currentSession?.id
|
|
706
967
|
}
|
|
707
968
|
}
|
|
708
|
-
|
|
709
|
-
type: type,
|
|
710
|
-
message: message
|
|
711
|
-
};
|
|
712
|
-
throw e;
|
|
713
|
-
}
|
|
714
|
-
finally {
|
|
715
|
-
end = Date.now();
|
|
716
|
-
SessionManager.instance.getCurrentSession().localRequests.push({
|
|
717
|
-
name: propertyKey,
|
|
718
|
-
location: target.constructor.name,
|
|
719
|
-
user: session.user,
|
|
720
|
-
start: start,
|
|
721
|
-
end: end,
|
|
722
|
-
exception: exception
|
|
723
|
-
});
|
|
724
|
-
}
|
|
969
|
+
}));
|
|
725
970
|
}
|
|
726
971
|
};
|
|
727
972
|
return descriptor;
|
|
728
973
|
};
|
|
729
974
|
}
|
|
730
975
|
|
|
976
|
+
class LogService {
|
|
977
|
+
static info(message) {
|
|
978
|
+
if (message) {
|
|
979
|
+
window.dispatchEvent(new CustomEvent(DISPATCH, { detail: { traces: createLogEntry("INFO", message, SessionManager.instance?.currentSessionID()) } }));
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
static warn(message) {
|
|
983
|
+
if (message) {
|
|
984
|
+
window.dispatchEvent(new CustomEvent(DISPATCH, { detail: { traces: createLogEntry("WARN", message, SessionManager.instance?.currentSessionID()) } }));
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
static error(message) {
|
|
988
|
+
if (message) {
|
|
989
|
+
window.dispatchEvent(new CustomEvent(DISPATCH, { detail: { traces: createLogEntry("ERROR", message, SessionManager.instance?.currentSessionID()) } }));
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
|
|
731
994
|
/*
|
|
732
995
|
* Public API Surface of inspect-ng-collector
|
|
733
996
|
*/
|
|
@@ -736,5 +999,5 @@ function TraceableStage() {
|
|
|
736
999
|
* Generated bundle index. Do not edit.
|
|
737
1000
|
*/
|
|
738
1001
|
|
|
739
|
-
export { NgCollectorModule, TraceableStage, initializeEvents };
|
|
1002
|
+
export { LogService, NgCollectorModule, TraceableStage, initializeEvents };
|
|
740
1003
|
//# sourceMappingURL=oneteme-inspect-ng-collector.mjs.map
|