un-cli 0.0.67 → 0.0.70

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.
package/index.html ADDED
@@ -0,0 +1,677 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>UN Logs</title>
8
+ </head>
9
+ <body>
10
+
11
+ <table>
12
+ <tr><td>Service</td>
13
+ <td colspan =3 ><select id ='cmbService'>
14
+ <option>(All Services)</option>
15
+ </select>
16
+ </td>
17
+ </tr>
18
+
19
+ <tr>
20
+ <td >Age</td>
21
+ <td colspan =3><input type ='text' id = 'txtAge' value = '30' style="width:30px"> minutes</td>
22
+ </tr>
23
+ <tr colspan =4>
24
+ <td><button id = 'btnTraceLogs'>Trace Logs</button></td>
25
+ <td><button id = 'btnValidateLogs'>Validate Logs</button></td>
26
+ <td><button id = 'btnUpdateSubnetworkLogs'>Update Subnetwork Logs</button></td>
27
+ <td><button id = 'btnAR'>Attribute Rules Logs</button></td>
28
+ <td><button id = 'btnSQLLogs'>SQL Logs</button></td>
29
+
30
+ </tr>
31
+
32
+ </table>
33
+
34
+ <table id = 'tblResult' border =1 cellpadding = 4 cellspacing = 4 style="text-align:center">
35
+
36
+ </table>
37
+ <script type = 'module'>
38
+ import { Portal } from "./portal.mjs"
39
+ import { UtilityNetwork } from "./utilitynetwork.node.mjs"
40
+ import { AdminLog } from "./adminlog.mjs"
41
+ import logger from "./logger.mjs"
42
+
43
+ const parameters = {
44
+ "user": "unadmin",
45
+ "password": "unadmin.109",
46
+ "portal": "https://utilitynetwork.esri.com/portal",
47
+ "service": "RedTrolley_SQLServer",
48
+ "referer": "https://utilitynetwork.esri.com/log"
49
+ }
50
+
51
+ let portal;
52
+ let adminLog = null;
53
+ let cmbService
54
+ let token;
55
+ async function init() {
56
+
57
+ cmbService = document.getElementById("cmbService")
58
+
59
+ token = await getToken(parameters);
60
+ const services = await portal.services()
61
+ const featureServices = services.services.filter(s => s.type == "FeatureServer")
62
+ featureServices.forEach(s=> {
63
+ const o = document.createElement("option");
64
+ o.text = s.name;
65
+ cmbService.appendChild(o);
66
+ })
67
+ }
68
+
69
+
70
+ async function getToken(parameters) {
71
+ portal = new Portal(parameters.portal, parameters.user, parameters.password,300, parameters.server, parameters.referer)
72
+ console.log("About to connect..")
73
+ const token = await portal.connect()
74
+ console.log(`Token generanted successfully.`)
75
+ return token;
76
+ }
77
+
78
+
79
+ async function loadTraceLogs () {
80
+
81
+ //build table
82
+ const tblResult = document.getElementById("tblResult");
83
+ //clear
84
+ while(tblResult.firstChild) tblResult.removeChild(tblResult.firstChild)
85
+ tblResult.appendChild(document.createTextNode("Loading...."));
86
+
87
+
88
+ parameters.service = cmbService.options[cmbService.selectedIndex].text
89
+
90
+ //create a new admin object (user might not be admin we won't use it until the user call log )
91
+ adminLog = new AdminLog(token, portal.serverUrl)
92
+
93
+ logger.info("Connected.")
94
+
95
+
96
+ const topLogCount = 1000;
97
+ const pageSize = 10000
98
+
99
+ let mins = document.getElementById("txtAge").value //query logs for the last 30 minutes
100
+
101
+ console.log(`Querying trace logs for ${parameters.service} for the last ${mins} minutes ...`)
102
+ const startTime = Date.now() - mins*60*1000
103
+ const endTime = Date.now();
104
+ let services = [parameters.service+ ".MapServer"]
105
+ if (parameters.service == "(All Services)")
106
+ services = "*"
107
+ let result= await adminLog.query([102002], services, topLogCount, startTime ,endTime , "VERBOSE")
108
+ let jsonRes = await result.json()
109
+ let allMessages = [].concat(jsonRes.logMessages)
110
+ allMessages = allMessages.filter(m => m.message.indexOf("------ Trace Parameters ----") > -1)
111
+ while (jsonRes.hasMore)
112
+ {
113
+ //start paging
114
+ logger.info(`Aggregating messages... total so far ${allMessages.length} entries but more left, pulling logs before ${new Date(jsonRes.endTime)}`)
115
+ result= await adminLog.query([102002], services, pageSize, jsonRes.endTime, null, "VERBOSE")
116
+ jsonRes = await result.json()
117
+
118
+ allMessages = allMessages.concat(jsonRes.logMessages.filter(m => m.message.indexOf("------ Trace Parameters ----") > -1))
119
+ }
120
+
121
+ await populateMessages(allMessages)
122
+
123
+
124
+ }
125
+
126
+
127
+
128
+ async function loadValidateLogs () {
129
+ //build table
130
+ const tblResult = document.getElementById("tblResult");
131
+ //clear
132
+ while(tblResult.firstChild) tblResult.removeChild(tblResult.firstChild)
133
+ tblResult.appendChild(document.createTextNode("Loading...."));
134
+
135
+ parameters.service = cmbService.options[cmbService.selectedIndex].text
136
+
137
+
138
+ //create a new admin object (user might not be admin we won't use it until the user call log )
139
+ adminLog = new AdminLog(token, portal.serverUrl)
140
+
141
+ logger.info("Connected.")
142
+
143
+
144
+ const topLogCount = 1000;
145
+ const pageSize = 10000
146
+
147
+ let mins = document.getElementById("txtAge").value //query logs for the last 30 minutes
148
+
149
+ console.log(`Querying validate logs for ${parameters.service} for the last ${mins} minutes ...`)
150
+ const startTime = Date.now() - mins*60*1000
151
+ const endTime = Date.now();
152
+ let services = [parameters.service+ ".MapServer"]
153
+ if (parameters.service == "(All Services)")
154
+ services = "*"
155
+ let result= await adminLog.query([102003], services, topLogCount, startTime ,endTime , "VERBOSE")
156
+ let jsonRes = await result.json()
157
+ let allMessages = [].concat(jsonRes.logMessages)
158
+ allMessages = allMessages.filter(m => m.message.indexOf("-------- Environment ---") > -1 && m.message.indexOf("The network is built.") > -1 && m.methodName == 'BuildEngineLog')
159
+ while (jsonRes.hasMore)
160
+ {
161
+ //start paging
162
+ logger.info(`Aggregating messages... total so far ${allMessages.length} entries but more left, pulling logs before ${new Date(jsonRes.endTime)}`)
163
+ result= await adminLog.query([102003], services, pageSize, jsonRes.endTime, null, "VERBOSE")
164
+ jsonRes = await result.json()
165
+
166
+ allMessages = allMessages.concat(jsonRes.logMessages.filter(m => m.message.indexOf("-------- Environment ---") > -1 && m.message.indexOf("------ Trace Parameters ----") == -1))
167
+ }
168
+
169
+
170
+
171
+
172
+ //validate logs missing elapsed populate it
173
+ allMessages = allMessages.map( m => {
174
+ try{
175
+
176
+ //The network is built. 0.093 seconds (4.982 total) - 29 MB memory
177
+
178
+ let re = /The network is built. [-+]?([0-9]*\.[0-9]+|[0-9]+) seconds \([-+]?([0-9]*\.[0-9]+|[0-9]+) total\)/;
179
+ let res = re.exec(m.message)
180
+ if (res && res.length > 1)
181
+ m.elapsed = res[2]
182
+
183
+ return m;
184
+ }
185
+ catch(ex){
186
+ return m;
187
+ }
188
+ })
189
+
190
+
191
+ await populateMessages(allMessages)
192
+
193
+
194
+ }
195
+
196
+
197
+ async function loadUpdateSubnetworkLogs () {
198
+ //build table
199
+ const tblResult = document.getElementById("tblResult");
200
+ //clear
201
+ while(tblResult.firstChild) tblResult.removeChild(tblResult.firstChild)
202
+ tblResult.appendChild(document.createTextNode("Loading...."));
203
+
204
+ parameters.service = cmbService.options[cmbService.selectedIndex].text
205
+ //create a new admin object (user might not be admin we won't use it until the user call log )
206
+ adminLog = new AdminLog(token, portal.serverUrl)
207
+
208
+ logger.info("Connected.")
209
+
210
+
211
+ const topLogCount = 1000;
212
+ const pageSize = 10000
213
+
214
+ let mins = document.getElementById("txtAge").value //query logs for the last 30 minutes
215
+
216
+
217
+ console.log(`Querying subnetwork logs for ${parameters.service} for the last ${mins} minutes ...`)
218
+ const startTime = Date.now() - mins*60*1000
219
+ const endTime = Date.now();
220
+ let services = [parameters.service+ ".MapServer"]
221
+ if (parameters.service == "(All Services)")
222
+ services = "*"
223
+ let result= await adminLog.query([102003], services, topLogCount, startTime ,endTime , "VERBOSE")
224
+ let jsonRes = await result.json()
225
+ let allMessages = [].concat(jsonRes.logMessages)
226
+ allMessages = allMessages.filter(m => m.message.indexOf("---- Subnetwork Parameters ----") > -1)
227
+ while (jsonRes.hasMore)
228
+ {
229
+ //start paging
230
+ logger.info(`Aggregating messages... total so far ${allMessages.length} entries but more left, pulling logs before ${new Date(jsonRes.endTime)}`)
231
+ result= await adminLog.query([102003], services, pageSize, jsonRes.endTime, null, "VERBOSE")
232
+ jsonRes = await result.json()
233
+
234
+ allMessages = allMessages.concat(jsonRes.logMessages.filter(m => m.message.indexOf("---- Subnetwork Parameters ----") > -1))
235
+ }
236
+
237
+ //update subnetwork missing elapsed populate it
238
+ allMessages = allMessages.map( m => {
239
+ try{
240
+
241
+ let re = /Total \([-+]?([0-9]*\.[0-9]+|[0-9]+) seconds\)/;
242
+ let res = re.exec(m.message)
243
+ if (res && res.length > 1)
244
+ m.elapsed = res[1]
245
+
246
+ re = /Total update subnetwork time \([-+]?([0-9]*\.[0-9]+|[0-9]+) seconds\)/;
247
+ res = re.exec(m.message)
248
+ if (res && res.length > 1)
249
+ m.elapsed = res[1]
250
+
251
+ return m;
252
+ }
253
+ catch(ex){
254
+ return m;
255
+ }
256
+ })
257
+ await populateMessages(allMessages)
258
+
259
+
260
+ }
261
+
262
+
263
+
264
+ async function loadAttributeRules () {
265
+
266
+ //build table
267
+ const tblResult = document.getElementById("tblResult");
268
+ tblResult.appendChild(document.createTextNode("Loading...."));
269
+
270
+ let mins = document.getElementById("txtAge").value //query logs for the last 30 minutes
271
+
272
+ parameters.service = cmbService.options[cmbService.selectedIndex].text
273
+ //create a new admin object (user might not be admin we won't use it until the user call log )
274
+ adminLog = new AdminLog(token, portal.serverUrl)
275
+
276
+ let showMaxGuid = true
277
+ let showMinGuid = false
278
+ const startTime = Date.now() - mins*60*1000
279
+ const endTime = Date.now();
280
+
281
+ let services = [parameters.service+ ".MapServer"]
282
+ if (parameters.service == "(All Services)")
283
+ services = "*"
284
+
285
+ const pageSize = 10000 //maximum messages per page
286
+ logger.info(`Querying attribute rules logs for ${parameters.service} in the past ${mins} minutes...`)
287
+ let result= await adminLog.query([102003], services, pageSize, startTime ,endTime , "DEBUG")
288
+ let jsonRes = await result.json()
289
+ let allMessages = [].concat(jsonRes.logMessages)
290
+
291
+ while (jsonRes.hasMore && jsonRes.endTime > startTime)
292
+ {
293
+ //start paging
294
+ logger.info(`Aggregating messages... total so far ${allMessages.length} debug entries but more left, pulling logs before ${new Date(jsonRes.endTime)}`)
295
+
296
+
297
+ result= await adminLog.query([102003], services, pageSize, jsonRes.endTime )
298
+ jsonRes = await result.json()
299
+ allMessages = allMessages.concat(jsonRes.logMessages)
300
+ }
301
+
302
+ const arMessages = allMessages
303
+ .filter(m => m.message.indexOf("Attribute rule execution complete:") > -1)
304
+ .map (m => JSON.parse(m.message.replace("Attribute rule execution complete:", "")))
305
+ .map( m => {
306
+ m["Elapsed Time (ms)"] = Math.round(m["Elapsed Time"]*1000000)/1000
307
+ // m["Arcade Evaluation Time:"] = Math.round(m["Arcade Evaluation Time:"]*1000,6)
308
+ //m.ArcadeTime = m["Arcade Evaluation Time:"]
309
+
310
+ delete m["Arcade Evaluation Time:"];
311
+ delete m["Elapsed Time"];
312
+ //delete m ['GlobalID'];
313
+ return m
314
+ })
315
+ .sort( (m1, m2) => m2["Elapsed Time (ms)"]- m1["Elapsed Time (ms)"])
316
+ .reduce( ( prev, cur ) => {
317
+ if (prev [cur["Rule name"]] === undefined)
318
+ {
319
+ prev [cur["Rule name"]] = {
320
+ "totalTime": 0,
321
+ "occurrence": 0,
322
+ "minTime": Number.MAX_SAFE_INTEGER,
323
+ "maxTime": -1,
324
+ "avgTime": 0,
325
+ "maxGuid": null,
326
+ "minGuid": null
327
+ };
328
+ }
329
+
330
+ prev [cur["Rule name"]].totalTime = prev [cur["Rule name"]].totalTime + cur["Elapsed Time (ms)"]
331
+
332
+ if (cur["Elapsed Time (ms)"] < prev [cur["Rule name"]].minTime ) {
333
+ prev [cur["Rule name"]].minTime = cur["Elapsed Time (ms)"];
334
+ prev [cur["Rule name"]].minGuid = cur["GlobalID"];
335
+ }
336
+
337
+ if (cur["Elapsed Time (ms)"] > prev [cur["Rule name"]].maxTime ){
338
+ prev [cur["Rule name"]].maxTime = cur["Elapsed Time (ms)"];
339
+ prev [cur["Rule name"]].maxGuid = cur["GlobalID"];
340
+ }
341
+
342
+ prev [cur["Rule name"]].occurrence++
343
+
344
+ prev [cur["Rule name"]].avgTime = prev [cur["Rule name"]].totalTime / prev [cur["Rule name"]].occurrence
345
+
346
+ return prev
347
+ }, {})
348
+
349
+ const rules = Object.keys(arMessages)
350
+ .map(a => {
351
+ const rule = {}
352
+ rule["Attribute Rule"] = a;
353
+ rule["Total Cost (ms)"] = parseFloat(arMessages[a].totalTime.toFixed(2))
354
+ if (!showMinGuid && !showMaxGuid) rule["Average Cost (ms)"] = parseFloat(arMessages[a].avgTime.toFixed(2))
355
+ rule["Max execution time (ms)"] = parseFloat(arMessages[a].maxTime.toFixed(2))
356
+ if (showMaxGuid) rule["Max GUID"] = arMessages[a].maxGuid
357
+ rule["Min execution time (ms)"] = parseFloat(arMessages[a].minTime.toFixed(2))
358
+ if (showMinGuid) rule["Min GUID"] = arMessages[a].minGuid
359
+ if (!showMinGuid && !showMaxGuid) rule["Occurrence"] = arMessages[a].occurrence;
360
+ return rule;
361
+ })
362
+ .sort( (m1, m2) => m2["Total Cost (ms)"] -m1["Total Cost (ms)"])
363
+ console.table(rules)
364
+
365
+ /*
366
+ Attribute Rule
367
+ │ Total Cost (ms)
368
+ │ Max execution time (ms)
369
+ │ Max GUID
370
+ │ Min execution time (m
371
+
372
+ */
373
+
374
+ const header = document.createElement("tr");
375
+ const cAttributeRule = document.createElement("th");
376
+ cAttributeRule.textContent = "Attribute Rule"
377
+
378
+ const cTotalCost = document.createElement("th");
379
+ cTotalCost.textContent = "Total Cost (ms)"
380
+
381
+ const cMaxExecutionTime = document.createElement("th");
382
+ cMaxExecutionTime.textContent = "Max execution time (ms)"
383
+
384
+ const cMaxGuid = document.createElement("th");
385
+ cMaxGuid.textContent = "Max GUID"
386
+
387
+ const cMinExecutionTime = document.createElement("th");
388
+ cMinExecutionTime.textContent = "Min execution time (ms)"
389
+
390
+
391
+ header.appendChild (cAttributeRule)
392
+ header.appendChild (cTotalCost)
393
+ header.appendChild (cMaxExecutionTime)
394
+ header.appendChild (cMaxGuid)
395
+ header.appendChild (cMinExecutionTime)
396
+
397
+ tblResult.appendChild(header)
398
+
399
+
400
+ rules.forEach(rule =>
401
+ {
402
+
403
+ const logRow = document.createElement("tr");
404
+ const cAttributeRule = document.createElement("td");
405
+ cAttributeRule.textContent = rule["Attribute Rule"]
406
+
407
+ const cTotalCost = document.createElement("td");
408
+ cTotalCost.textContent = rule["Total Cost (ms)"]
409
+
410
+ const cMaxExecutionTime = document.createElement("td");
411
+ cMaxExecutionTime.textContent = rule["Max execution time (ms)"]
412
+
413
+ const cMaxGuid = document.createElement("td");
414
+ cMaxGuid.textContent = rule["Max GUID"]
415
+
416
+ const cMinExecutionTime = document.createElement("td");
417
+ cMinExecutionTime.textContent = rule["Min execution time (ms)"]
418
+
419
+ logRow.appendChild (cAttributeRule)
420
+ logRow.appendChild (cTotalCost)
421
+ logRow.appendChild (cMaxExecutionTime)
422
+ logRow.appendChild (cMaxGuid)
423
+ logRow.appendChild (cMinExecutionTime)
424
+ tblResult.appendChild(logRow)
425
+
426
+
427
+ })
428
+
429
+
430
+ const totalARExecution = rules.reduce( (prev, cur) => prev + cur["Total Cost (ms)"], 0)
431
+ console.log(`Total time spend executing attribute rules (${Math.round(totalARExecution)} ms) (${Math.round(totalARExecution/1000)} s) (${Math.round(totalARExecution/(1000*60))} m)`)
432
+
433
+
434
+
435
+ }
436
+ async function loadSQLLogs () {
437
+
438
+ //build table
439
+ const tblResult = document.getElementById("tblResult");
440
+ //clear
441
+ while(tblResult.firstChild) tblResult.removeChild(tblResult.firstChild)
442
+ tblResult.appendChild(document.createTextNode("Loading...."));
443
+
444
+
445
+ parameters.service = cmbService.options[cmbService.selectedIndex].text
446
+
447
+ //create a new admin object (user might not be admin we won't use it until the user call log )
448
+ adminLog = new AdminLog(token, portal.serverUrl)
449
+
450
+ logger.info("Connected.")
451
+
452
+
453
+ const topLogCount = 1000;
454
+ const pageSize = 10000
455
+
456
+ let mins = document.getElementById("txtAge").value //query logs for the last 30 minutes
457
+
458
+
459
+ console.log(`Querying cursor sql logs for ${parameters.service} for the last ${mins} minutes ...`)
460
+ const startTime = Date.now() - mins*60*1000
461
+ const endTime = Date.now();
462
+ let services = [parameters.service+ ".MapServer"]
463
+ if (parameters.service == "(All Services)")
464
+ services = "*"
465
+ let result= await adminLog.query([102023], services, topLogCount, startTime ,endTime , "DEBUG")
466
+ let jsonRes = await result.json()
467
+ let allMessages = [].concat(jsonRes.logMessages)
468
+ allMessages = allMessages.filter(m => m.message.indexOf("EndCursor;") > -1)
469
+ while (jsonRes.hasMore)
470
+ {
471
+ //start paging
472
+ logger.info(`Aggregating messages... total so far ${allMessages.length} entries but more left, pulling logs before ${new Date(jsonRes.endTime)}`)
473
+ result= await adminLog.query([102023], services, pageSize, jsonRes.endTime, null, "DEBUG")
474
+ jsonRes = await result.json()
475
+
476
+ allMessages = allMessages.concat(jsonRes.logMessages.filter(m => m.message.indexOf("EndCursor;") > -1))
477
+ }
478
+ console.log ("Filtering messages...")
479
+
480
+ allMessages = allMessages
481
+ .map( m=> {
482
+ m.dataAccessElapsed = parseFloat(m.message.split(";")[1].split(" ")[1])
483
+ m.executeQueryElapsed = parseFloat(m.message.split(";")[2].split(" ")[1])
484
+ m.totalExecutionElapsed = m.dataAccessElapsed + m.executeQueryElapsed
485
+ m.elapsed = parseFloat(m.elapsed); return m;
486
+
487
+ })
488
+ .sort( (m1,m2) => m2.totalExecutionElapsed - m1.totalExecutionElapsed)
489
+ .slice(0, 100) ;//first 100
490
+
491
+
492
+ console.log("-----Top 10 SQL----")
493
+ while(tblResult.firstChild) tblResult.removeChild(tblResult.firstChild)
494
+
495
+ let i =0;
496
+
497
+ const header = document.createElement("tr");
498
+ const cService = document.createElement("th");
499
+ cService.textContent = "Source"
500
+ const cTime = document.createElement("th");
501
+ cTime.textContent = "Time"
502
+ const cUser = document.createElement("th");
503
+ cUser.textContent = "User"
504
+ const cMethod = document.createElement("th");
505
+ cMethod.textContent = "Method"
506
+ const cQueryTime = document.createElement("th");
507
+ cQueryTime.textContent = "Query Time (ms)"
508
+ cQueryTime.title = "includes search + data access nextRow"
509
+ const cTotalTime = document.createElement("th");
510
+ cTotalTime.title = "Total time the cursor was opened"
511
+ cTotalTime.textContent = "Total Time (ms)"
512
+ const cLog = document.createElement("th");
513
+ cLog.textContent = "Full SQL"
514
+ header.appendChild (cService)
515
+ header.appendChild (cTime)
516
+ header.appendChild (cUser)
517
+ header.appendChild (cMethod)
518
+ header.appendChild (cQueryTime)
519
+ header.appendChild (cTotalTime)
520
+ header.appendChild (cLog)
521
+ tblResult.appendChild(header)
522
+
523
+
524
+ allMessages= allMessages.forEach(m =>
525
+ {
526
+
527
+ const logRow = document.createElement("tr");
528
+ const x = m.message.split(";")
529
+ x.shift()
530
+ console.log(`id: ${i++}`)
531
+ console.log(`\tAt: ${new Date(m.time)} (${m.time})`)
532
+ console.log(`\tUser: ${m.user}`)
533
+ console.log(`\tTotal Time: ${numberWithCommas(Math.round(m.elapsed*1000))} ms (Total time the cursor was opened)`)
534
+ console.log(`\tQuery Time: ${numberWithCommas(m.totalExecutionElapsed)} ms (includes search + data access nextRow)`)
535
+ console.log(`\tQuery:`)
536
+ x.forEach(a => console.log(`\t${a}`))
537
+ console.log(`\n`)
538
+
539
+ const cService = document.createElement("th");
540
+ cService.textContent = m.source.replace(".MapServer", "")
541
+
542
+ const cTime = document.createElement("td");
543
+ cTime.textContent = new Date(m.time).toLocaleString()
544
+
545
+ const cUser = document.createElement("td");
546
+ cUser.textContent = m.user
547
+ const cMethod = document.createElement("td");
548
+ cMethod.textContent = "Cursor"
549
+ const cQueryTime = document.createElement("td");
550
+ cQueryTime.textContent = numberWithCommas(m.totalExecutionElapsed)
551
+ const cTotalTime = document.createElement("td");
552
+ cTotalTime.textContent = numberWithCommas(Math.round(m.elapsed*1000))
553
+ const cLog = document.createElement("td");
554
+ cLog.textContent = m.message.substr( m.message.indexOf("SQL: ") + 5, 50) + "..."
555
+ cLog.fullLog = m.message;
556
+ cLog.title = m.message + "\nClick to copy"
557
+ cLog.addEventListener("click", e=> {navigator.clipboard.writeText(e.target.fullLog); alert("Copied to clipboard")})
558
+ logRow.appendChild (cService)
559
+ logRow.appendChild (cTime)
560
+ logRow.appendChild (cUser)
561
+ logRow.appendChild (cMethod)
562
+ logRow.appendChild (cQueryTime)
563
+ logRow.appendChild (cTotalTime)
564
+ logRow.appendChild (cLog)
565
+ tblResult.appendChild(logRow)
566
+
567
+
568
+ })
569
+
570
+
571
+
572
+
573
+
574
+
575
+
576
+ //await populateMessages(allMessages)
577
+
578
+
579
+ }
580
+
581
+
582
+ function numberWithCommas(x) {
583
+ // return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
584
+ return x.toLocaleString()
585
+ }
586
+
587
+ init();
588
+
589
+ const btnTraceLogs = document.getElementById("btnTraceLogs");
590
+ btnTraceLogs.addEventListener("click", e => loadTraceLogs())
591
+
592
+ const btnValidateLogs = document.getElementById("btnValidateLogs");
593
+ btnValidateLogs.addEventListener("click", e => loadValidateLogs())
594
+
595
+ const btnUpdateSubnetworkLogs = document.getElementById("btnUpdateSubnetworkLogs");
596
+ btnUpdateSubnetworkLogs.addEventListener("click", e => loadUpdateSubnetworkLogs())
597
+
598
+ const btnSQLLogs = document.getElementById("btnSQLLogs");
599
+ btnSQLLogs.addEventListener("click", e => loadSQLLogs())
600
+
601
+ const btnAR = document.getElementById("btnAR");
602
+ btnAR.addEventListener("click", e => loadAttributeRules())
603
+
604
+
605
+
606
+ async function populateMessages(allTheMessages) {
607
+
608
+ //sort messages
609
+
610
+ const allMessages = allTheMessages.map(m => {
611
+ const newMessage = Object.assign({}, m);
612
+ delete newMessage.machine;
613
+ delete newMessage.type;
614
+ delete newMessage.code;
615
+ delete newMessage.requestID;
616
+ delete newMessage.process;
617
+ delete newMessage.thread;
618
+ newMessage.elapsedms = parseInt (parseFloat(newMessage.elapsed) * 1000)
619
+ newMessage.time = new Date(newMessage.time).toLocaleString()
620
+ delete newMessage.elapsed
621
+ return newMessage;
622
+ })
623
+ .sort( (m1,m2) => m2.elapsedms - m1.elapsedms)
624
+
625
+ //build table
626
+ const tblResult = document.getElementById("tblResult");
627
+ //clear
628
+ while(tblResult.firstChild) tblResult.removeChild(tblResult.firstChild)
629
+
630
+ const header = document.createElement("tr");
631
+ const cService = document.createElement("th");
632
+ cService.textContent = "Source"
633
+ const cTime = document.createElement("th");
634
+ cTime.textContent = "Time"
635
+ const cUser = document.createElement("th");
636
+ cUser.textContent = "User"
637
+ const cMethod = document.createElement("th");
638
+ cMethod.textContent = "Method"
639
+ const cElapsedMS = document.createElement("th");
640
+ cElapsedMS.textContent = "Elapsed (ms)"
641
+ const cLog = document.createElement("th");
642
+ cLog.textContent = "Full Log"
643
+ header.appendChild (cService)
644
+ header.appendChild (cTime)
645
+ header.appendChild (cUser)
646
+ header.appendChild (cMethod)
647
+ header.appendChild (cElapsedMS)
648
+ header.appendChild (cLog)
649
+ tblResult.appendChild(header)
650
+ allMessages.forEach(m => {
651
+ const logRow = document.createElement("tr");
652
+ const cService = document.createElement("td");
653
+ cService.textContent = m.source.replace(".MapServer", "")
654
+ const cTime = document.createElement("td");
655
+ cTime.textContent = m.time
656
+ const cUser = document.createElement("td");
657
+ cUser.textContent = m.user
658
+ const cMethod = document.createElement("td");
659
+ cMethod.textContent = m.methodName
660
+ const cElapsedMS = document.createElement("td");
661
+ cElapsedMS.textContent = m.elapsedms
662
+ const cLog = document.createElement("td");
663
+ cLog.textContent = "..."
664
+ cLog.fullLog = m.message;
665
+ cLog.addEventListener("click", e=> {navigator.clipboard.writeText(e.target.fullLog); alert("Copied to clipboard")})
666
+ logRow.appendChild (cService)
667
+ logRow.appendChild (cTime)
668
+ logRow.appendChild (cUser)
669
+ logRow.appendChild (cMethod)
670
+ logRow.appendChild (cElapsedMS)
671
+ logRow.appendChild (cLog)
672
+ tblResult.appendChild(logRow)
673
+ })
674
+ }
675
+ </script>
676
+ </body>
677
+ </html>