un-cli 0.0.70 → 0.0.73

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.
Files changed (4) hide show
  1. package/index.html +246 -179
  2. package/index.mjs +100 -87
  3. package/logger.mjs +16 -2
  4. package/package.json +1 -1
package/index.html CHANGED
@@ -9,16 +9,32 @@
9
9
  <body>
10
10
 
11
11
  <table>
12
+ <tr>
13
+ <td>
14
+ Admin User
15
+ </td>
16
+ <td colspan =3><input type = 'text' id = 'txtAdmin' value = 'admin'></td>
17
+ </tr>
18
+ <tr>
19
+ <td>
20
+ Admin Password
21
+ </td>
22
+ <td colspan =3><input type = 'password' id = 'txtPassword' value = ''></td>
23
+ </tr>
24
+ <tr>
25
+
26
+ <td colspan =5><button id = 'btnLogin'>Login</button></td>
27
+ </tr>
12
28
  <tr><td>Service</td>
13
29
  <td colspan =3 ><select id ='cmbService'>
14
- <option>(All Services)</option>
30
+
15
31
  </select>
16
32
  </td>
17
33
  </tr>
18
34
 
19
35
  <tr>
20
36
  <td >Age</td>
21
- <td colspan =3><input type ='text' id = 'txtAge' value = '30' style="width:30px"> minutes</td>
37
+ <td colspan =3><input type ='text' id = 'txtAge' value = '10' style="width:30px"> minutes</td>
22
38
  </tr>
23
39
  <tr colspan =4>
24
40
  <td><button id = 'btnTraceLogs'>Trace Logs</button></td>
@@ -26,7 +42,8 @@
26
42
  <td><button id = 'btnUpdateSubnetworkLogs'>Update Subnetwork Logs</button></td>
27
43
  <td><button id = 'btnAR'>Attribute Rules Logs</button></td>
28
44
  <td><button id = 'btnSQLLogs'>SQL Logs</button></td>
29
-
45
+ <td>Message<input id = 'txtFilter' type = 'text'></td>
46
+ <td>User<input id = 'txtUser' type = 'text'></td>
30
47
  </tr>
31
48
 
32
49
  </table>
@@ -39,23 +56,42 @@
39
56
  import { UtilityNetwork } from "./utilitynetwork.node.mjs"
40
57
  import { AdminLog } from "./adminlog.mjs"
41
58
  import logger from "./logger.mjs"
59
+
60
+
42
61
 
43
- const parameters = {
62
+ let parameters = {
44
63
  "user": "unadmin",
45
- "password": "unadmin.109",
64
+ "password": "",
46
65
  "portal": "https://utilitynetwork.esri.com/portal",
47
- "service": "RedTrolley_SQLServer",
66
+ "service": "",
48
67
  "referer": "https://utilitynetwork.esri.com/log"
49
68
  }
69
+
50
70
 
51
71
  let portal;
52
72
  let adminLog = null;
53
73
  let cmbService
54
74
  let token;
75
+ const btnLogin = document.getElementById("btnLogin")
76
+ const txtAdmin = document.getElementById("txtAdmin");
77
+ const txtPassword = document.getElementById("txtPassword")
78
+
79
+ btnLogin.addEventListener("click", () => init())
55
80
  async function init() {
56
-
81
+ try {
82
+
83
+
84
+ parameters.user = txtAdmin.value;
85
+ parameters.password = txtPassword.value;
86
+ parameters.referer = window.location.href;
87
+
57
88
  cmbService = document.getElementById("cmbService")
58
-
89
+ while (cmbService.firstChild) cmbService.removeChild(cmbService.firstChild)
90
+
91
+ const opt = document.createElement("option")
92
+ opt.textContent = "(All Services)"
93
+ cmbService.appendChild (opt)
94
+
59
95
  token = await getToken(parameters);
60
96
  const services = await portal.services()
61
97
  const featureServices = services.services.filter(s => s.type == "FeatureServer")
@@ -64,6 +100,20 @@
64
100
  o.text = s.name;
65
101
  cmbService.appendChild(o);
66
102
  })
103
+
104
+
105
+
106
+ document.getElementById("btnTraceLogs").disabled = false
107
+ document.getElementById("btnValidateLogs").disabled = false
108
+ document.getElementById("btnUpdateSubnetworkLogs").disabled = false
109
+ document.getElementById("btnAR").disabled = false
110
+ document.getElementById("btnSQLLogs").disabled = false
111
+
112
+
113
+ }
114
+ catch(ex){
115
+ alert(`Failed to login to ${parameters.portal} check the user/password and make sure its an admin`)
116
+ }
67
117
  }
68
118
 
69
119
 
@@ -82,42 +132,17 @@
82
132
  const tblResult = document.getElementById("tblResult");
83
133
  //clear
84
134
  while(tblResult.firstChild) tblResult.removeChild(tblResult.firstChild)
85
- tblResult.appendChild(document.createTextNode("Loading...."));
86
135
 
87
136
 
88
137
  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
-
138
+
99
139
  let mins = document.getElementById("txtAge").value //query logs for the last 30 minutes
100
140
 
101
141
  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
-
142
+
143
+ //page query the admin log
144
+ let allMessages = await adminLogQueryWithPaging(mins, parameters.service, [102002], "------ Trace Parameters ----", "VERBOSE")
145
+
121
146
  await populateMessages(allMessages)
122
147
 
123
148
 
@@ -126,49 +151,23 @@
126
151
 
127
152
 
128
153
  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)
154
+ //build table
155
+ const tblResult = document.getElementById("tblResult");
156
+ //clear
157
+ while(tblResult.firstChild) tblResult.removeChild(tblResult.firstChild)
140
158
 
141
- logger.info("Connected.")
142
-
143
-
144
- const topLogCount = 1000;
145
- const pageSize = 10000
159
+ parameters.service = cmbService.options[cmbService.selectedIndex].text
146
160
 
161
+
147
162
  let mins = document.getElementById("txtAge").value //query logs for the last 30 minutes
148
163
 
149
164
  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
-
165
+
166
+ //-1 && m.message.indexOf("The network is built.") > -1 && m.methodName == 'BuildEngineLog')
167
+ //page query the admin log
168
+ let allMessages = await adminLogQueryWithPaging(mins, parameters.service, [102003], "The network is built.", "VERBOSE")
169
+
170
+
172
171
  //validate logs missing elapsed populate it
173
172
  allMessages = allMessages.map( m => {
174
173
  try{
@@ -195,45 +194,21 @@ tblResult.appendChild(document.createTextNode("Loading...."));
195
194
 
196
195
 
197
196
  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)
197
+ //build table
198
+ const tblResult = document.getElementById("tblResult");
199
+ //clear
200
+ while(tblResult.firstChild) tblResult.removeChild(tblResult.firstChild)
207
201
 
208
- logger.info("Connected.")
209
-
210
-
211
- const topLogCount = 1000;
212
- const pageSize = 10000
202
+ parameters.service = cmbService.options[cmbService.selectedIndex].text
203
+
204
+
205
+ let mins = document.getElementById("txtAge").value //query logs for the last 30 minutes
213
206
 
214
- let mins = document.getElementById("txtAge").value //query logs for the last 30 minutes
207
+
208
+ console.log(`Querying subnetwork logs for ${parameters.service} for the last ${mins} minutes ...`)
209
+ let allMessages = await adminLogQueryWithPaging(mins, parameters.service, [102003], "---- Subnetwork Parameters ----", "VERBOSE")
215
210
 
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
-
211
+
237
212
  //update subnetwork missing elapsed populate it
238
213
  allMessages = allMessages.map( m => {
239
214
  try{
@@ -265,41 +240,20 @@ async function loadAttributeRules () {
265
240
 
266
241
  //build table
267
242
  const tblResult = document.getElementById("tblResult");
268
- tblResult.appendChild(document.createTextNode("Loading...."));
269
-
243
+ while(tblResult.firstChild) tblResult.removeChild(tblResult.firstChild)
244
+
270
245
  let mins = document.getElementById("txtAge").value //query logs for the last 30 minutes
271
246
 
272
247
  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
-
248
+
276
249
  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
250
+ let showMinGuid = false
251
+
286
252
  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
- }
253
+ let allMessages = await adminLogQueryWithPaging(mins, parameters.service, [102003], "Attribute rule execution complete:", "DEBUG")
301
254
 
302
- const arMessages = allMessages
255
+
256
+ const arMessages = filterMessages(allMessages)
303
257
  .filter(m => m.message.indexOf("Attribute rule execution complete:") > -1)
304
258
  .map (m => JSON.parse(m.message.replace("Attribute rule execution complete:", "")))
305
259
  .map( m => {
@@ -370,7 +324,8 @@ async function loadAttributeRules () {
370
324
  │ Min execution time (m
371
325
 
372
326
  */
373
-
327
+ while(tblResult.firstChild) tblResult.removeChild(tblResult.firstChild)
328
+
374
329
  const header = document.createElement("tr");
375
330
  const cAttributeRule = document.createElement("th");
376
331
  cAttributeRule.textContent = "Attribute Rule"
@@ -439,48 +394,70 @@ async function loadSQLLogs () {
439
394
  const tblResult = document.getElementById("tblResult");
440
395
  //clear
441
396
  while(tblResult.firstChild) tblResult.removeChild(tblResult.firstChild)
442
- tblResult.appendChild(document.createTextNode("Loading...."));
443
-
397
+
444
398
 
445
399
  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.")
400
+
401
+
402
+ let mins = document.getElementById("txtAge").value //query logs for the last 30 minutes
451
403
 
404
+
405
+ console.log(`Querying cursor sql logs for ${parameters.service} for the last ${mins} minutes ...`)
452
406
 
453
- const topLogCount = 1000;
454
- const pageSize = 10000
407
+ //startTime is the most recent
408
+ //endTime is the oldest
455
409
 
456
- let mins = document.getElementById("txtAge").value //query logs for the last 30 minutes
410
+
457
411
 
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)")
412
+ /*
413
+ const topLogCount = 100;
414
+ const startTime = Date.now()
415
+ const endTime = Date.now() - mins*60*1000
416
+ let services = [theService + ".MapServer"]
417
+ if (theService == "(All Services)")
464
418
  services = "*"
465
- let result= await adminLog.query([102023], services, topLogCount, startTime ,endTime , "DEBUG")
419
+ let result= await adminLog.query([code], services, topLogCount, startTime ,endTime , "DEBUG")
466
420
  let jsonRes = await result.json()
467
421
  let allMessages = [].concat(jsonRes.logMessages)
468
422
  allMessages = allMessages.filter(m => m.message.indexOf("EndCursor;") > -1)
469
423
  while (jsonRes.hasMore)
470
424
  {
471
425
  //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")
426
+ logger.info(`Aggregating messages... total so far ${allMessages.length} entries but more left, pulling logs between ${new Date(jsonRes.endTime)} and ${new Date(endTime)}`)
427
+ result= await adminLog.query([102023], services, pageSize, jsonRes.endTime, endTime, "DEBUG")
474
428
  jsonRes = await result.json()
475
429
 
476
430
  allMessages = allMessages.concat(jsonRes.logMessages.filter(m => m.message.indexOf("EndCursor;") > -1))
477
431
  }
432
+ */
433
+
434
+ //page query the admin log
435
+ let allMessages = await adminLogQueryWithPaging(mins, parameters.service, [102023], "EndCursor;", "DEBUG")
436
+
437
+
478
438
  console.log ("Filtering messages...")
479
439
 
480
- allMessages = allMessages
440
+ allMessages = filterMessages(allMessages)
481
441
  .map( m=> {
482
- m.dataAccessElapsed = parseFloat(m.message.split(";")[1].split(" ")[1])
483
- m.executeQueryElapsed = parseFloat(m.message.split(";")[2].split(" ")[1])
442
+ m.dataAccessElapsed =0;
443
+ m.executeQueryElapsed = 0;
444
+ const sDataAccess = "DataAccess "
445
+ const idxDataAccess = m.message.indexOf(sDataAccess)
446
+ if (idxDataAccess >=0) {
447
+ const idxNext = m.message.indexOf(" ",idxDataAccess + sDataAccess.length )
448
+ m.dataAccessElapsed = parseInt(m.message.substr( idxDataAccess + sDataAccess.length, idxNext - idxDataAccess - sDataAccess.length))
449
+ }
450
+
451
+ const sExecuteQuery = "ExecuteQuery "
452
+ const idxExecuteQuery = m.message.indexOf(sExecuteQuery)
453
+ if (idxExecuteQuery >=0) {
454
+ const idxNext = m.message.indexOf(" ",idxExecuteQuery + sExecuteQuery.length)
455
+ m.executeQueryElapsed = parseInt(m.message.substr( idxExecuteQuery + sExecuteQuery.length, idxNext - idxExecuteQuery - sExecuteQuery.length))
456
+ }
457
+
458
+
459
+ //m.dataAccessElapsed = parseFloat(m.message.split(";")[1].split(" ")[1])
460
+ //m.executeQueryElapsed = parseFloat(m.message.split(";")[2].split(" ")[1])
484
461
  m.totalExecutionElapsed = m.dataAccessElapsed + m.executeQueryElapsed
485
462
  m.elapsed = parseFloat(m.elapsed); return m;
486
463
 
@@ -489,7 +466,7 @@ tblResult.appendChild(document.createTextNode("Loading...."));
489
466
  .slice(0, 100) ;//first 100
490
467
 
491
468
 
492
- console.log("-----Top 10 SQL----")
469
+ console.log("-----Top SQL----")
493
470
  while(tblResult.firstChild) tblResult.removeChild(tblResult.firstChild)
494
471
 
495
472
  let i =0;
@@ -501,8 +478,8 @@ tblResult.appendChild(document.createTextNode("Loading...."));
501
478
  cTime.textContent = "Time"
502
479
  const cUser = document.createElement("th");
503
480
  cUser.textContent = "User"
504
- const cMethod = document.createElement("th");
505
- cMethod.textContent = "Method"
481
+ const cVersion = document.createElement("th");
482
+ cVersion.textContent = "Version"
506
483
  const cQueryTime = document.createElement("th");
507
484
  cQueryTime.textContent = "Query Time (ms)"
508
485
  cQueryTime.title = "includes search + data access nextRow"
@@ -514,7 +491,7 @@ tblResult.appendChild(document.createTextNode("Loading...."));
514
491
  header.appendChild (cService)
515
492
  header.appendChild (cTime)
516
493
  header.appendChild (cUser)
517
- header.appendChild (cMethod)
494
+ header.appendChild (cVersion)
518
495
  header.appendChild (cQueryTime)
519
496
  header.appendChild (cTotalTime)
520
497
  header.appendChild (cLog)
@@ -544,21 +521,32 @@ tblResult.appendChild(document.createTextNode("Loading...."));
544
521
 
545
522
  const cUser = document.createElement("td");
546
523
  cUser.textContent = m.user
547
- const cMethod = document.createElement("td");
548
- cMethod.textContent = "Cursor"
524
+ const cVersion = document.createElement("td");
525
+ const idxVersion = m.message.indexOf("Version: ")
526
+ if (idxVersion >=0) {
527
+ const idxNext = m.message.indexOf(";",idxVersion)
528
+ cVersion.textContent = m.message.substr( idxVersion + 9, idxNext - idxVersion - 9 )
529
+ }
549
530
  const cQueryTime = document.createElement("td");
550
531
  cQueryTime.textContent = numberWithCommas(m.totalExecutionElapsed)
551
532
  const cTotalTime = document.createElement("td");
552
533
  cTotalTime.textContent = numberWithCommas(Math.round(m.elapsed*1000))
553
534
  const cLog = document.createElement("td");
554
- cLog.textContent = m.message.substr( m.message.indexOf("SQL: ") + 5, 50) + "..."
535
+ const cLogText = document.createElement("input")
536
+ cLogText.type = "text"
537
+ cLogText.style = "width:500px"
538
+ cLogText.value = m.message.substr( m.message.indexOf("SQL: ") + 5, m.message.length)
539
+ cLogText.readOnly= true;
540
+ cLog.appendChild(cLogText)
541
+ //cLog.textContent = m.message.substr( m.message.indexOf("SQL: ") + 5, 50) + "..."
555
542
  cLog.fullLog = m.message;
556
543
  cLog.title = m.message + "\nClick to copy"
557
- cLog.addEventListener("click", e=> {navigator.clipboard.writeText(e.target.fullLog); alert("Copied to clipboard")})
544
+ cLog.addEventListener("click", e=> {navigator.clipboard.writeText(e.target.fullLog); e.target.selectionStart = 0; e.target.selectionEnd = e.target.value.length;
545
+ /* alert("Copied to clipboard") */})
558
546
  logRow.appendChild (cService)
559
547
  logRow.appendChild (cTime)
560
548
  logRow.appendChild (cUser)
561
- logRow.appendChild (cMethod)
549
+ logRow.appendChild (cVersion)
562
550
  logRow.appendChild (cQueryTime)
563
551
  logRow.appendChild (cTotalTime)
564
552
  logRow.appendChild (cLog)
@@ -584,30 +572,50 @@ function numberWithCommas(x) {
584
572
  return x.toLocaleString()
585
573
  }
586
574
 
587
- init();
575
+ //init();
588
576
 
589
577
  const btnTraceLogs = document.getElementById("btnTraceLogs");
590
578
  btnTraceLogs.addEventListener("click", e => loadTraceLogs())
579
+ btnTraceLogs.disabled = true
591
580
 
592
581
  const btnValidateLogs = document.getElementById("btnValidateLogs");
593
582
  btnValidateLogs.addEventListener("click", e => loadValidateLogs())
583
+ btnValidateLogs.disabled = true
594
584
 
595
585
  const btnUpdateSubnetworkLogs = document.getElementById("btnUpdateSubnetworkLogs");
596
586
  btnUpdateSubnetworkLogs.addEventListener("click", e => loadUpdateSubnetworkLogs())
597
-
587
+ btnUpdateSubnetworkLogs.disabled = true
588
+
598
589
  const btnSQLLogs = document.getElementById("btnSQLLogs");
599
590
  btnSQLLogs.addEventListener("click", e => loadSQLLogs())
600
-
591
+ btnSQLLogs.disabled = true
592
+
601
593
  const btnAR = document.getElementById("btnAR");
602
594
  btnAR.addEventListener("click", e => loadAttributeRules())
603
-
604
-
595
+ btnAR.disabled = true
596
+
597
+ function filterMessages (allMessages) {
598
+ const txtFilter = document.getElementById("txtFilter")
599
+ const txtUser = document.getElementById("txtUser")
600
+ if (txtFilter.value == "" && txtUser.value == "") return allMessages;
601
+ //const filtered= allMessages.filter(m => m.message.toUpperCase().indexOf(txtFilter.value.toUpperCase()) > 0 && m.user.toUpperCase().indexOf(txtUser.value.toUpperCase()) > 0)
602
+ const filtered= allMessages.filter(m => {
603
+
604
+ if (m.message.toUpperCase().indexOf(txtFilter.value.toUpperCase()) >= 0
605
+ &&
606
+ m.user.toUpperCase().indexOf(txtUser.value.toUpperCase()) >= 0)
607
+ return true
608
+
609
+ return false
610
+ })
611
+ return filtered
612
+ }
605
613
 
606
614
  async function populateMessages(allTheMessages) {
607
615
 
608
616
  //sort messages
609
617
 
610
- const allMessages = allTheMessages.map(m => {
618
+ const allMessages = filterMessages (allTheMessages).map(m => {
611
619
  const newMessage = Object.assign({}, m);
612
620
  delete newMessage.machine;
613
621
  delete newMessage.type;
@@ -672,6 +680,65 @@ function numberWithCommas(x) {
672
680
  tblResult.appendChild(logRow)
673
681
  })
674
682
  }
683
+
684
+
685
+ async function adminLogQueryWithPaging(mins, theService, code, filter, level){
686
+ const topLogCount = 1000;
687
+ let stop = false;
688
+ const prg = document.createTextNode("Loading.... 0%");
689
+ const btn = document.createElement("button")
690
+ btn.textContent = '🛑'
691
+ btn.addEventListener("click", ()=> stop = true )
692
+ //create a new admin object (user might not be admin we won't use it until the user call log )
693
+ let adminLog = new AdminLog(token, portal.serverUrl)
694
+ tblResult.appendChild(prg);
695
+ tblResult.appendChild(btn)
696
+ const startTime = Date.now()
697
+ const endTime = Date.now() - mins*60*1000
698
+ let services = [theService + ".MapServer"]
699
+ if (theService == "(All Services)")
700
+ services = "*"
701
+ let result= await adminLog.query(code, services, topLogCount, startTime ,endTime , level)
702
+ let jsonRes = await result.json()
703
+ let allMessages = [].concat(jsonRes.logMessages)
704
+ allMessages = allMessages.filter(m => m.message.indexOf(filter) > -1)
705
+ while (jsonRes.hasMore && !stop)
706
+ {
707
+ //start paging
708
+ prg.textContent = "Loading ... " + parseInt((( (startTime - endTime) - (jsonRes.endTime - endTime) ) /((startTime - endTime)))*100) + "%"
709
+ logger.info(`Aggregating messages... total so far ${allMessages.length} entries but more left, pulling logs between ${new Date(jsonRes.endTime)} and ${new Date(endTime)}`)
710
+ result= await adminLog.query(code, services, topLogCount, jsonRes.endTime, endTime, level)
711
+ jsonRes = await result.json()
712
+
713
+ allMessages = allMessages.concat(jsonRes.logMessages.filter(m => m.message.indexOf(filter) > -1))
714
+ }
715
+
716
+ return allMessages
717
+
718
+ }
719
+
720
+
721
+ /*
722
+ const topLogCount = 100;f
723
+ const startTime = Date.now()
724
+ const endTime = Date.now() - mins*60*1000
725
+ let services = [theService + ".MapServer"]
726
+ if (theService == "(All Services)")
727
+ services = "*"
728
+ let result= await adminLog.query([code], services, topLogCount, startTime ,endTime , "DEBUG")
729
+ let jsonRes = await result.json()
730
+ let allMessages = [].concat(jsonRes.logMessages)
731
+ allMessages = allMessages.filter(m => m.message.indexOf("EndCursor;") > -1)
732
+ while (jsonRes.hasMore)
733
+ {
734
+ //start paging
735
+ logger.info(`Aggregating messages... total so far ${allMessages.length} entries but more left, pulling logs between ${new Date(jsonRes.endTime)} and ${new Date(endTime)}`)
736
+ result= await adminLog.query([102023], services, pageSize, jsonRes.endTime, endTime, "DEBUG")
737
+ jsonRes = await result.json()
738
+
739
+ allMessages = allMessages.concat(jsonRes.logMessages.filter(m => m.message.indexOf("EndCursor;") > -1))
740
+ }
741
+ */
675
742
  </script>
676
743
  </body>
677
744
  </html>
package/index.mjs CHANGED
@@ -7,7 +7,7 @@ import { AdminLog } from "./adminlog.mjs"
7
7
  import logger from "./logger.mjs"
8
8
  import fetch from "node-fetch"
9
9
  //update version
10
- let version = "0.0.70";
10
+ let version = "0.0.73";
11
11
  const GENERATE_TOKEN_TIME_MIN = 30;
12
12
 
13
13
  let rl = null;
@@ -53,10 +53,10 @@ function parseInput(){
53
53
 
54
54
  if (Object.values(params).includes(null))
55
55
  {
56
- console.log ("HELP: uncli --portal https://unportal.domain.com/portal --service servicename --user username --password password [--gdbversion* user.version --server https://federatedserver.domain.com/server --file commandfile* --verify true|false]")
57
- console.log("--file commandfile is optional and you can pass a path to a file with a list of command to execute. ")
58
- console.log("--gdbversion is optional and allows the UN to be opened in that version. When not specified sde.DEFAULT is used.")
59
- console.log("--server is optional except when there are more than one federated server sites to the portal. If the portal only has one server it will be selected.")
56
+ logger.info ("HELP: uncli --portal https://unportal.domain.com/portal --service servicename --user username --password password [--gdbversion* user.version --server https://federatedserver.domain.com/server --file commandfile* --verify true|false]")
57
+ logger.info("--file commandfile is optional and you can pass a path to a file with a list of command to execute. ")
58
+ logger.info("--gdbversion is optional and allows the UN to be opened in that version. When not specified sde.DEFAULT is used.")
59
+ logger.info("--server is optional except when there are more than one federated server sites to the portal. If the portal only has one server it will be selected.")
60
60
  process.exit();
61
61
  }
62
62
 
@@ -73,7 +73,7 @@ async function getToken(parameters) {
73
73
  }
74
74
 
75
75
  async function regenerateToken(parameters) {
76
- console.log("Regenerating token.")
76
+ logger.info("Regenerating token.")
77
77
  const token = await getToken(parameters);
78
78
  un.token = token;
79
79
  executeInput("clear");
@@ -193,7 +193,7 @@ const inputs = {
193
193
  },
194
194
  "^whoami$": async () => {
195
195
 
196
- console.log(`${parameters.user}@${parameters.service}@${parameters.gdbversion}`)
196
+ logger.info(`${parameters.user}@${parameters.service}@${parameters.gdbversion}`)
197
197
 
198
198
  },
199
199
  "^def --layers$|^layers$": async () => {
@@ -231,20 +231,20 @@ const inputs = {
231
231
 
232
232
  const subnetworks = await un.getSubnetworks();
233
233
  if (subnetworks.features.length === 0) {
234
- console.log("No dirty subnetworks found.")
234
+ logger.info("No dirty subnetworks found.")
235
235
  return;
236
236
  }
237
237
  const subs = subnetworks.features.map(a => a.attributes)
238
238
  console.table(subs)
239
239
  const rowCount = subs.length;
240
- console.log (`${numberWithCommas(rowCount)} rows returned.`)
240
+ logger.info (`${numberWithCommas(rowCount)} rows returned.`)
241
241
  },
242
242
  "^topology$": async () => {
243
243
  const moments = ["initialEnableTopology","fullValidateTopology","partialValidateTopology","enableTopology","disableTopology","definitionModification","updateIsConnected"]
244
244
  const networkMoments = await un.queryMoment(moments)
245
245
  // networkMoments.forEach (m => momentsText += `\n${m.moment} : ${m.time === 0 ? "N/A": new Date(m.time*1000)} ${m.duration === 0 ? "" : ` Duration: ${Math.round(m.duration/1000)}s `} `)
246
246
  // networkMoments.forEach (m => momentsText += `\n${m.moment} : ${m.time === 0 ? "N/A": new Date(m.time*1000)} ${m.duration === 0 ? "" : ` Duration: ${Math.round(m.duration/1000)}s `} `)
247
- // console.log('\x1b[36m%s\x1b[0m', 'I am cyan'); //cyan
247
+ // logger.info('\x1b[36m%s\x1b[0m', 'I am cyan'); //cyan
248
248
  const topoMoments = networkMoments.networkMoments.map(m => {
249
249
  const t = m.time === 0 ? "N/A": new Date(m.time*1000)
250
250
  const d = m.duration === 0 ? "N/A" : numberWithCommas(Math.round(m.duration)) + " ms"
@@ -260,7 +260,7 @@ const inputs = {
260
260
  console.table(topoMoments)
261
261
  },
262
262
  "^topology --enable$": async () => {
263
- console.log("Enabling topology ...");
263
+ logger.info("Enabling topology ...");
264
264
  const fromDate = new Date();
265
265
  const result = await un.enableTopology()
266
266
  const toDate = new Date();
@@ -270,7 +270,7 @@ const inputs = {
270
270
  },
271
271
  "^topology --disable$": async () => {
272
272
  const fromDate = new Date();
273
- console.log("Disabling topology ...");
273
+ logger.info("Disabling topology ...");
274
274
  const result = await un.disableTopology()
275
275
  const toDate = new Date();
276
276
  const timeEnable = toDate.getTime() - fromDate.getTime();
@@ -279,25 +279,25 @@ const inputs = {
279
279
  },
280
280
  "^evaluate$": async () => {
281
281
  const fromDate = new Date();
282
- console.log("Building Evaluation Blocks ...");
282
+ logger.info("Building Evaluation Blocks ...");
283
283
  //return evaluation blocks for layer 5
284
284
  const blocks = await buildEvaluationBlocks(5);
285
285
 
286
- console.log("Evaluating Attribute Rules ...");
286
+ logger.info("Evaluating Attribute Rules ...");
287
287
  //blocks.forEach(b => un.evaluate (null, b, ["validationRules", "calculationRules"], async = false, gdbVersion = "sde.DEFAULT"))
288
- //Object.keys(blocks).forEach(k => console.log(blocks[k]))
288
+ //Object.keys(blocks).forEach(k => logger.info(blocks[k]))
289
289
  const promises = []
290
290
  Object.keys(blocks).forEach(k => promises.push(un.evaluate (null, blocks[k], ["validationRules", "calculationRules"] )))
291
291
 
292
- console.log("done sending all requests.. now waiting for response ")
292
+ logger.info("done sending all requests.. now waiting for response ")
293
293
 
294
- Promise.all(promises).then(a=>console.log("done")).catch(a=>console.log("failed" + JSON.stringify(a)))
294
+ Promise.all(promises).then(a=>logger.info("done")).catch(a=>logger.info("failed" + JSON.stringify(a)))
295
295
 
296
296
  const result = {}
297
297
  const toDate = new Date();
298
298
  const timeEnable = toDate.getTime() - fromDate.getTime();
299
299
  result.duration = numberWithCommas(Math.round(timeEnable)) + " ms"
300
- console.log(result)
300
+ logger.info(result)
301
301
  },
302
302
 
303
303
  //partition so that we can run and commit incrementally..
@@ -305,7 +305,7 @@ const inputs = {
305
305
  //timeouts
306
306
  //in case failure you don't lose everything
307
307
  "^topology --validate -fn$": async () => {
308
- console.log("Validating Network topology ...");
308
+ logger.info("Validating Network topology ...");
309
309
 
310
310
  const fullExtent = un.featureServiceJson.fullExtent;
311
311
  /*
@@ -343,7 +343,7 @@ const inputs = {
343
343
  const timeEnable = toDate.getTime() - fromDate.getTime();
344
344
  const duration = numberWithCommas(Math.round(timeEnable)) + " ms"
345
345
  console.clear()
346
- console.log("Validating extent " + e.xmin)
346
+ logger.info("Validating extent " + e.xmin)
347
347
  console.table({duration})
348
348
 
349
349
  })
@@ -352,7 +352,7 @@ const inputs = {
352
352
  },
353
353
 
354
354
  "^topology --validate$": async () => {
355
- console.log("Validating Network topology ...");
355
+ logger.info("Validating Network topology ...");
356
356
  const fromDate = new Date();
357
357
  const result = await un.validateNetworkTopology()
358
358
  const toDate = new Date();
@@ -363,35 +363,35 @@ const inputs = {
363
363
  "^subnetworks --dirty$": async () => {
364
364
  const subnetworks = await un.getSubnetworks("isdirty=1");
365
365
  if (subnetworks.features.length === 0) {
366
- console.log("No dirty subnetworks found.")
366
+ logger.info("No dirty subnetworks found.")
367
367
  return;
368
368
  }
369
369
 
370
370
  const subs = subnetworks.features.map(a => a.attributes)
371
371
  console.table(subs)
372
372
  const rowCount = subs.length;
373
- console.log (`${numberWithCommas(rowCount)} rows returned.`)
373
+ logger.info (`${numberWithCommas(rowCount)} rows returned.`)
374
374
  },
375
375
  "^subnetworks --deleted$": async () => {
376
376
  const subnetworks = await un.getSubnetworks("isdirty=1 and isdeleted=1");
377
377
  if (subnetworks.features.length === 0) {
378
- console.log("No dirty and deleted subnetworks found.")
378
+ logger.info("No dirty and deleted subnetworks found.")
379
379
  return;
380
380
  }
381
381
 
382
382
  const subs = subnetworks.features.map(a => a.attributes)
383
383
  console.table(subs)
384
384
  const rowCount = subs.length;
385
- console.log (`${numberWithCommas(rowCount)} rows returned.`)
385
+ logger.info (`${numberWithCommas(rowCount)} rows returned.`)
386
386
  },
387
387
 
388
388
  "^update subnetworks --deleted$" : async () => {
389
- console.log("Querying all subnetworks that are dirty and deleted.");
389
+ logger.info("Querying all subnetworks that are dirty and deleted.");
390
390
  let subnetworks = await un.queryDistinct(500002, "domainnetworkname,tiername,subnetworkname", "isdirty=1 and isdeleted=1","domainnetworkname,tiername,subnetworkname");
391
- console.log(`Discovered ${subnetworks.features.length} dirty deleted subnetworks.`);
391
+ logger.info(`Discovered ${subnetworks.features.length} dirty deleted subnetworks.`);
392
392
  for (let i = 0; i < subnetworks.features.length; i++) {
393
393
  const f = subnetworks.features[i]
394
- console.log("Updating Subnetwork " + v(f.attributes,"subnetworkName"));
394
+ logger.info("Updating Subnetwork " + v(f.attributes,"subnetworkName"));
395
395
 
396
396
  const fromDate = new Date();
397
397
 
@@ -404,34 +404,46 @@ const inputs = {
404
404
  subnetworkResult.duration = numberWithCommas(Math.round(timeEnable)) + " ms"
405
405
 
406
406
 
407
- console.log(`Result ${JSON.stringify(subnetworkResult)}`)
407
+ logger.info(`Result ${JSON.stringify(subnetworkResult)}`)
408
408
  }
409
409
  },
410
410
 
411
411
  "^update subnetworks --all" : async input => {
412
412
 
413
+ let subnetworks;
414
+ let more = false;
415
+ let failedSubnetworks = []
413
416
  do {
414
417
 
415
418
  let sort = "asc";
416
419
  if (input.indexOf("--desc") > 0) sort = "desc"
420
+ let failedSubWhereClause = ""
421
+
422
+ if (failedSubnetworks.length > 0 )
423
+ failedSubWhereClause = " AND SUBNETWORKNAME NOT IN (" + failedSubnetworks.join(",") + ")"
417
424
 
418
- console.log("Querying all subnetworks that are dirty.");
419
- let subnetworks = await un.queryDistinct(500002, "domainnetworkname,tiername,subnetworkname", "isdirty=1", `domainnetworkname ${sort},tiername ${sort},subnetworkname ${sort}`);
420
- console.log(`Discovered ${subnetworks.features.length} dirty subnetworks.`);
425
+ logger.info("Querying all subnetworks that are dirty.");
426
+ subnetworks = await un.queryDistinct(500002, "domainnetworkname,tiername,subnetworkname", "isdirty=1 " + failedSubWhereClause, `domainnetworkname ${sort},tiername ${sort},subnetworkname ${sort}`);
427
+ logger.info(`Discovered ${subnetworks.features.length} dirty subnetworks.`);
421
428
 
422
429
  for (let i = 0; i < subnetworks.features.length; i++) {
423
430
  const f = subnetworks.features[i]
424
- console.log("Updating Subnetwork " + v(f.attributes,"subnetworkName"));
431
+ const subnetworkName = v(f.attributes,"subnetworkName")
432
+ logger.info("Updating Subnetwork " + subnetworkName);
425
433
 
426
434
  const fromDate = new Date();
427
435
 
428
436
  const subnetworkResult = await un.updateSubnetworks(v(f.attributes,"domainNetworkName"), v(f.attributes,"tierName"), v(f.attributes,"subnetworkName"),false);
429
-
437
+ //check if we have processed this subnetwork (maybe be an error)
438
+ const tier = un.getTier(v(f.attributes,"domainNetworkName"), v(f.attributes,"tierName"))
439
+ if (subnetworkResult.success == false || tier.manageSubnetwork?.propertySetItems?.includes("IsDirty"))
440
+ failedSubnetworks.push("'" + subnetworkName + "'")
441
+
430
442
  const toDate = new Date();
431
443
  const timeEnable = toDate.getTime() - fromDate.getTime();
432
444
  subnetworkResult.duration = numberWithCommas(Math.round(timeEnable)) + " ms"
433
445
 
434
- console.log(`Result ${JSON.stringify(subnetworkResult)}`)
446
+ logger.info(`Result ${JSON.stringify(subnetworkResult)}`)
435
447
  }
436
448
 
437
449
  }
@@ -439,18 +451,19 @@ const inputs = {
439
451
 
440
452
  },
441
453
  "^update subnetworks --all --async$" : async () => {
442
- console.log("Querying all subnetworks that are dirty.");
454
+ logger.info("Querying all subnetworks that are dirty.");
443
455
  let subnetworks = await un.queryDistinct(500002, "domainnetworkname,tiername,subnetworkname", "isdirty=1", "domainnetworkname,tiername,subnetworkname");
444
- console.log(`Discovered ${subnetworks.features.length} dirty subnetworks.`);
456
+ logger.info(`Discovered ${subnetworks.features.length} dirty subnetworks.`);
445
457
  for (let i = 0; i < subnetworks.features.length; i++) {
446
458
  const f = subnetworks.features[i]
447
- console.log("Sending job for " + v(f.attributes,"subnetworkName"));
459
+ logger.info("Sending job for " + v(f.attributes,"subnetworkName"));
448
460
  const subnetworkResult = await un.updateSubnetworks(v(f.attributes,"domainNetworkName"), v(f.attributes,"tierName"), v(f.attributes,"subnetworkName"),true);
449
- console.log(`Result from submitting job ${JSON.stringify(subnetworkResult)}`)
461
+ logger.info(`Result from submitting job ${JSON.stringify(subnetworkResult)}`)
450
462
  }
451
463
  },
452
464
  "^export subnetworks --all --folder .*$|^export subnetworks --all$" : async input => {
453
465
 
466
+ let subnetworks
454
467
  //create folder
455
468
  const file = input.match(/--folder .*/gm)
456
469
  let inputDir = "Exported"
@@ -461,13 +474,13 @@ const inputs = {
461
474
 
462
475
  do {
463
476
 
464
- console.log("Querying all subnetworks that are clean.");
465
- let subnetworks = await un.queryDistinct(500002, "domainnetworkname,tiername,subnetworkname", "isdirty=0","domainnetworkname,tiername,subnetworkname");
466
- console.log(`Discovered ${subnetworks.features.length} subnetworks that can be exported.`);
477
+ logger.info("Querying all subnetworks that are clean.");
478
+ subnetworks = await un.queryDistinct(500002, "domainnetworkname,tiername,subnetworkname", "isdirty=0","domainnetworkname,tiername,subnetworkname");
479
+ logger.info(`Discovered ${subnetworks.features.length} subnetworks that can be exported.`);
467
480
  for (let i = 0; i < subnetworks.features.length; i++) {
468
481
  const f = subnetworks.features[i]
469
482
  const subnetworkName = v(f.attributes,"subnetworkName")
470
- console.log("Exporting subnetworks " + v(f.attributes,"subnetworkName"));
483
+ logger.info("Exporting subnetworks " + v(f.attributes,"subnetworkName"));
471
484
 
472
485
  const fromDate = new Date();
473
486
 
@@ -482,7 +495,7 @@ const inputs = {
482
495
  //if undefined exit
483
496
  if (!subnetworkResult.url)
484
497
  {
485
- console.log("Export subnetwork failed " + JSON.stringify(subnetworkResult))
498
+ logger.info("Export subnetwork failed " + JSON.stringify(subnetworkResult))
486
499
  continue;
487
500
  }
488
501
 
@@ -495,7 +508,7 @@ const inputs = {
495
508
  fs.writeFileSync(`${inputDir}/${subnetworkName}.json`, jsonExport)
496
509
 
497
510
 
498
- console.log(`Result ${JSON.stringify(subnetworkResult)} written to file ${process.cwd()}/${inputDir}/${subnetworkName}.json`)
511
+ logger.info(`Result ${JSON.stringify(subnetworkResult)} written to file ${process.cwd()}/${inputDir}/${subnetworkName}.json`)
499
512
 
500
513
  }
501
514
  }
@@ -515,20 +528,20 @@ const inputs = {
515
528
  if (!fs.existsSync(inputDir)) fs.mkdirSync(inputDir)
516
529
 
517
530
 
518
- console.log("Querying all subnetworks that are clean and not exported.");
531
+ logger.info("Querying all subnetworks that are clean and not exported.");
519
532
  let subnetworks = await un.queryDistinct(500002, "domainnetworkname,tiername,subnetworkname", "isdirty = 0 and (LASTACKEXPORTSUBNETWORK is null or LASTACKEXPORTSUBNETWORK < LASTUPDATESUBNETWORK)","domainnetworkname,tiername,subnetworkname");
520
- console.log(`Discovered ${subnetworks.features.length} subnetworks that can be exported.`);
533
+ logger.info(`Discovered ${subnetworks.features.length} subnetworks that can be exported.`);
521
534
  for (let i = 0; i < subnetworks.features.length; i++) {
522
535
  const f = subnetworks.features[i]
523
536
  const subnetworkName = v(f.attributes,"subnetworkName")
524
- console.log(`Exporting subnetwork ${subnetworkName}` );
537
+ logger.info(`Exporting subnetwork ${subnetworkName}` );
525
538
  const subnetworkResult = await un.exportSubnetworks(v(f.attributes,"domainNetworkName"), v(f.attributes,"tierName"), v(f.attributes,"subnetworkName"),false);
526
539
  //fetch the json and write it to disk
527
540
  const subContent = await fetch(subnetworkResult.url);
528
541
  const jsonExport = await subContent.text();
529
542
  fs.writeFileSync(`${inputDir}/${subnetworkName}.json`, JSON.stringify(jsonExport))
530
543
 
531
- console.log(`Result ${JSON.stringify(subnetworkResult)} written to file ${process.cwd()}/${inputDir}/${subnetworkName}.json`)
544
+ logger.info(`Result ${JSON.stringify(subnetworkResult)} written to file ${process.cwd()}/${inputDir}/${subnetworkName}.json`)
532
545
  }
533
546
 
534
547
 
@@ -538,7 +551,7 @@ const inputs = {
538
551
  "^ia$": async input => {
539
552
 
540
553
  const result = await un.returnInvalidAssociations();
541
- console.log("Invalid Associations " + JSON.stringify(result))
554
+ logger.info("Invalid Associations " + JSON.stringify(result))
542
555
  },
543
556
  "^connect --service": async input =>{
544
557
 
@@ -561,10 +574,10 @@ const inputs = {
561
574
  if (inputParam != null && inputParam.length > 0)
562
575
  subnetworkName = inputParam[0].replace("--subnetwork ", "")
563
576
 
564
- console.log(`Tracing subnetwork ${subnetworkName}`);
577
+ logger.info(`Tracing subnetwork ${subnetworkName}`);
565
578
  const result = await un.subnetworkTraceSimple(subnetworkName)
566
579
  if (result == null) {
567
- console.log(`Subnetwork ${subnetworkName} doesn't exist`);
580
+ logger.info(`Subnetwork ${subnetworkName} doesn't exist`);
568
581
  return null;
569
582
  }
570
583
  const toDate = new Date();
@@ -586,19 +599,19 @@ const inputs = {
586
599
  if (!fs.existsSync(inputDir)) fs.mkdirSync(inputDir)
587
600
 
588
601
 
589
- console.log("Querying all subnetworks that are clean and deleted.");
602
+ logger.info("Querying all subnetworks that are clean and deleted.");
590
603
  let subnetworks = await un.queryDistinct(500002, "domainnetworkname,tiername,subnetworkname", "isdirty = 0 and isdeleted=1");
591
- console.log(`Discovered ${subnetworks.features.length} subnetworks that can be exported.`);
604
+ logger.info(`Discovered ${subnetworks.features.length} subnetworks that can be exported.`);
592
605
  for (let i = 0; i < subnetworks.features.length; i++) {
593
606
  const f = subnetworks.features[i]
594
607
  const subnetworkName = v(f.attributes,"subnetworkName")
595
- console.log(`Exporting subnetwork ${subnetworkName}` );
608
+ logger.info(`Exporting subnetwork ${subnetworkName}` );
596
609
  const subnetworkResult = await un.exportSubnetworks(v(f.attributes,"domainNetworkName"), v(f.attributes,"tierName"), v(f.attributes,"subnetworkName"),false);
597
610
 
598
611
  //if undefined exit
599
612
  if (!subnetworkResult.url)
600
613
  {
601
- console.log("Export subnetwork failed " + JSON.stringify(subnetworkResult))
614
+ logger.info("Export subnetwork failed " + JSON.stringify(subnetworkResult))
602
615
  continue;
603
616
  }
604
617
 
@@ -607,7 +620,7 @@ const inputs = {
607
620
  const jsonExport = await subContent.text();
608
621
  fs.writeFileSync(`${inputDir}/${subnetworkName}.json`, JSON.stringify(jsonExport))
609
622
 
610
- console.log(`Result ${JSON.stringify(subnetworkResult)} written to file ${process.cwd()}/${inputDir}/${subnetworkName}.json`)
623
+ logger.info(`Result ${JSON.stringify(subnetworkResult)} written to file ${process.cwd()}/${inputDir}/${subnetworkName}.json`)
611
624
  }
612
625
 
613
626
 
@@ -616,7 +629,7 @@ const inputs = {
616
629
  "^cwd$" : async input => {
617
630
 
618
631
 
619
- console.log(process.cwd())
632
+ logger.info(process.cwd())
620
633
 
621
634
  },
622
635
 
@@ -628,14 +641,14 @@ const inputs = {
628
641
  //create directory if doesn't exists
629
642
  if (!fs.existsSync(inputDir)) fs.mkdirSync(inputDir)
630
643
  fs.writeFileSync(`${inputDir}/${Math.random()}`, Math.random())
631
- console.log(inputDir)
644
+ logger.info(inputDir)
632
645
 
633
646
 
634
647
  },
635
648
 
636
649
 
637
650
  "^count$": async () => {
638
- console.log("Querying all layers....")
651
+ logger.info("Querying all layers....")
639
652
  const layerProperties = [
640
653
  "id",
641
654
  "name",
@@ -669,12 +682,12 @@ const inputs = {
669
682
 
670
683
 
671
684
  console.table(layerCount)
672
- console.log(`Total number of rows in all layers : ${numberWithCommas(totalRows)} .`)
685
+ logger.info(`Total number of rows in all layers : ${numberWithCommas(totalRows)} .`)
673
686
  },
674
687
 
675
688
 
676
689
  "^count --system$": async () => {
677
- console.log("Querying all system layers....")
690
+ logger.info("Querying all system layers....")
678
691
 
679
692
  const systemLayers = un.getSystemLayers();
680
693
  let totalRows = 0;
@@ -697,7 +710,7 @@ const inputs = {
697
710
  }
698
711
 
699
712
  console.table(layerCount)
700
- console.log(`Total number of rows in all system layers : ${numberWithCommas(totalRows)} .`)
713
+ logger.info(`Total number of rows in all system layers : ${numberWithCommas(totalRows)} .`)
701
714
 
702
715
  },
703
716
 
@@ -712,7 +725,7 @@ const inputs = {
712
725
  mins = inputParam[0].replace("--age ", "")
713
726
 
714
727
 
715
- console.log(`Querying attribute rules logs for ${parameters.service} for the last ${mins} minutes ...`)
728
+ logger.info(`Querying attribute rules logs for ${parameters.service} for the last ${mins} minutes ...`)
716
729
 
717
730
  const startTime = Date.now() - mins*60*1000
718
731
  const endTime = Date.now();
@@ -762,7 +775,7 @@ const inputs = {
762
775
  if (inputParam != null && inputParam.length > 0)
763
776
  mins = inputParam[0].replace("--age ", "")
764
777
 
765
- console.log(`Querying trace logs for ${parameters.service} for the last ${mins} minutes ...`)
778
+ logger.info(`Querying trace logs for ${parameters.service} for the last ${mins} minutes ...`)
766
779
  const startTime = Date.now() - mins*60*1000
767
780
  const endTime = Date.now();
768
781
  let result= await adminLog.query([102002], [parameters.service+ ".MapServer"], topLogCount, startTime ,endTime , "VERBOSE")
@@ -803,7 +816,7 @@ const inputs = {
803
816
  delete newMessage.message
804
817
 
805
818
  console.table([newMessage])
806
- console.log(m.message)
819
+ logger.info(m.message)
807
820
  })
808
821
 
809
822
  },
@@ -821,7 +834,7 @@ const inputs = {
821
834
  mins = inputParam[0].replace("--age ", "")
822
835
 
823
836
 
824
- console.log(`Querying validate logs for ${parameters.service} for the last ${mins} minutes ...`)
837
+ logger.info(`Querying validate logs for ${parameters.service} for the last ${mins} minutes ...`)
825
838
  const startTime = Date.now() - mins*60*1000
826
839
  const endTime = Date.now();
827
840
  let result= await adminLog.query([102003], [parameters.service+ ".MapServer"], topLogCount, startTime ,endTime , "VERBOSE")
@@ -886,7 +899,7 @@ const inputs = {
886
899
  delete newMessage.message
887
900
 
888
901
  console.table([newMessage])
889
- console.log(m.message)
902
+ logger.info(m.message)
890
903
  })
891
904
 
892
905
 
@@ -905,7 +918,7 @@ const inputs = {
905
918
  if (inputParam != null && inputParam.length > 0)
906
919
  mins = inputParam[0].replace("--age ", "")
907
920
 
908
- console.log(`Querying subnetwork logs for ${parameters.service} for the last ${mins} minutes ...`)
921
+ logger.info(`Querying subnetwork logs for ${parameters.service} for the last ${mins} minutes ...`)
909
922
  const startTime = Date.now() - mins*60*1000
910
923
  const endTime = Date.now();
911
924
  let result= await adminLog.query([102003], [parameters.service+ ".MapServer"], topLogCount, startTime ,endTime , "VERBOSE")
@@ -970,7 +983,7 @@ const inputs = {
970
983
  delete newMessage.message
971
984
 
972
985
  console.table([newMessage])
973
- console.log(m.message)
986
+ logger.info(m.message)
974
987
  })
975
988
 
976
989
 
@@ -987,7 +1000,7 @@ const inputs = {
987
1000
  if (inputParam != null && inputParam.length > 0)
988
1001
  mins = inputParam[0].replace("--age ", "")
989
1002
 
990
- console.log(`Querying cursor sql logs for ${parameters.service} for the last ${mins} minutes ...`)
1003
+ logger.info(`Querying cursor sql logs for ${parameters.service} for the last ${mins} minutes ...`)
991
1004
  const startTime = Date.now() - mins*60*1000
992
1005
  const endTime = Date.now();
993
1006
  let result= await adminLog.query([102023], [parameters.service+ ".MapServer"], topLogCount, startTime ,endTime , "DEBUG")
@@ -1003,7 +1016,7 @@ const inputs = {
1003
1016
 
1004
1017
  allMessages = allMessages.concat(jsonRes.logMessages.filter(m => m.message.indexOf("EndCursor;") > -1))
1005
1018
  }
1006
- console.log ("Filtering messages...")
1019
+ logger.info ("Filtering messages...")
1007
1020
 
1008
1021
  allMessages = allMessages
1009
1022
  .map( m=> {
@@ -1017,21 +1030,21 @@ const inputs = {
1017
1030
  .slice(0, 10) ;//first 10
1018
1031
 
1019
1032
 
1020
- console.log("-----Top 10 SQL----")
1033
+ logger.info("-----Top 10 SQL----")
1021
1034
  let i =0;
1022
1035
  allMessages= allMessages.forEach(m =>
1023
1036
  {
1024
1037
 
1025
1038
  const x = m.message.split(";")
1026
1039
  x.shift()
1027
- console.log(`id: ${i++}`)
1028
- console.log(`\tAt: ${new Date(m.time)} (${m.time})`)
1029
- console.log(`\tUser: ${m.user}`)
1030
- console.log(`\tTotal Time: ${numberWithCommas(Math.round(m.elapsed*1000))} ms (Total time the cursor was opened)`)
1031
- console.log(`\tQuery Time: ${numberWithCommas(m.totalExecutionElapsed)} ms (includes search + data access nextRow)`)
1032
- console.log(`\tQuery:`)
1033
- x.forEach(a => console.log(`\t${a}`))
1034
- console.log(`\n`)
1040
+ logger.info(`id: ${i++}`)
1041
+ logger.info(`\tAt: ${new Date(m.time)} (${m.time})`)
1042
+ logger.info(`\tUser: ${m.user}`)
1043
+ logger.info(`\tTotal Time: ${numberWithCommas(Math.round(m.elapsed*1000))} ms (Total time the cursor was opened)`)
1044
+ logger.info(`\tQuery Time: ${numberWithCommas(m.totalExecutionElapsed)} ms (includes search + data access nextRow)`)
1045
+ logger.info(`\tQuery:`)
1046
+ x.forEach(a => logger.info(`\t${a}`))
1047
+ logger.info(`\n`)
1035
1048
 
1036
1049
  })
1037
1050
 
@@ -1143,11 +1156,11 @@ const inputs = {
1143
1156
  console.table(rules)
1144
1157
 
1145
1158
  const totalARExecution = rules.reduce( (prev, cur) => prev + cur["Total Cost (ms)"], 0)
1146
- console.log(`Total time spend executing attribute rules (${Math.round(totalARExecution)} ms) (${Math.round(totalARExecution/1000)} s) (${Math.round(totalARExecution/(1000*60))} m)`)
1159
+ logger.info(`Total time spend executing attribute rules (${Math.round(totalARExecution)} ms) (${Math.round(totalARExecution/1000)} s) (${Math.round(totalARExecution/(1000*60))} m)`)
1147
1160
 
1148
1161
  },
1149
1162
 
1150
- "^version$": () => console.log(version),
1163
+ "^version$": () => logger.info(version),
1151
1164
  "^clear$|^cls$": () => console.clear(),
1152
1165
  "^quit$": () => {
1153
1166
  if (rl) rl.close();
@@ -1172,7 +1185,7 @@ const inputs = {
1172
1185
 
1173
1186
  while(true) {
1174
1187
  const result = await un.query(layerId, `1=1`, undefined, undefined, ["globalId"], "sde.DEFAULT", offset, recordCount)
1175
- console.log(`Processing ${recordCount} rows`)
1188
+ logger.info(`Processing ${recordCount} rows`)
1176
1189
  //for each assocaition check if its valid
1177
1190
  for (let i = 0 ; i < result.features.length; i++){
1178
1191
  const row = result.features[i]
@@ -1287,7 +1300,7 @@ function numberWithCommas(x) {
1287
1300
  /*
1288
1301
  rl.question("What is your name ? ", function(name) {
1289
1302
  rl.question("Where do you live ? ", function(country) {
1290
- console.log(`${name}, is a citizen of ${country}`);
1303
+ logger.info(`${name}, is a citizen of ${country}`);
1291
1304
  rl.close();
1292
1305
  });
1293
1306
  });
@@ -1300,7 +1313,7 @@ function setupReadLine() {
1300
1313
  });
1301
1314
 
1302
1315
  rl.on("close", function() {
1303
- console.log("\nbye");
1316
+ logger.info("\nbye");
1304
1317
  process.exit(0);
1305
1318
  });
1306
1319
 
@@ -1322,7 +1335,7 @@ export async function run (){
1322
1335
  console.error(`Minimum required node js is ${minVer} your version is ${process.version}`)
1323
1336
  process.exit(0);
1324
1337
  }
1325
- console.log(`uncli ${version} is experimental command line utility for basic utility network services. Use as is.`)
1338
+ logger.info(`uncli ${version} is experimental command line utility for basic utility network services. Use as is.`)
1326
1339
  parameters = await parseInput( )
1327
1340
  //set certificate verification
1328
1341
  const verifyCert = parameters["verify"] === 'true' ? 1 : 0;
package/logger.mjs CHANGED
@@ -1,9 +1,23 @@
1
1
  const logger = {}
2
- logger.info = console.log
3
- logger.error = console.error
2
+ logger.info = m => console.log (`${shortDate()}: ${m}`)
3
+ logger.error =m => console.error (`${shortDate()}: ${m}`)
4
4
 
5
5
  export default logger;
6
6
 
7
+ function shortDate()
8
+ {
9
+
10
+ const t = new Date();
11
+ const date = ('0' + t.getDate()).slice(-2);
12
+ const month = ('0' + (t.getMonth() + 1)).slice(-2);
13
+ const year = t.getFullYear();
14
+ const hours = ('0' + t.getHours()).slice(-2);
15
+ const minutes = ('0' + t.getMinutes()).slice(-2);
16
+ const seconds = ('0' + t.getSeconds()).slice(-2);
17
+ const time = `${month}/${date}/${year}:${hours}:${minutes}:${seconds}`;
18
+ return time;
19
+ }
20
+
7
21
  /*
8
22
  import winston from "winston"
9
23
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "un-cli",
3
- "version": "0.0.70",
3
+ "version": "0.0.73",
4
4
  "description": "Command line interface for working with ArcGIS Utility Network Extension",
5
5
  "main": "index.mjs",
6
6
  "bin": {